mcp-agents
mcp-agents
封装 AI CLI 工具的 MCP 服务器 —— Claude Code、Antigravity CLI(agy)和 Codex CLI —— 并且可以将 Chrome DevTools MCP 代理到远程租用的浏览器。
前置条件
Node.js >= 26
至少安装以下 CLI 之一并加入
$PATH:
CLI | 安装方式 |
| |
| |
|
|
只有你用 --provider 选中的那个 CLI 需要存在。
Related MCP server: claudecode-mcp
安装
npm install -g mcp-agents全局安装是启动最快、最可靠的方式。MCP 服务器运行起来后,npx -y mcp-agents 在功能上等价,但启动依赖 npm 包解析/缓存状态,之后 MCP 客户端才能连接。
提示: 如果你的项目 .mcp.json 引用了 mcp-agents,请在你的设置脚本(例如 bin/setup)中加入 npm install -g mcp-agents,这样新开发者就能自动获得它。
快速测试
# Default provider (codex)
mcp-agents
# Specific provider
mcp-agents --provider claude
mcp-agents --provider gemini
# Browser provider (example injected lease helper)
mcp-agents --provider browser \
--browser_lease_command '["bin/box","--browser"]'该服务器通过 stdio 上的 JSON-RPC 通信。当它开始监听时,会向 stderr 打印 [mcp-agents] ready (provider: <name>)。
提供方与工具
每个 --provider 标志选择一个 CLI 后端:
提供方 | 工具名称 | CLI 命令 |
|
|
|
|
|
|
| (透传) |
|
| (透传) |
|
Claude 审查
对于重要的第二意见和代码审查,请使用后台工具:
调用
claude-start,传入完整的审查提示词和绝对cwd。调用
claude-status,传入返回的jobId和cursor。每次用新的 cursor 重复调用,直到状态变为终态。当状态为
completed时,调用claude-result。从nextOffset继续,直到done为true。如果不再需要结论,调用
claude-cancel。
工具 | 必需参数 | 可选参数 |
|
| — |
|
|
|
|
|
|
|
| — |
claude-status 默认长轮询 10 秒,wait_ms 最多接受 60 秒。取消状态轮询不会取消其任务。任务是单次性的,且仅限当前 MCP 连接内:没有回复会话,断开连接会取消进行中的工作。服务器允许 8 个活动任务和 32 个保留任务,终态任务保留一小时,结果按 32,768 个 Unicode 码点分页,超过 10 MiB 的最终结果会被拒绝。
后台审查有桥接方拥有的两小时截止时间。操作员可以在启动服务器时用 --timeout <seconds> 替换它;调用方不能用 timeout_ms 缩短任务。Claude 固定为 claude-opus-4-8,effort 为 xhigh,以叶子审查者身份运行:它保留项目说明和仓库上下文,但禁用 hooks、子代理、技能、斜杠命令、外部 MCP 服务器和变更工具。只有 Read、Glob、Grep 和计划模式下的只读 Bash 检查可用;叶子指令还禁止测试执行、安装、委派和外部副作用。中间模型输出、工具输入/结果、路径和推理过程不会通过 MCP 转发;只暴露经过净化的阶段状态和最终结论。
阻塞式 claude_code 工具只用于小型提示词,即单个 MCP 调用可以轻松在客户端超时内完成的情况。
claude_code 参数
参数 | 类型 | 必需 | 描述 |
|
| 是 | 发送给 Claude Code 的提示词 |
|
| 否 | 超时时间(毫秒)(默认:900 000 / 15 分钟) |
任何额外的 tools/call 参数都会被忽略(例如 model、effort 或 config)。
Claude 固定为 claude-opus-4-8,effort 为 xhigh;调用方不能按调用更改模型或 effort。调用以 --output-format json 运行;服务器解析 JSON 载荷并返回助手的 result 文本(如果 is_error=true 则返回 MCP 错误)。
较长的默认值是为了容纳深度 Opus 审查;调用方仍然可以设置更小的 timeout_ms,服务器操作员可以用 --timeout <seconds> 覆盖默认值。
gemini 参数
参数 | 类型 | 必需 | 描述 |
|
| 是 | 发送给 Antigravity CLI( |
|
| 否 | 超时时间(毫秒)(默认:300 000 / 5 分钟) |
任何额外的 tools/call 参数都会被忽略(例如 model 或 model_reasoning_effort)。
agy 始终以 --sandbox 运行(启用终端限制);没有按调用切换沙箱的选项。
browser(远程 Chrome 透传)
浏览器提供方会立即启动本地 chrome-devtools-mcp 服务器,然后在第一次调用广告的浏览器工具时惰性获取远程 Chrome 租约。MCP 服务器及其写入的所有文件都保持本地;只有 CDP 穿过操作员提供的回环隧道。获取期间到达的调用共享一次配置尝试,并保持 FIFO 顺序。没有包装器拥有的获取、状态、释放、任务或取消工具。
使用 crabbox 快速设置
最好搭配 crabbox:临时、单租户的盒子,会在自身容量耗尽时消亡 —— 这正是浏览器租约想要的生命周期,而且不需要你操心正确的拆除。
你的 acquire 辅助脚本做四件事:租用一个盒子;在盒子上以 --remote-debugging-port=<remote> 启动 Chromium;打开 ssh -L 127.0.0.1:<local-cdp-port>:127.0.0.1:<remote>(当被测页面由你的机器提供时,为 --app-port 添加匹配的 -R);然后,一旦 /json/version 在本地端口上应答,就打印:
record_version=1
state=ready
generation=<opaque token>
local_cdp_port=<the port you were given>
browser_url=http://127.0.0.1:<that same port>status 重新检查该租约,release 将其拆除,任何退出码 69 都让通道保持故障关闭。
该提供方没有云或 SSH 知识。注入的命令拥有租约,并接收以下 argv 形式:
acquire --session <id> --local-cdp-port <port> --viewport <WxH> [--app-port <port>]
status --session <id> [--generation <token>]
release --session <id> --generation <token> --reason idle|shutdown成功的 acquire 输出是惰性 UTF-8 key=value 数据,包含版本 1 的就绪记录、代次、选定的本地 CDP 端口和匹配的浏览器 URL。退出码 69 是故障关闭:调用返回"GUI 未验证 —— 没有可用的浏览器盒子",并且永远不会启动本地浏览器。辅助脚本报告的本地开发服务器预检错误会原样保留。退出码 75 报告回环绑定竞争;mcp-agents 选择新端口、重启下游、重放原始 MCP initialize 能力(包括 roots)和 initialized 通知,并最多重试三次,不会暴露重复的 initialize 结果。
chrome-devtools-mcp 故意不固定版本 —— 回退会浮动到最新版本。这里没有任何东西依赖特定版本的重连行为:每个浏览器工具结果都会根据其签发时的租约代次进行验证,无论下游是否报告重连,因此较新的版本不能悄悄削弱故障关闭契约。解析按以下顺序确定性进行:
--browser_command或MCP_AGENTS_BROWSER_COMMAND(命令字符串或 JSON argv)。包本地可解析的
chrome-devtools-mcp,然后是node_modules/.bin/chrome-devtools-mcp。npx -y chrome-devtools-mcp@latest。
第三条路径可能让第一次 initialize 等待 npm 解析。为了更快启动,请将 chrome-devtools-mcp 与 mcp-agents 一起安装,或者安装在其他地方并用 --browser_command 指向其可执行文件。如果你需要为特定部署固定版本,就在那里固定它。浏览器下游要求 Node 版本不低于它所解析的 chrome-devtools-mcp 版本所支持的版本;本包自身的 >=26 下限保持在该版本之上,因为未固定的依赖会跟踪最新版本。
chrome-devtools-mcp 故意是开发依赖,而不是运行时依赖。因此,开发者检出会走包本地路径,而发布包的消费者使用 npx 回退,除非他们将包与 mcp-agents 一起安装或提供显式命令。
CLI 标志 | 默认值 | 环境变量 |
| 必需 |
|
| 上述解析顺序 |
|
|
|
|
|
|
|
| 省略 |
|
| 省略 |
|
| 省略;可重复 |
|
视口会传给租约辅助脚本,以便设置远程 Chromium 的窗口大小;Chrome DevTools MCP 的 --viewport 故意省略,因为通过 --browserUrl 附加时它是无效的。
每个完整的下游 JSON-RPC 帧都会重置代次空闲计时器;stderr 和部分输出不会。空闲释放有 60 秒的清理上限,以便远程 Chromium、SSH 隧道和盒子真正停止。关闭释放使用单独的 15 秒上限,并保持跟踪和回收。两者都是尽力而为的成本优化。如果 Chrome 消失,中断的原生连接错误不会重放。辅助脚本状态 69 会用 browser_lease_replaced 丰富它,明确警告浏览器已被替换、状态已丢失、中断的结果未知,调用方必须检查状态而不是盲目重放。状态 0 保留原生错误;状态 70 保持未知,而不是被误报为丢失租约。下一次浏览器调用会重新获取并使用 Chrome DevTools MCP 的重连路径。
客户端初始化帧以及下游的 roots/list 请求/响应在转发时不会重写 ID 或 URI。当下游重启时,属于已终止进程的响应会被丢弃,其请求关联会在替代进程复用 ID 之前被注销。这保留了 Chrome DevTools MCP 的本地文件写入允许列表,因此有意不传递 --allowUnrestrictedPaths。应用和 MinIO 的预检失败会分别原样呈现。性能跟踪和 Lighthouse 描述会警告远程链接测量不是门槛,upload_file 会警告本地路径不能直接交给远程 Chromium。
URL 限制是选择加入的,因为仅回环的默认设置会破坏 OAuth 和第三方资源。强化的仅回环部署可以重复,例如:
--browser_allowed_url_pattern 'http://127.0.0.1/*' \
--browser_allowed_url_pattern 'https://127.0.0.1/*'使用与目标应用兼容的最窄模式。该提供程序不启用实验性页面 ID 路由:一个进程拥有一个租约、配置文件和端口。
codex(直通)
codex 提供程序在隔离的 CODEX_HOME 中直通到 Codex 的原生 MCP 服务器(codex mcp-server)。桥接器在服务器启动目录的私有 tmp/codex-homes/ 目录树下创建每个主目录,复制 auth.json,写入最小的 config.toml,并且不继承您正常的外部 MCP 服务器列表。这可以防止 Codex 在桥接调用期间递归启动其他代理工具,如 Claude 或 Gemini。父目录和生成的主目录使用 0700 模式;复制的凭据和生成的运行时文件使用 0600 模式。
隔离的主目录是身份验证快照:在桥接器重新连接之前,它无法看到之后的 codex login。如果 Codex 报告其类型化的 unauthorized 终止事件,包装器会抑制重复事件,并返回一个 MCP 工具错误,其中 structuredContent.code 设置为 codex_auth_invalidated,action 设置为 reauthenticate_and_restart。新的 Codex 轮次会在本地被拒绝,而 status、result、cancel、peek、ping 和其他 MCP 操作仍然可用。停止桥接器,以相同的操作系统用户运行 codex logout 和 codex login,使用 codex exec 验证,然后重新连接。在清理时,仅当隔离副本已更改且规范身份验证仍与启动快照匹配时,才会写回轮换的身份验证;因此,过期的桥接器无法覆盖较新的手动登录或其他桥接器的令牌轮换。
唯一列入允许列表的用户首选项是快速模式。启动时,桥接器读取源 $CODEX_HOME/config.toml,并且仅当同时找到顶层 service_tier = "fast" 和 [features].fast_mode = true 时,才在隔离的主目录中启用快速模式。部分、禁用、缺失或无法读取的设置将保持标准模式;所有其他用户配置保持隔离。更改任一设置后,请重新启动 MCP 服务器。快速模式会消耗更多 ChatGPT 积分或产生 API 优先计费。
CLI 标志 | 默认值 | Codex 配置键 |
|
|
|
|
|
|
|
|
|
其他启动默认值:sandbox_mode=workspace-write、approval_policy=never(可通过 --sandbox_mode / --approval_policy 为整个服务器配置)、web_search=cached、check_for_update_on_startup=false、allow_login_shell=false 和 history.persistence=none。固定的桥接器功能默认值为 features.multi_agent=false、features.apps=false、features.plugins=false、features.hooks=false 和 features.skill_mcp_dependency_install=false;应用/插件保持禁用状态,以将 ChatGPT 应用/插件技能(如 Figma、Gmail、Presentations 等)排除在桥接的会话上下文之外。原生子代理还通过 [agents] enabled = false 被禁用,因为在 Codex >= 0.145.0 上,仅靠稳定的 multi_agent 功能标志不再移除协作工具;会话通过 allow_subagents 按调用选择加入(见下文)。该 [agents] 行是感知版本的:桥接器在启动时探测一次 codex --version,并在 Codex < 0.145.0 上省略它,因为在 [agents] 下的布尔值会导致致命的配置解析错误(0.102–0.144),并且功能标志本身仍然控制协作工具。无法解析的版本将假定为现代 Codex。
工作区写入会话默认启用网络访问,以便沙箱命令可以访问本地服务,如 DynamoDB、Redis、OpenSearch 和 MinIO。设置 --codex-workspace-network=false 或 MCP_AGENTS_CODEX_WORKSPACE_NETWORK_ACCESS=false 可为整个服务器禁用它;CLI 标志优先于环境变量。这是服务器拥有的沙箱设置,有意不出现在按调用工具模式中。
Codex 不为此设置提供仅限 localhost 的范围。启用它允许工作区写入会话中的命令进行常规出站网络访问。文件系统写入仍仅限于工作区和其他配置的可写根目录;只读和完全危险访问会话不使用 sandbox_workspace_write 设置。
桥接器用刻意精简的契约替换了 Codex 宽泛的配置形原生模式:
| 类型 | 必需 | 描述 |
|
| 是 | 初始用户提示 |
|
| 是 | 绝对工作目录 |
|
| 是 |
|
|
| 否 |
|
|
| 否 |
|
|
| 否 | 让会话生成 Codex 的原生进程内子代理;默认为 |
|
| 否 | 常设目标; |
| 类型 | 必需 | 描述 |
|
| 是 | 后续用户提示 |
|
| 是 |
|
|
| 否 | 可选的提示级常设目标提醒 |
两个模式都设置 additionalProperties: false。不支持的、缺失的或无效的参数会在 Codex 运行前在本地以 JSON-RPC -32602 拒绝。这包括原生逃生舱口,如 config、approval-policy、developer-instructions、base-instructions 和 compact-prompt;未来的上游模式新增内容将保持隐藏,直到 mcp-agents 有意采用它们。两个精选选项之外的模型值以相同方式被拒绝。
原生子代理。 在 codex 或 codex-start 上设置 allow_subagents: true 可让该会话使用 Codex 内置的多代理工具(spawn_agent、wait_agent 等)。它的作用域与会话完全相同,就像 sandbox 一样:回复会继承它且无法更改,并且默认为关闭。在内部,该标志仅通过按调用配置覆盖来切换原生多代理门控(agents.enabled 加上 features.multi_agent,与上述版本门控匹配);隔离主目录的其他一切均不变。特别是 [mcp_servers] 剥离仍然有效,因此生成的子代理是仅限 Codex 的进程内工作进程——它们无法重新进入此桥接器或访问 Claude、Gemini 或任何其他外部 MCP 工具,并且不会复制您真实的 $CODEX_HOME/agents/ 中的自定义代理角色。剩余的注意事项是并发性,而不是可达性:子代理继承会话的 sandbox_mode 和 approval_policy,因此在 approval_policy=never 的 workspace-write 下,多个代理可能同时写入同一工作区。Codex 会协调它们,但请相应调整委派范围。
对于 MCP 桥接器来说,approval_policy=never 是有意为之的:分离的工具调用无法可靠地进行交互式审批对话。操作员可以使用 --approval_policy 为整个服务器选择 untrusted 或 on-request,但调用方不能按请求削弱或更改该策略。每个新会话仍必须明确说明其沙箱,以便在调用点可以看到写入权限。
启动标志(--model、--model_reasoning_effort)配置隔离的原生 Codex 服务器默认值(gpt-5.6-sol 和 xhigh,除非被覆盖)。每次初始 codex 调用可以从两个模型中选择一个,并从四个允许的推理力度中选择一个:
模型 | 用途 |
| 要求高、开放式或高价值的工作;默认值 |
| 更快的日常工作和较简单的任务 |
值 | 用途 |
| 平衡速度和深度 |
| 需要更多分析和检查的复杂工作 |
| 困难但有边界的实现工作 |
| 极难、质量优先的工作,具有较高的架构、并发、数据完整性或安全风险 |
选择器仅在创建会话时应用。省略任一选项将使用其服务器配置的默认值。每个 codex-reply 都继承这两个选择,并且无法更改它们。通过封闭的包装器契约,其他模型和力度级别被有意设为不可用。
例如,只读审查从以下内容开始:
{
"prompt": "Review this diff",
"cwd": "/absolute/path/to/project",
"sandbox": "read-only",
"model": "gpt-5.6-terra",
"model_reasoning_effort": "high",
"goal": "Find correctness and security defects"
}目标注入。 在服务器启动时使用 --goal "<text>" 设置默认目标,或在调用时传递 goal。mcp-agents 在内部将初始目标转换为 Codex 的原生 developer-instructions:
{
"prompt": "Refactor the parser",
"cwd": "/absolute/path/to/project",
"sandbox": "workspace-write",
"model_reasoning_effort": "xhigh",
"goal": "Keep the public API unchanged"
}开发人员消息在线程中持续存在,因此回复会继承它。codex-reply 上的按调用 goal 会变成简洁的提示提醒,因为原生回复工具没有 developer-instructions 字段。不直接公开开发人员指令:goal 是精简的、可审计的常设目标接口。按调用的目标会覆盖服务器默认值;"" 会在一次调用中抑制该默认值。
桥接器会重写 tools/list 响应以公布这些精选模式。除了上述类型化的身份验证失败外,正常的原生帧保持逐字节直通;本地生成的验证和身份验证错误使用与进度和恢复消息相同的帧安全队列/边界规则。
线程内的优先级。 初始 codex 调用中设置的目标是一条 developer 角色消息,并且会在整个线程中持续存在,因此它拥有最高优先级:之后在 codex-reply 上提供的不同 goal 只是提示级别的提醒,而无法可靠地覆盖常驻目标(已实测验证——与初始目标冲突的回复目标会被忽略,以常驻目标为准)。当回复提醒不与冲突的常驻目标对立时,它是有效的。若想在中途真正改变目标,应发起一个新的 codex 调用,而不是在 codex-reply 上修改它。
注意——这不是 Codex 原生的
/goal。 Codex 的/goal斜杠命令 (一种持久的、线程作用域的目标状态,具有生命周期/预算/基于证据的完成机制) 是仅限 TUI 的功能——它在 Codex 终端 UI 中解析,无法通过codex mcp-server触达。在 MCP 提示前加上/goal …并不会激活它; 这些文字只会作为用户消息原样传过去。因此,本包装器通过developer-instructions(MCP 原生承载常驻目标的方式)来引导 Codex, 这是一种 prompt/role 层面的条件策略,而非原生的目标生命周期子系统。
单次调用的活性。 Codex 透传逻辑会独立跟踪每个打开的 tools/call。
--codex_idle_timeout <seconds>(默认 600,0 表示禁用)限制一次调用
在没有关联 Codex 活动的情况下可以持续多久。只有携带该调用 _meta.requestId
(或其匹配的响应或交互式交流)的 Codex 事件才会刷新其空闲截止时间。Codex 的
stderr、客户端 ping、无关请求,以及属于其他调用的事件,都不能让一个卡住的调用继续存活。
如果某个调用达到空闲截止时间,包装器仅让该调用失败(返回 JSON-RPC 错误
-32001),并向 Codex 发送该请求的 notifications/cancelled——这是尽力
而为的通知,即请求 Codex 停止,而非强制它停止(见下文取消一节)——同时抑制
该停滞调用的迟发原生响应,并保持连接打开——其他相关调用和 stdio
传输不受影响。这一点很重要,因为关闭 stdio 传输会使 MCP 客户端(如 Claude
Desktop 里的 Claude Code)将服务器标记为 failed,并在本次会话后续中
永久注销所有 mcp__codex__* 工具(stdio 服务器不会自动重连),因此单个
停滞的调用绝不能让整个桥接崩溃。在真正的拆除场景中(客户端断开、信号或 stdout
EPIPE),Codex 进程组仍会被回收。唯一例外是:如果 Codex 在写入响应帧的
半路被卡住(没有安全的边界可以注入错误),并且它还在忽略取消请求,包装器会
重试一次,然后把问题升级为有界的整体拆除——没有任何方法能在半帧中插入一个干净
的完整帧,因此客户端只能重连到一个全新的桥接。
取消。 客户端取消(notifications/cancelled——每次按下 ESC、中止一次
交互回合或关闭子代理)都按同一方式处理:它恰好只耗用一个请求。
--codex_cancel_grace <seconds>(默认 30)限制 Codex 处理确认取消所需的
时间;到期后,包装器会在本地终结该请求 id,抑制 Codex 迟到的响应,并让桥接及所有
其他调用继续运行。本地终结请求并不证明 Codex 已停止——一个未被确认的回合
会被记录为已放弃,但仍可能继续运行和写入。上述“半帧内升级”会触发第二个完整的
宽限期,所以该路径在桥接最终关闭前需要大约双倍的时间。宽限期长度是故意的——在
Codex 一次进行中,它会运行沙箱命令,因此不会快速处理 MCP 取消;如果宽限期太短,
升级路径反而会成为默认路径。这一点比超时情况更重要,因此存放 Codex 的
CODEX_HOME 是隔离的,其中包含 Codex 的 sessions/ 目录:一旦整个桥接
拆除,该进程中每个 threadId 都会永久无法续跑,下一次 codex-reply 就会以
Session not found 失败。
[!WARNING] 放弃一个请求并不会阻止 Codex 运行。包装器会请求它停止,但一个忽略取消 的回合会在客户端放弃之后继续运行,并且持续写入工作区。每次发生放弃时,包装器都会 在 stderr 中记录其
thread_id和job_id;如果该回合之后仍然正常结束,也会 再次记录日志。因此,一个被意外修改的目录树是可以解释的,而不必猜测。后台任务 是这里的最尖锐情况:codex-start的任务存在包装器的任务表中,而不在 MCP 客户端的任务注册表中,因此客户端侧的“停止任务”无法触达它——只有携带其jobId的codex-cancel才能触达。由于任务是通过本进程轮询的,它不可能在 客户端重连后继续存在;因此客户端断开连接会取消每一个非终结状态的任务和 打开的请求,并是一个受控的收尾来回收 Codex 进程组,前提是它仍在继续工作。
--timeout <seconds> 也对 Codex 调用生效(默认 7200),这是个不可变更的硬性
截止时间。相关联的活动可以延长空闲窗口,但永远不会延长硬性截止时间。当客户端必须
总是先于自身的保存时限收到包装器的显式错误时,请把包装器截止时间设置为低于 MCP
客户端自己的实时工具超时时间。
当收到请求中携带 _meta.progressToken 时,包装器会用该确切的 token 发送标准的
MCP notifications/progress 更新。它永远不会凭空生成一个 progress token。
第一条有效状态会立即发送;后续更新会被合并为每秒最多一次,并最终保留最新状态。
在其他没有输出的工作中,每 10 秒会发送一次 Codex: still running 通知,其中
包含最近一次与该请求相关的 Codex 事件已经过去了多长时间。
状态文本按“故障关闭”默认不披露内部细节。桥接只暴露明确标记的说明、当前计划步骤,
以及针对命令、补丁、MCP 工具、网页/图片工作、子代理的通用生命周期摘要。它不暴露
最终答案原文、推理内容、提示词、命令字符串或输出、工具参数、搜索查询、文件路径,
以及 token 统计信息。消息会被规范化空白,并截断到 200 个 Unicode 码点。原生的
codex/event 帧保持逐字节不变,唯一例外是一个类型化的 unauthorized 错误事件
会被替换为前面那个单一的结构化 auth 失败消息;进度是一条并行的 MCP 通道,通常
显示为 UI 状态,而不是额外的工具结果或模型上下文。
可选后台任务。 现有的 codex 和 codex-reply 调用仍然保持阻塞并维持现有行为。
需要对话记录级更新的客户端,可以改用由 Codex 桥接器提供的六个包装器拥有的任务工具:
工具 | 目的 |
| 以与 |
| 以与 |
| 使用返回的 |
| 从绝对偏移量读取保留的说明 |
| 以受限的方式分页读取最终回答 |
| 以幂等方式请求取消 |
尽量优先使用阻塞的 codex 调用,包括长时间构建的场景。 它只需要一次工具调用
而不是每次状态变化都让调用者转一圈,仍然可以向支持进度的 UI 流式推送
notifications/progress,并且可以通过中止本来取消它。仅当任务必须“活得比调用者更久”
(即在你停止等待后仍要继续运行)或者需要让另一个智能体后面能按 jobId 来取消它时,
才考虑使用任务式后台任务。
codex-peek — 这个响应是否仍在执行?
阻塞调用在返回之前是不透明的,因此从外部看,“卡住”和“忙”看起来完全一样。
codex-peek 可以在不取消任何内容的情况下回答这一问题:它列出当前所有正在发生的
Codex 回合,包括阻塞调用和后台调用,且只读、立即返回,并接受可选的
cwd / threadId / requestId 过滤条件。
字段 | 含义 |
| 客户端调用的句柄,在其生命周期内稳定。它是包装器内部的 |
| 后台任务的句柄,用于替代 |
|
|
| 一旦 Codex 报告即出现,“生成”—同时标记生成记录或输出文件 |
| 工作目录;当从线程而非调用中恢复时标记为 |
| 该回合被赋予的沙箱权限 |
| 从调用开始到现在的真实经时——不是进度 |
| 距离最后一次关联的 Codex 事件的时间;值很小且逐次变小,说明健康 |
不要尝试通过进程列表去找每个回合:codex mcp-server 是长驻进程,并复用了每个请求,
所以没有可发现的 codex exec 进程;在一个回合正在运行时,进程列表检查什么也报不出来。
三种答案的含义比表面看起来少。 空的列表不是“回合已完成”的证据——一个被放弃的
回合仍在 Codex 内部运行,只是因为已经没有任何可上报的“在途”内容才没有结果;这类
数量上会返回为 abandonedTurnsProcessWide——这个名称指明了它的作用域,因为单个
被放弃的回合没有保留工作区,所以它的内容永远不会被某个过滤条件缩小范围。一个较大的
elapsedSeconds 也不是“卡住”——它只是墙钟时间;lastActivitySeconds 较大也
不意味着“卡住”:一个工具调用完全可能合法地静默运行好几分钟。所以“安静”只表明
尚未有结论,绝不表示完成。为了查明而取消,才是唯一不可撤销的操作。cwd
过滤条件绝不会过滤掉工作区未知的回合——它会用 cwdUnknown 标记并报告,因为
“我不知道”绝不能悄悄变成“那里什么也没有运行”。
启动(start)结果会立即返回一个不透明的 jobId、一个状态 cursor 以及下一个
建议的调用。连续 codex-status 调用会返回普通的 MCP 工具结果,因此外层智能体或
子智能体即使在 UI 不能渲染 notifications/progress 的情况下,也能中继 Codex
正在做什么——这是任务模式提供而阻塞调用没有提供的一个可见性。当前只在当前的
cursor 下,status 调用会持续等待一个变化然后返回一个心跳;wait_ms 可以
设为 0 到 60000,省略时默认使用下面的状态间隔(当该间隔被禁用时仍用
10000 ms)。
有两种情况会结束一次状态等待,而它们对轮询成本都很重要。游标推进由服务端通过 --codex_status_interval <seconds>(默认 30)控制节奏,它会合并中间进度,而不是在每条消息上都推进游标。另一种是 wait_ms 心跳,它不受该间隔的节奏控制——因此 wait_ms 现在跟随状态间隔(上限为 60000,所以超过 60 秒的间隔仍会每 60 秒心跳一次),以避免心跳超过它所报告的游标。wait_ms 仍然是 空闲 等待的上限,而绝不是轮询间隔的下限:只要游标已经落后于头部,状态调用就会立即返回,因此落后的轮询者不会因为调高它而变慢——但已跟上进度的轮询者会变慢,这就是为什么调低 wait_ms 只会白白浪费轮次。
只有中间进度更新才受节奏控制;生命周期转换——首次 running、取消以及任何终态——会直接推进游标并唤醒所有等待者,绕过该间隔,因此调高它绝不会延迟完成。停滞检测同样不受影响——lastActivitySeconds 是根据原始 Codex 事件打戳的,而不是根据状态节拍——并且 codex-commentary 仍保留完整叙述。0 会在每次变化时恢复游标推进;高于 60 的值则让心跳上限接管,只会让状态文本变得陈旧。进度通知保持自身更精细得多的节奏,并且不消耗调用方的上下文——但请注意,它们仅针对阻塞调用发出:后台任务的请求不携带进度令牌,因此任务唯一的可见性是 codex-status / codex-commentary。
当 commentaryEndOffset 前进时,使用最后一个 nextOffset 调用 codex-commentary。评论只包含显式标记为 commentary 阶段的 Codex 消息。隐藏推理、提示、最终答案草稿、命令字符串和输出、工具参数、路径、搜索查询以及原始响应项均被排除。不安全的终端控制符会被剥离,但剩余文本由模型生成,仍必须视为不可信。偏移量按 Unicode 码点计数。每次读取最多返回 32,768 个码点;桥接器保留一 MiB 的 UTF-8 尾部,并在较旧的评论已超出缓冲区时报告绝对截断边界。
一旦状态变为终态,使用 codex-result 并从 nextOffset 继续,直到 done 为 true。每一页都将其负载同时作为普通 MCP 文本内容和 structuredContent.text 返回,以服务于优先使用结构化结果的客户端。结果页同样限制为 32,768 个码点。大于桥接器 10 MiB 捕获限制的原生结果帧会使任务原子性地失败,而不是将其私有响应泄漏到 MCP 传输上。
任务刻意设计为连接本地化:重启或重新连接 MCP 服务器会丢失它们。最多可有八个任务处于活动状态,并保留 32 条记录;终态记录在一小时后过期。取消具有与阻塞调用相同的有界结算语义,因此在重试已取消的、可能具有写能力的任务之前,请检查工作树。任务 API 是调用级的选择加入,不要求客户端支持 MCP Tasks。
这些通知刻意让能感知进度的客户端的空闲窗口保持存活,将活性判定权交给包装器的空闲和硬性截止时间。它们不会刷新 --codex_idle_timeout,不会延长包装器的硬性截止时间,也不会延长客户端单独的硬性挂钟工具超时。生成的进度帧只在原生换行边界处插入;如果 Codex 在帧中途停滞,最新通知会等待安全边界,而真正的空闲看门狗仍会终止永久停滞。请将客户端超时配置为超过预期的 Codex 最长运行时间加上响应余量;当它到期时,客户端会取消调用,下面的有界取消路径将接管。
终态结果恢复。 Codex 会在一个早期的、与请求关联的会话事件中宣布线程 ID,因此包装器在构建完成前就将其保留。如果 Codex 随后发出其终态完成事件和最终代理消息,但其原生 tools/call 响应在短暂的终态响应宽限期内未到达,包装器将返回一个等效的成功结果,其中同时包含 content 和 structuredContent.threadId。匹配的迟到原生响应会被丢弃,从而保持 JSON-RPC 响应的恰好一次语义。这覆盖了工作已落入工作树但调用方既未收到结果也未收到线程 ID 的故障模式。
取消与重连。 客户端取消会启动一个短暂的、不可重置的宽限期,由 --codex_cancel_grace 界定(下面的帧中途升级会启用第二个宽限期,因此该路径可能耗时约两倍)。如果 Codex 未在其中完成结算,包装器会在本地结算该请求 ID,抑制 Codex 的迟到响应,并让桥接器和所有同级调用继续运行——单个停滞的调用绝不能让整个桥接器宕掉。有两个有界例外:一个在帧中途卡住且也忽略取消的流(由于没有可注入错误的安全边界,包装器会重试一次,然后升级为整个桥接器的拆除),以及聚合上限——一旦被抑制的响应达到 MAX_SUPPRESSED_CODEX_RESPONSES,桥接器就会终结,而不是无限期跟踪它们。在任一情况之后,客户端会重新连接到一个全新的桥接器。在宽限期内到达的原生响应,只要能在不破坏部分转发的帧的情况下被拦截,就会被丢弃。被取消的、可能具有写能力的调用绝不会自动重放。取消是尽力而为的,并不能证明 Codex 已停止——一个未确认的轮次会被记录为已放弃而非已终止,并且可能继续运行并写入工作区,因此在手动重试之前请检查工作树。
这个遗留桥接器刻意不会在现有 stdio 连接内重新生成 codex mcp-server,也不会透明地重放线程。codex-reply 状态属于旧的 Codex 进程,因此来自已拆除子进程的线程 ID 在重连后无法恢复。持久的同连接恢复需要一次单独的迁移,从透明的遗留直通迁移到基于 codex app-server 的 MCP 适配器(thread/start、turn/start、turn/interrupt 和 thread/resume)。
与 Claude Code 集成
使用全局安装的 mcp-agents 二进制文件,向项目的 .mcp.json 添加条目:
{
"mcpServers": {
"codex": {
"command": "mcp-agents",
"args": ["--provider", "codex"],
"timeout": 7500000
},
"gemini": {
"command": "mcp-agents",
"args": ["--provider", "gemini"]
}
}
}npm(全局安装)与 npx——优先选择全局安装的二进制文件。 上面的 command: "mcp-agents" 形式直接启动本地安装的二进制文件;下面的 npx 替代方案 在每次进程启动时运行 npx -y mcp-agents。这不仅关乎冷启动速度,更关乎可靠性:Claude Code 在(重新)连接时会重新启动 stdio 服务器——包括会话中途重连之后——而 npx 在每次启动时都会执行一次包注册表解析,且没有离线回退。如果该解析很慢(VPN、强制网络门户、注册表故障),缓存过期到已不存在的版本(npm error code ETARGET),或以其他方式失败,则启动失败、传输关闭、工具在该会话中消失。全局安装的二进制文件(或指向 node server.js 的绝对路径)可消除网络依赖,并从信号/拆除路径中减少一个进程层级。使用 npm install -g mcp-agents(或从源码检出执行 npm link)安装一次,然后将配置指向它。
对于用作个人 Codex 桥接器的源码检出,用户级 ~/.claude.json 条目可以直接启动该目录树,并禁用每次请求的空闲上限(这样,长时间且合理静默的审查将仅受客户端自身挂钟超时的限制,而不会被提前中止):
{
"mcpServers": {
"codex": {
"type": "stdio",
"command": "node",
"args": ["/absolute/path/to/mcp-agents/server.js", "--provider", "codex", "--codex_idle_timeout", "0"],
"env": {},
"timeout": 3600000
}
}
}裸 node 会依据 MCP 客户端的 PATH 进行解析;如果 node 由在该环境中未初始化的版本管理器(nvm/fnm/asdf)管理,请改用绝对 node 路径(which node,例如 /opt/homebrew/bin/node)。
在服务器启动时覆盖 codex 默认值:
{
"mcpServers": {
"codex": {
"command": "mcp-agents",
"args": ["--provider", "codex", "--model", "gpt-5.6-sol", "--model_reasoning_effort", "xhigh", "--codex-workspace-network=false"],
"timeout": 7500000
}
}
}每次初始 codex 调用都可以选择 gpt-5.6-sol 或 gpt-5.6-terra,以及 medium、high、xhigh 或 max;省略的选择器使用服务器默认值,回复会继承这两项选择。其他模型、原始 config 以及每次调用的审批策略参数会在 Codex 运行之前被拒绝。向 args 添加 "--goal", "<text>" 以提供默认目标(参见上文 目标注入)。
Claude 将每个服务器的 timeout(以毫秒为单位)解释为硬性挂钟上限;进度不会延长它。请将其保持在包装器的 --timeout(默认 7,200 秒)之上,并包含响应余量。项目的 .mcp.json 条目可以覆盖同名的用户级 MCP 条目,因此请将超时放在项目条目上,而不是依赖用户级副本。
除了上述显式的 Fast-mode 组合外,桥接器不会从你正常的 ~/.codex/config.toml 继承设置。特别是,继承的 MCP 服务器在桥接的 Codex 会话中仍然有意保持不可用。
{
"mcpServers": {
"codex": {
"command": "npx",
"args": ["-y", "mcp-agents", "--provider", "codex"],
"timeout": 7500000
}
}
}npx 只影响进程启动——一旦连接,工具调用延迟无论哪种方式都是相同的服务器代码。但每次启动(包括每次重连)都会针对 npm 注册表解析包,且没有离线回退,因此缓慢、离线或缓存过期的解析可能导致启动失败并在会话中途丢失工具(参见上文 npm vs npx)。固定 mcp-agents@x.y.z 可以避免会话中途的 @latest 拾取刚发布的版本,但并不能消除每次启动的网络依赖。只有在零安装比启动可靠性更重要时,才使用 npx。
与 OpenAI Codex 集成
向 ~/.codex/config.toml 添加两个条目——每个你想使用的提供方一个。960 秒的 Claude 客户端超时保持与阻塞式 900 秒 claude_code 工具的兼容性。后台审查不会保持一个 MCP 请求打开:claude-start 立即返回,每次 claude-status 轮询最多持续 60 秒。
[mcp_servers.claude-code]
command = "mcp-agents"
args = ["--provider", "claude"]
tool_timeout_sec = 960
[mcp_servers.claude-code.tools.claude-start]
approval_mode = "approve"
[mcp_servers.claude-code.tools.claude-status]
approval_mode = "approve"
[mcp_servers.claude-code.tools.claude-result]
approval_mode = "approve"
[mcp_servers.claude-code.tools.claude-cancel]
approval_mode = "approve"
[mcp_servers.gemini]
command = "mcp-agents"
args = ["--provider", "gemini"]
tool_timeout_sec = 360在 Codex 会话中,请求 Claude 的第二意见或审查,并使用 claude-start → claude-status → claude-result。将 claude_code 保留用于小型阻塞提示;gemini 仍然是阻塞工具。
开发
npm install
npm link # symlinks mcp-agents to your local server.js执行 npm link 后,对 server.js 的任何编辑都会立即生效——无需重新安装。
通过真实的 /tmp 项目 .mcp.json 文件对启动路径进行基准测试:
npm run bench:mcp-startup这会测量从 initialize 到 tools/list 的 MCP 启动过程;它不会调用提供方的模型/工具。
如需手动进行 Claude 后台检查,请使用简短的审查提示并以本仓库作为 cwd 调用 claude-start,使用每次返回的游标轮询 claude-status,并使用 claude-result 读取结论。对于相反方向,让 Claude Code 调用 codex-start,轮询 codex-status,并读取 codex-result。这些冒烟检查使用真实的模型调用,并与确定性的测试套件门禁保持分离。
工作原理
MCP 客户端通过 stdio 连接
服务器从其 argv 读取
--provider <name>(默认为codex)Gemini 注册一个阻塞式 CLI 工具;Claude 注册其遗留阻塞工具以及一次性审查任务工具;Codex 转发其原生工具并添加其后台任务工具
客户端使用工具名称和
prompt调用tools/call服务器将 CLI 作为分离的子进程运行;Claude 审查任务将 stream-json 解析为安全的状态和保留的结果页,而阻塞工具返回规范化的提供方输出
服务器会保持一个小的 keepalive 定时器,以便在异步子进程注册活动句柄之前 stdin 到达 EOF 时,Node.js 不会过早退出。对于 Claude 和 Gemini 提供商模式,该 keepalive 会在关闭期间被清除。当 MCP stdio 连接关闭时,活动的 Claude 作业会收到中断,并有有界的 TERM/KILL 回退;任何剩余的受跟踪的分离提供商进程组都会在服务器退出之前被回收。
许可证
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
MCP server for progressive tool usage at any scale (see https://klavis.ai)
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server for Clipkit — gives AI agents a video toolbox via the Clipkit schema.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Related MCP Servers
- AlicenseBqualityAmaintenanceMCP server that lets AI models invoke CLI agents (Gemini, Codex, Claude, OpenCode) as tools — with parallel execution, retries, and structured output parsing.11,491 PyPI4MIT
- AlicenseAqualityBmaintenanceLocal MCP server that wraps the headless Claude Code CLI as MCP tools, providing stateless access to Claude's coding capabilities through prompt-based interactions. It enables users to execute Claude Code commands with various prompt formats and structured outputs directly from MCP clients.3MIT
- FlicenseAqualityDmaintenanceAn MCP server that bridges multiple AI clients (Claude, Gemini, Codex, OpenCode) so they can call each other as tools.181 npm75-
- AlicenseNot gradedqualityCmaintenanceUniversal MCP server that wraps any CLI tool, enabling AI assistants to run commands via natural language.1MIT