MCP — Model Context Protocol¶
Cortex 内置按权限面和平台面拆分的 MCP(Model Context Protocol)服务器,赋予智能体访问远程机器、任务监控、线程控制、调度、费用和平台集成的能力。本文档解释每个服务器提供什么、如何组合以及如何添加第三方 MCP 服务器。
什么是 MCP¶
MCP 是一个开放协议,允许 LLM 应用通过标准化的 JSON-RPC 接口(基于 stdio 或 HTTP)向智能体暴露工具。Cortex 使用 MCP 在智能体进程(无法直接访问 agent-server 内部)和服务器能力之间架起桥梁。MCP 支持因后端而异——功能矩阵参见 backends.md。
Claude Code 从 JSON 文件读取 MCP 服务器配置,并将每个服务器作为子进程生成。智能体可以像内置工具(Bash、Read、Edit 等)一样调用 MCP 工具,工具名称以 mcp__<server-name>__ 为前缀。
为什么 Cortex 内置自己的 MCP 服务器¶
Cortex 的 agent-server 维护智能体进程无法直接访问的状态:到远程机器的 WebSocket 连接、调度数据库、费用记录、Slack API 客户端和执行注册表。MCP 服务器充当受控桥梁——智能体调用 MCP 工具,MCP 服务器与 agent-server 内部通信(通过 HTTP 到本地 webhook 服务器端口 3001,或通过读取共享文件),结果流回智能体。
内置 MCP 服务器¶
cortex-core¶
暴露远程机器操作和只读时钟,并在所有会话中加载。保留 cortex-core 服务器名,因此现有客户端和 skill 使用的 mcp__cortex-core__remote_* 名称不变。
| 工具 | 参数 | 描述 |
|---|---|---|
remote_bash |
device、command、timeout?、description?、run_in_background? |
通过 cortex-client 在远程设备上执行 shell 命令 |
remote_read |
device、file_path、offset?、limit? |
从远程设备读取文件(支持图像和 PDF) |
remote_write |
device、file_path、content |
向远程设备写入文件内容 |
remote_edit |
device、file_path、old_string、new_string、replace_all? |
通过字符串替换编辑远程设备上的文件 |
remote_glob |
device、pattern、path? |
在远程设备上查找匹配 glob 模式的文件 |
remote_grep |
device、pattern、path?、glob?、type?、output_mode?、-A?、-B?、-C?、-i?、-n?、head_limit?、offset?、multiline? |
使用 ripgrep 在远程设备上搜索文件内容 |
current_time |
timezone? |
获取当前日期时间;可选 IANA 时区(默认服务器本地)。返回 Unix 时间戳、UTC ISO 字符串及带偏移的本地时间 |
服务器实现在 agent-server/src/domain/mcp/core-server.ts。
cortex-tasks¶
暴露只读任务监控工具,并在仍维护的 Claude 和 PI 顶层直接会话与线程会话中加载。PI Agent 子代理只获得 cortex-core。
| 工具 | 参数 | 描述 |
|---|---|---|
task_status |
task_id、project? |
读取任务的生命周期状态(status、是否可执行、claimed_by、blocked_by、依赖、parent) |
task_result |
task_id、project? |
读取任务的结果(done/blocked、done_when、完成备注、阻塞原因) |
task_list |
project?、status?、parent?、limit? |
列出任务(可按 status 或 parent 过滤) |
服务器实现在 agent-server/src/domain/mcp/tasks-server.ts。
cortex-manager-qa¶
向顶层直接会话和线程会话暴露 manager 到子任务的回答通道。Claude 中的规范工具名是 mcp__cortex-manager-qa__answer_subtask。PI Agent 子代理不加载此服务器,因为它们不持有任务树问题。
| 工具 | 参数 | 描述 |
|---|---|---|
answer_subtask |
question_id、answer |
回答子任务提出的澄清问题 |
服务器实现在 agent-server/src/domain/mcp/manager-qa-server.ts。
cortex-thread¶
暴露线程生命周期控制面和向上澄清通道。对于 Claude 和 PI,仅当 CORTEX_THREAD_ID 标识活动线程时加载;直接会话永远不会获得这些工具。
| 工具 | 参数 | 描述 |
|---|---|---|
thread_abort |
kind、diagnosis |
升级你自己的线程(too-big / mis-scoped / blocked-external,终态 aborted) |
thread_split |
subtasks |
把你自己的任务分解为子任务(keep-parent 汇合),子任务走正常派发队列 |
thread_wait |
on_tasks?、on_threads? |
挂起你自己的线程直到被等待的子项完成;与 cortex-task spawn 配合使用 |
ask_manager |
question |
向规划本任务的 manager 提出阻塞式澄清问题 |
服务器实现在 agent-server/src/domain/mcp/thread-server.ts。工具注册器仍在 agent-server/src/domain/mcp/tools/。
cortex-ext¶
暴露 Cortex 管理工具:调度、费用查询和上下文解析。Claude 仅在直接/用户会话中加载它;PI bridge 在所有顶层会话中加载 cortex-ext。
| 工具 | 参数 | 描述 |
|---|---|---|
cortex_schedule_add |
type、message、interval?、time?、dayOfWeek?、delay?、target?、fallback?、profile?、preCheck?、channel? |
创建调度任务(interval、daily、weekly 或 once) |
cortex_schedule_list |
limit? |
列出所有调度任务及其状态 |
cortex_schedule_get |
id |
通过 8 字符十六进制 ID 查找调度任务 |
cortex_schedule_remove |
id |
删除调度任务(幂等) |
cortex_schedule_pause |
id |
暂停周期性调度任务 |
cortex_schedule_resume |
id |
恢复暂停的调度任务 |
cost_query |
(无) | 查询当前费用:今天/月支出、预算限制、剩余预算、API/plan 分摊、来源细分、令牌使用量 |
query_executions |
execution_id?、task_id?、status?、project?、limit? |
查询执行记录——按状态、项目过滤,或按 ID 查找 |
cortex_context |
(无) | 返回当前执行上下文:channel、sessionId、sessionName、threadId、profile、project、backend |
服务器实现在 agent-server/src/domain/mcp/server.ts。各个工具在 agent-server/src/domain/mcp/tools/。
cortex-slack¶
Slack 平台特定的 MCP 服务器。仅当会话源自 Slack 时加载,提供平台特定的文件上传和消息功能。
| 工具 | 参数 | 描述 |
|---|---|---|
slack_send_file |
file_path、file_name?、title?、comment? |
上传本地文件到 Slack |
服务器实现在 agent-server/src/domain/mcp/slack-server.ts。
cortex-feishu¶
飞书/Lark 平台特定的 MCP 服务器。仅当会话源自飞书时加载,只暴露一个工具——向聊天发送文件。
| 工具 | 参数 | 描述 |
|---|---|---|
feishu_send_file |
file_path、file_name?、title?、channel? |
上传本地文件到飞书聊天 |
文档、表格、电子表格、知识库等操作不再是 MCP 工具。它们改由飞书官方 CLI
(@larksuite/cli)完成,通过 feishu-doc skill 驱动。该 CLI 能可靠处理原生表格和
block 级精修(此前的 feishu_docx_* MCP 工具会把表格降级成纯文本 block,已移除)。
安装/鉴权 preflight 以及如何委托给 CLI 自带的 lark-doc / lark-sheets / lark-base
skill 指南,见 feishu-doc skill。
服务器实现在 agent-server/src/domain/mcp/feishu-server.ts。工具在 agent-server/src/domain/mcp/feishu/file.ts。
cortex-tui-bridge¶
在交互式 TUI 会话和用户发起的 Claude print 会话中加载。它用经 Cortex 路由的 MCP 等效工具替换 Claude Code 原生的 EnterPlanMode、ExitPlanMode 和 AskUserQuestion。
| 工具 | 描述 |
|---|---|
cortex_plan_enter |
发出智能体处于计划模式的提醒 |
cortex_plan_exit |
读取计划文件,发送到 Slack 供人类审批,阻塞直到解决 |
cortex_ask_user |
通过 Slack 模态框询问 1-4 个问题,阻塞直到回答 |
服务器实现在 agent-server/src/domain/mcp/tui-server.ts。工具在 agent-server/src/domain/mcp/tools/tui-plan.js 和 tui-ask.js。
MCP 配置文件¶
Cortex 在启动时自动生成 MCP 配置文件(通过 agent-server/src/core/config-generator.ts 和 agent-server/src/entry/startup-helpers.ts 中的 ensureMcpConfig() 调用)。平台特定的服务器(cortex-slack、cortex-feishu)根据会话的源平台动态加载。
| 文件 | 加载者 | 服务器 |
|---|---|---|
~/.cortex/config/mcp-config.json |
直接会话基础层 | core + tasks + manager-Q&A + ext |
~/.cortex/config/mcp-config-core.json |
线程会话分层 | 仅 cortex-core |
~/.cortex/config/mcp-config-tasks.json |
线程会话分层 | 仅 cortex-tasks |
~/.cortex/config/mcp-config-manager-qa.json |
线程会话回答分层 | 仅 cortex-manager-qa |
~/.cortex/config/mcp-config-thread.json |
仅线程会话的分层 | 仅 cortex-thread |
~/.cortex/config/mcp-config-tui.json |
交互工具分层(按需) | 仅 cortex-tui-bridge |
~/.cortex/config/mcp-config-slack.json |
Slack 特定分层(按需) | cortex-slack |
每个文件遵循 Claude Code 的标准 MCP 配置格式:
{
"mcpServers": {
"cortex-core": {
"command": "node",
"args": ["/path/to/core-server.js"],
"cwd": "/path/to/cwd"
},
"cortex-tasks": {
"command": "node",
"args": ["/path/to/tasks-server.js"],
"cwd": "/path/to/cwd"
},
"cortex-manager-qa": {
"command": "node",
"args": ["/path/to/manager-qa-server.js"],
"cwd": "/path/to/cwd"
},
"cortex-ext": {
"command": "node",
"args": ["/path/to/server.js"],
"cwd": "/path/to/cwd"
}
}
}
配置文件在每次 agent-server 启动时重新生成。手动编辑它们将被覆盖。要自定义 MCP 配置,修改 core/config-generator.ts 中的生成器或工具读取的 profile/budget/schedule 设置。
如何选择正确的配置¶
在 agent-adapter/claude/spawn-args.ts 中,MCP 配置按会话上下文组合:
- 直接/用户会话加载
mcp-config.json(core + tasks + manager-Q&A + ext),再追加符合条件的平台和交互分层;永不加载mcp-config-thread.json。 - 线程/模板会话加载
mcp-config-core.json、mcp-config-tasks.json、mcp-config-manager-qa.json和mcp-config-thread.json;不加载仅直接会话使用的 ext、平台或 TUI bridge 分层。
线程分支由 session.cortexContext.useCoreMcp 标记。PI bridge 的顶层会话始终连接 core、tasks、manager-Q&A 和 ext;仅当 CORTEX_THREAD_ID 存在时,shouldLoadThreadControl() 才追加 cortex-thread。PI Agent 子代理只连接 cortex-core。平台服务器继续由来源频道谓词门控。
MCP 工具如何与 agent-server 通信¶
MCP 服务器作为独立的子进程运行。它们不能直接访问 agent-server 的进程内状态(WebSocket 连接、调度仓库、执行注册表)。相反,它们通过两条路径通信:
-
HTTP 环回 — 远程机器工具(
remote_bash、remote_read等)发送 HTTP POST 到http://127.0.0.1:3001/webhook/remote-command。agent-server/src/orchestration/routing/webhook.ts中的 webhook 处理程序将请求转发到client-manager.sendCommand(),后者通过 WebSocket 发送到远程设备。 -
共享文件访问 — 调度、费用和执行工具直接读取和写入
~/.cortex/data/中的共享数据文件(schedules.json、costs.jsonl、executions.json),使用与主服务器进程相同的仓库层。
插件提供的 MCP servers¶
按 target 分配的第三方 MCP 应放入 $CORTEX_HOME/plugins/<plugin-id>/ 下的 portable Agent Plugins package。Package 在根目录 mcp.json 声明 servers,再由 Settings → Plugins 分配给 agent 或 template slot。Schema 支持 stdio、streamable-http 与 legacy sse;完整 package 与 trust model 见技能与插件。
Legacy plugin directory 仍会原样传给 backend。Claude 可以从该目录加载 Claude-native root .mcp.json,但 Cortex 不会 inventory、summarize 或 acknowledgment-gate 这些 native servers,PI 也不会获得它们。本节保证只适用于 portable root mcp.json(agent-server/src/domain/plugins/runtime.ts:546-562;agent-server/src/agent-adapter/claude/spawn-args.ts:224-238)。
Cortex 在 spawn 时统一校验和规范化 package。Claude 获得叠加在常规 Cortex files 之后的 private supplemental config。Stdio entry 仍是独立 process;每个 remote entry 会变成本地 stdio proxy,其 URL 与 headers 保存在 private config。PI 获得由 MCP bridge 消费的 private content-addressed config。两个 remote path 使用相同的 manual-redirect fetch,并在 configured header 或 request body 被重放之前拒绝所有 redirect。Connection 与 tool registration 按 process 隔离。Materialization 遵循声明的 dependency:plugin-scoped PLUGIN_DATA 不可用时会省略依赖它的 stdio servers,同时保留 remote MCP、skills 与 bundled tools(agent-server/src/agent-adapter/claude/mcp-config.ts:105-164;agent-server/src/agent-adapter/claude/remote-mcp-proxy.ts:48-82;agent-server/src/agent-adapter/pi/mcp-bridge.ts:279-476)。
Resolved MCP composition 为 none 或 benchmark-thread-run 时 portable MCP 会被省略;受限 PI Agent subagent 也不会获得它。普通顶层 Claude 与 PI session 只有在分配了相应 plugin 时才会加载(agent-server/src/domain/plugins/runtime.ts:120-122,673-688;agent-server/src/agent-adapter/pi/adapter.ts:901-918;agent-server/src/agent-adapter/pi/mcp-bridge.ts:220-244)。
Plugin catalog 与 Settings API 只公开 sanitized summary。Stdio summary 包含 executable basename、argument count 与 environment key names;remote summary 包含 origin 与 header names。Environment values、完整 remote URL 与 header values 都留在 server 侧(agent-server/src/domain/plugins/mcp.ts:102-216;agent-server/src/domain/ui-service/plugins-shared.ts:98-134)。Installed stdio command 与 working directory 仍是 administrator-trusted package inputs;private config 和 per-server isolation 不是 code sandbox。
Global custom MCP servers¶
$CORTEX_HOME/config/mcp-config*.json 描述 Cortex 的 global 与 session-composed MCP layers。这些文件在 server startup 时重新生成,因此直接修改只是临时的。要持久加入 global server,必须在 agent-server/src/core/config-generator.ts 中显式修改 builder 与 privilege composition;它不属于 assignment-scoped plugin。
这种区分把 global Cortex privileges 与 administrator-installed plugin capabilities 分开。Server 应随 agent 或 template assignment 加载时使用 portable plugin;只有所有 eligible session composition 都应获得该 server 时才修改 global builders。
权限模型¶
MCP 工具跨越从智能体进程到 agent-server 内部和远程机器的信任边界。Installed plugin 属于 administrator-trusted code。对 portable root mcp.json,assignment confirmation 会显式呈现新增 capability,但它不是 sandbox,也不是独立 authorization boundary;legacy Claude-native MCP configuration 不经过该 confirmation。Cortex 应用以下控制:
-
服务器级可用性 — 后端工具 allowlist 无法逐个过滤 MCP 工具,因此权限按服务器拆分。顶层直接会话和线程会话都获得 cortex-manager-qa;只有线程会话获得 cortex-thread。PI
Agent子代理只获得 cortex-core,PI 顶层会话继续保留 cortex-ext。 -
Claude account-level MCP discovery 被禁用 —
~/.cortex/.claude/settings.json中的ENABLE_CLAUDEAI_MCP_SERVERS: "false"阻止 account-level auto-discovery,但不会禁用显式分配的 legacy plugin directory 内 Claude-native.mcp.json。Cortex 通过自己的 config layers 管理 bundled 与 portable MCP,同时保留该 legacy backend behavior。 -
绕过权限 — Claude Code 以
--dangerously-skip-permissions --permission-mode bypassPermissions生成,意味着它不会对每个 MCP 工具调用提示。访问控制在 MCP 工具实现级别和通过 PreToolUse 钩子系统进行。 -
PreToolUse 守卫 —
tasks-yaml-guard.mjs钩子拦截对TASKS.yaml文件的 Edit/Write 操作(包括远程编辑)并检查项目锁。 -
网络边界 — 与远程机器通信的 MCP 工具通过 client-manager 的 WebSocket 层。
machines.json注册表控制哪些设备是已知的。只有具有活跃 WebSocket 连接的设备才能接收命令。
传递给 MCP 服务器的环境变量¶
MCP 服务器进程接收 agent server 环境变量的一个子集:
| 变量 | 来源 | 使用者 |
|---|---|---|
SLACK_CHANNEL |
生成时的频道参数 | cortex-ext(slack_send_file)、tui-server |
SLACK_BOT_TOKEN |
process.env | cortex-ext |
CORTEX_SESSION_ID |
会话上下文 | tui-server、context 工具 |
CORTEX_SESSION_NAME |
会话上下文 | context 工具 |
CORTEX_THREAD_ID |
线程上下文 | cortex-thread 工具、PI 线程控制谓词、context 工具 |
CORTEX_PROFILE |
会话上下文 | context 工具 |
CORTEX_PROJECT |
会话上下文 | context 工具 |
CORTEX_EXECUTION_ID |
执行上下文 | 任务锁钩子 |
CORTEX_TUI_MODE |
在 TUI 模式下设为 '1' |
tui-server |
CORTEX_CALLBACK_SOURCE |
可选回调元数据 | cortex-ext |
CORTEX_SCHEDULE_TASK_ID |
可选调度任务 ID | cortex-ext |
ANTHROPIC_BASE_URL |
可选 API 基础 URL 覆盖 | 模型路由 |
PLUGIN_ROOT |
解析后的 selected plugin root | Portable stdio plugin servers |
PLUGIN_DATA |
Private persistent per-plugin data directory | Portable stdio plugin servers |
安全考量¶
MCP 工具赋予智能体在远程机器上执行 shell 命令、读写文件、上传到 Slack 和修改调度的能力。安全假设如下:
cortex-clientWebSocket 端口(3002)不暴露到公网。使用 Tailscale、VPN 或 localhost-only 绑定(网络拓扑选项参见 cross-machine.md)。- Webhook HTTP 端口(3001)仅绑定到
127.0.0.1——MCP 服务器通过环回而不是网络与之通信。 - 智能体在与 safety-and-approvals.md 中记录的相同影响范围安全边界内运行。MCP 工具不能绕过对高权限操作的 need-approval 门控。