AgentBridge
AgentBridge is a local MCP server that lets Claude Code delegate coding tasks to external CLI workers like Codex and Antigravity. It assembles structured prompts, runs the workers with git snapshotting, and returns compact structured results without running its own models.
README
AgentBridge
Status: mid-migration, and this README describes the older shape.
AgentBridge started as a Claude-Code-to-Codex/Antigravity bridge, and everything documented below works today. It is being generalised so that any supported CLI can be the orchestrator and any other can be a worker, with routing driven by a per-user profile instead of hardcoded model names.
For where it is going, read
docs/architecture.mdanddocs/roles.md. In-flight: a provider adapter layer (src/providers/), a routing profile (src/profile/), and anagentbridge initsetup flow. The Cursor adapter is present but unverified — its flags were written from prior knowledge rather than read off an installed CLI, and it says so at the top of the file.Until the migration lands, treat the sections below as accurate for Codex and Antigravity workers, and the docs as accurate for the design.
Orchestrators
AgentBridge serves its /agentbridge … command surface as MCP prompts, so
any MCP client that supports prompts/list gets the same commands from the
server itself — no per-host command files to install or keep in sync.
| Host | Install | Commands |
|---|---|---|
| Codex CLI | docs/install-codex.md |
via MCP prompts, plus hosts/codex/AGENTS.md |
| Claude Code | register the MCP server, then optionally copy hosts/claude-code/skills/agentbridge into ~/.claude/skills/ |
via MCP prompts |
| Command | Does |
|---|---|
agentbridge <goal> |
size the work, plan, delegate, verify, report |
agentbridge_setup |
detect CLIs, prove each works, write the routing profile |
agentbridge_status |
what is installed and how roles map; no inference |
agentbridge_doctor |
diagnose with real smoke jobs and say what to fix |
agentbridge_profile |
show or re-derive routing, optionally one role |
agentbridge_recon |
one bounded repository investigation |
agentbridge_review |
independent review by a different model family |
agentbridge_resume |
continue an interrupted run |
The doctrine behind those commands lives in doctrine/ and names no
models — it routes by role, and .agentbridge/profile.json maps
roles onto whatever the user actually has installed.
A small local stdio MCP server that lets Claude Code delegate work to the
Codex CLI and the Antigravity CLI (agy) as external workers — using
the CLI sessions you are already logged into, with no API keys.
Claude stays the orchestrator. AgentBridge is deliberately dumb plumbing: it turns Claude's structured request into a worker prompt, runs the CLI, and hands back a compact structured result.
User
└─> Claude Code (orchestrator — decides what to delegate)
└─> AgentBridge MCP tool (codex_run / antigravity_run)
└─> codex exec | agy --print
└─> result
<─ structured MCP result
<─ Claude inspects the work and continues
What it is not
No cloud service, web UI, database, daemon, dashboard, job queue, account system, or API-key management. It is one Node process that Claude Code starts over stdio and stops when it exits.
How it works
- Claude calls
codex_runorantigravity_runwith a structured request (goal, mode, model, effort, paths, contract, acceptance criteria…). - AgentBridge assembles a worker prompt from exactly those fields. It runs no model of its own — this is string assembly, not inference.
- It reserves write scopes, snapshots the git working tree, and spawns the CLI
with an argument array (
shell: false). - It parses the CLI's machine-readable output, extracts the worker's final result (never its internal reasoning), diffs the git tree to determine what actually changed, and returns a compact JSON result.
One MCP call = one worker attempt. AgentBridge never retries. Whether another attempt is worthwhile is Claude's decision.
Requirements
| Node.js | ≥ 20.10 (built and verified on 24.14) |
| Codex CLI | on PATH, already signed in (codex login) — verified against codex-cli 0.147.0 |
| Antigravity CLI | agy on PATH, already signed in — verified against agy 1.1.12 |
| git | optional but strongly recommended; without it files_changed / scope_violations cannot be computed |
AgentBridge never reads, copies, exports, or modifies your Codex or Antigravity credentials. It invokes the CLIs exactly as a logged-in human would.
Install and build
npm install
npm run build
npm test
The test suite uses mocked processes throughout, so a normal npm test consumes
no model quota.
Register with Claude Code
Register once at user scope so every project can use it:
claude mcp add --transport stdio --scope user agentbridge -- node D:\Code\Agentbridge\dist\index.js
Verify from a terminal:
claude mcp list
claude mcp get agentbridge
Then verify from inside Claude Code by running /mcp. You should see
agentbridge listed as connected, with three tools: codex_run,
antigravity_run, bridge_status. Ask Claude to call bridge_status for a
full health report.
If you rebuild AgentBridge, restart Claude Code (or reconnect the server from
/mcp) so it picks up the new dist/.
Project directory
Workers run in, and are scoped to, a single project directory, resolved in this order:
AGENTBRIDGE_PROJECT_DIR, then the legacyCLAUDE_PROJECT_DIR(which Claude Code exports).- The first
file://root the MCP client advertises. - The server process's working directory.
bridge_status reports which one was used.
Tools
codex_run
| Field | Type | Notes |
|---|---|---|
goal |
string | required |
mode |
analyze | implement | review |
required |
model |
gpt-5.6-sol | gpt-5.6-terra | gpt-5.6-luna |
required |
effort |
light | medium | high | extra high | max |
required |
relevant_files |
string[] | files to look at first |
allowed_paths |
string[] | required in implement mode |
no_touch |
string[] | paths the worker must not modify |
context |
string | background the repo does not contain |
contract |
string | interfaces/types to conform to exactly |
acceptance_criteria |
string[] | |
tests |
string[] | context for the worker — AgentBridge never runs these itself |
timeout_seconds |
number | default 900, clamped to 30–3600 |
Models. Three slugs are addressable, and each is passed to the CLI verbatim:
model |
What it is |
|---|---|
gpt-5.6-sol |
strongest general engineering model |
gpt-5.6-terra |
deep brownfield / existing-codebase specialist |
gpt-5.6-luna |
economical high-volume workhorse |
Effort mapping (orchestrator label → Codex model_reasoning_effort):
light |
medium |
high |
extra high |
max |
|---|---|---|---|---|
low |
medium |
high |
xhigh |
max |
The mapping is total and deterministic. Codex's ultra tier is deliberately not
exposed: only some models offer it, and a sixth label that works for two of three
models would make routing model-dependent.
Availability. Before launching, AgentBridge checks the requested model and
effort against the Codex CLI's own model catalogue (models_cache.json in
CODEX_HOME) — a file read, no inference.
- model listed, effort listed → the job runs
- model listed, effort not →
invalid_effort, withdetails.supported_efforts - model not listed →
requested_model_unavailable, withdetails.available_models - no readable catalogue → the job runs anyway, with a warning that availability
was
unverified
Nothing is ever substituted for anything else. A routing decision that cannot be honoured comes back as a structured error carrying enough metadata to reroute in one step, rather than as a quietly weaker model.
The invocation built is:
codex exec --json --skip-git-repo-check -m <MODEL> -c model_reasoning_effort="<EFFORT>" \
-s <read-only|workspace-write> -C <PROJECT> -o <tmpfile> --color never
with the prompt streamed over stdin. Model, effort and sandbox are passed on
every call, so a run never inherits whatever happens to be set in
~/.codex/config.toml.
analyze and review use Codex's real read-only sandbox — writes are
genuinely prevented, not merely discouraged.
antigravity_run
Same schema, with:
| Field | Type | Notes |
|---|---|---|
model |
Gemini Flash 3.7 |
required |
effort |
light / medium / high |
optional, defaults to medium |
Logical names are resolved at run time against the live agy models list:
| Label | Effort | Resolves to (on this machine) |
|---|---|---|
Gemini Flash 3.7 |
light |
gemini-3.7-flash-low |
Gemini Flash 3.7 |
medium |
gemini-3.7-flash-medium |
Gemini Flash 3.7 |
high |
gemini-3.7-flash-high |
Antigravity encodes the reasoning tier in the model id, so model + effort
resolve to a single id and no separate --effort flag is sent — the two can
never disagree. Flash has only these three tiers: extra high and max return
invalid_effort rather than quietly running a weaker tier than you asked for.
Antigravity is intentionally scoped to the cheap Gemini tier. The Claude models
that agy also offers are not exposed as routable labels — for Claude-class
reasoning, use Claude Code itself or Codex, which have real sandboxing and
(for Codex) selectable effort.
The label has an ordered candidate list of ids for the same model. If none
of them are offered by the installed CLI, the call fails with
requested_model_unavailable and the full available-model list. It never
silently falls back to a different model. The resolved id is echoed back in
warnings on every run.
The invocation built is:
agy --print <PROMPT> --model <RESOLVED_ID> --output-format json \
--mode <plan|accept-edits> --add-dir <PROJECT> \
--dangerously-skip-permissions --print-timeout <N>s
--disable-slash-commands is added only for implement runs: the CLI ignores
--mode plan whenever slash-command expansion is disabled, so sending both would
silently discard the only no-write behaviour Antigravity offers.
bridge_status
No arguments. Consumes no model inference — it only runs --version probes,
agy models, one git rev-parse, and a read of the Codex CLI's model cache.
Returns:
- AgentBridge version, project directory (and how it was resolved), node/platform
git_verification— whether git-basedfiles_changed/scope_violationswill work here at all. When it will not, an emptyscope_violationsis silence, not a clean bill of health, and the warnings say socodex.installed/version/path/authcodex.model_status— per model:available|unavailable|unverified, the AgentBridge effort labels it accepts, and the CLI's raw reasoning levelscodex.model_source— where availability came from and how fresh it isantigravity.installed/version/path/auth, detected models, how each logical label + tier resolved, andmodel_statusin the same three-state shapeantigravity.unsupported_efforts— the orchestrator labels Flash cannot take- active jobs and their write scopes
- warnings
Availability is never guessed. When the installed CLI offers no cheap proof, the
status is unverified rather than a claim in either direction.
It never returns credentials or environment variables.
Result format
{
"status": "success",
"provider": "codex",
"model": "gpt-5.6-luna",
"effort": "high",
"mode": "implement",
"duration_ms": 12345,
"exit_code": 0,
"summary": "...",
"files_changed": ["src/upload.ts"],
"scope_violations": [],
"tests_or_checks_run": ["npm test -- upload"],
"test_results": "12 passed",
"concerns_or_blockers": [],
"stderr_tail": "",
"warnings": []
}
effort is present for both providers — the Codex reasoning level, or the Flash tier the model id encodes. files_changed and scope_violations are
computed by AgentBridge from git, not taken from the worker's word. Internal
reasoning is dropped. summary is capped at 16 000 characters, keeping the head
and tail and setting summary_truncated: true when it clips.
Errors
Failures return the same envelope shape with status: "failed", an error
category, an actionable message, and — where available — exit_code,
stderr_tail, and a details object.
| Category | Meaning |
|---|---|
executable_not_found |
codex / agy not on PATH |
authentication_required |
the CLI reported a login problem — sign in again yourself |
requested_model_unavailable |
the requested model is not offered; no substitution was made |
invalid_effort |
effort label outside the five supported values |
invalid_arguments |
e.g. implement mode without allowed_paths |
scope_conflict |
another active worker already owns overlapping write paths |
scope_violation |
a supplied path escaped the project root, or the worker wrote outside its scope |
timeout |
the worker overran; its process tree was terminated |
process_failed |
non-zero exit, or a non-SUCCESS CLI envelope |
output_parse_failed |
the CLI's machine-readable output could not be parsed |
Examples of Claude calling the workers
Cheap, fast analysis:
{ "tool": "codex_run",
"goal": "Explain how session refresh works and where it can race.",
"mode": "analyze", "model": "gpt-5.6-luna", "effort": "light",
"relevant_files": ["src/auth/session.ts"] }
Hard implementation, maximum reasoning, tightly scoped:
{ "tool": "codex_run",
"goal": "Make the uploader retry 502s with exponential backoff.",
"mode": "implement", "model": "gpt-5.6-sol", "effort": "max",
"allowed_paths": ["src/upload.ts", "tests/upload.test.ts"],
"no_touch": ["src/auth"],
"contract": "export function upload(f: File): Promise<Result>",
"acceptance_criteria": ["Retries up to 3 times", "Existing callers unchanged"],
"tests": ["npm test -- upload"] }
Two Codex workers on disjoint scopes — these run concurrently:
{ "tool": "codex_run", "mode": "implement", "model": "gpt-5.6-sol",
"effort": "high", "allowed_paths": ["src/api"], "goal": "..." }
{ "tool": "codex_run", "mode": "implement", "model": "gpt-5.6-luna",
"effort": "medium", "allowed_paths": ["src/ui"], "goal": "..." }
Antigravity for cheap mechanical work:
{ "tool": "antigravity_run", "goal": "Summarise every exported symbol in src/lib.",
"mode": "analyze", "model": "Gemini Flash 3.7", "effort": "light" }
{ "tool": "antigravity_run", "goal": "Build the settings page from design.png.",
"mode": "implement", "model": "Gemini Flash 3.7", "effort": "high",
"allowed_paths": ["src/pages/settings"] }
Concurrency and file scope
implementrequiresallowed_paths. Paths are normalised against the project root; anything escaping it (.., other drives, absolute paths elsewhere) is rejected before a process starts.- Active
implementjobs hold their write scopes in memory. A new job whose scopes overlap an active one is refused withscope_conflict. Disjoint scopes run in parallel — unrelated work is never serialised. analyzeandreviewreserve nothing: they never block, and are never blocked.
V1 limitation: detection, not isolation
File-scope protection detects and reports violations; it does not sandbox
each worker into its own tree. A Codex implement worker runs with
workspace-write across the project, so it can write outside its
allowed_paths — AgentBridge will list every such file in scope_violations,
downgrade the status from success, and tell you plainly.
Nothing is ever reverted automatically. Reverting a file that was already modified before the worker started would destroy your (or Claude's) existing work. Detection plus honest reporting is the V1 contract; git-worktree isolation is deliberately out of scope.
Attribution is careful about pre-existing state: files that were already dirty before a run and are byte-identical afterwards are never blamed on the worker. Comparison uses porcelain status plus content hashing, and committed files are picked up via a HEAD-move diff.
Security
- Processes are spawned with argument arrays and
shell: false— never an interpolated command string. Shell metacharacters in arguments stay literal. - Windows
.cmd/.ps1launchers (which Node refuses to spawn without a shell) are resolved to their real Node entry script and run asnode <script>, soshell: trueis never needed. - Prompts go to Codex over stdin; oversized Antigravity prompts are written to a temp file and referenced by path. Neither can hit the Windows 32 767-character command-line limit.
testsis context for the worker. AgentBridge never executes it, and there is no MCP argument anywhere that becomes a command AgentBridge runs.- Path traversal outside the project root is rejected.
- Timeouts kill the whole process tree:
taskkill /T /Fon Windows, and on POSIX a SIGTERM to the process group escalating to SIGKILL after a 3-second grace period. The escalation deliberately survives the direct child's exit, since that is exactly when descendants may still be running. This is best-effort — Node exposes no Windows Job Object, so iftaskkillitself cannot start, only the direct child can be reached. - Output buffers are bounded (8 MB per stream) and UTF-8 is decoded only after reassembly, so multi-byte characters are never split.
- Logs record job metadata only. Never tokens, never the environment, and
prompts/outputs only when
AGENTBRIDGE_DEBUG=1. - What AgentBridge does not protect you from: the worker is a real coding
agent running with your permissions. In
implementmode it can run repository commands through its own tooling. Scope yourallowed_pathsaccordingly.
Verification
AgentBridge runs the project's own checks itself after a worker exits, outside
any sandbox, and returns the real output in verification:
"verification": [
{ "command": "npm run typecheck", "ok": true, "exit_code": 0, "timed_out": false, "duration_ms": 4120, "output_tail": "..." },
{ "command": "npm run test", "ok": false, "exit_code": 1, "timed_out": false, "duration_ms": 8830, "output_tail": "..." }
]
verify_commands— run exactly these, in any mode.- Omitted in implement mode — AgentBridge reads
package.jsonand runs thetypecheckandtestscripts if they exist. It never runsbuild,dev, orstarton its own initiative; ask for those explicitly. skip_verification: true— run nothing, and rely on the worker's account.
Commands run without a shell, so |, &&, ;, > and backticks outside
quotes are refused rather than half-executed. A failing check sets
error: "verification_failed" and downgrades a success to partial, so a
worker claiming green tests cannot outrank the tests themselves.
tests_or_checks_run and test_results report what AgentBridge actually ran
whenever verification happened; they fall back to the worker's own claims only
when it did not.
Because the commands come from the repository, a brief that names the wrong
runner cannot make AgentBridge run it: a repo whose test script is
node --import tsx --test is checked with that, whatever the brief said.
Environment variables
| Variable | Purpose |
|---|---|
AGENTBRIDGE_PROJECT_DIR |
project directory; host-neutral, preferred |
CLAUDE_PROJECT_DIR |
legacy name, still honoured; set by Claude Code |
AGENTBRIDGE_DEBUG=1 |
log sanitized prompts and outputs |
AGENTBRIDGE_LOG_DIR |
log location (default ~/.agentbridge/logs) |
AGENTBRIDGE_CODEX_BIN |
explicit path to the Codex CLI |
AGENTBRIDGE_AGY_BIN |
explicit path to the agy CLI |
AGENTBRIDGE_CODEX_SANDBOX |
pin the Codex sandbox policy: read-only, workspace-write, danger-full-access, or auto (default) |
AGENTBRIDGE_CODEX_WINDOWS_SANDBOX |
Windows sandbox backend (default unelevated) |
AGENTBRIDGE_CODEX_SANDBOX=auto uses read-only for analyze/review and
workspace-write for implement — except that on Windows a sandboxed Codex
worker cannot capture a subprocess's output (spawn EPERM on piped stdio),
which is what npm scripts, test runners, and bundlers all do — so it can read
and edit but can never run a test runner, type checker, or build. That is a Codex
limitation with no configuration knob, so implement jobs fall back to
danger-full-access once a one-shot probe confirms it, and say so in
warnings. Analyze and review keep their enforced read-only boundary. On Windows, if a run fails with the broken
sandbox helper (helper_unknown_error: apply deny-read ACLs), AgentBridge
retries that job once with danger-full-access, remembers the verdict for the
rest of the process, and attaches a warning to every affected result saying the
boundary was not enforced. Nothing else triggers that fallback, and restarting
AgentBridge re-tries the real sandbox — so a fixed Codex release restores it
automatically. macOS and Linux never probe, retry, or fall back.
Logs are one JSON line per job: timestamp, job id, provider, model, effort, mode, project, duration, exit code, error category.
Troubleshooting
executable_not_found — the CLI is not on the PATH that Claude Code
exports to child processes. Confirm with codex --version / agy --version in
the same shell, or set AGENTBRIDGE_CODEX_BIN / AGENTBRIDGE_AGY_BIN.
authentication_required — your CLI session lapsed. Fix it in a terminal:
codex login for Codex, or sign in again with agy. AgentBridge deliberately
has no way to repair this: it does not touch credentials.
requested_model_unavailable — the model list changed, or the installed CLI
never offered that model. Run bridge_status (or agy models) to see what is
actually offered; the error's details already carry it. AgentBridge fails here on
purpose rather than quietly running a different model. If a provider renamed a
model id, add the new id to that label's candidate list in
src/models/antigravity.ts (or to CODEX_MODELS in src/models/codex.ts),
then rebuild.
output_parse_failed — the CLI changed its machine-readable output shape.
Check details.stdout_head in the result, then compare against
parseCodexEvents / parseAgyOutput.
After a CLI update — re-run the tests, then the live smoke check:
SMOKE_LIVE=1 node scripts/smoke.mjs
That drives a real MCP session and runs the cheapest configuration of each
worker. Without SMOKE_LIVE=1 it only performs the handshake and
bridge_status, consuming nothing.
files_changed is always empty — the project directory is not inside a git
working tree. The warning in the result says so. Change verification needs git.
Nothing appears under /mcp — check the registered path points at
dist/index.js (built, not src/), and restart Claude Code after a rebuild.
Layout
src/
index.ts stdio entry point
server.ts MCP server, tool schemas, dispatch
config.ts project-dir resolution, timeout clamping
logging.ts JSONL job log (stderr only, never stdout)
parse.ts worker-envelope parsing, summary capping
types.ts
cli/
resolve.ts PATH lookup + Windows shim unwrapping
detect.ts version probes, agy model listing, auth heuristics
codex-catalogue.ts zero-inference Codex model availability + effort capability
codex-sandbox.ts sandbox policy decision and helper-failure detection
models/
codex.ts effort map, argv construction
antigravity.ts logical→real model resolution, argv construction
process/
runner.ts shell-free spawn, bounded output, tree kill
prompts/
worker-prompt.ts structured request → worker prompt
scope/
paths.ts normalisation, traversal rejection, overlap
locks.ts in-memory write-scope registry
git-state.ts snapshot/diff file attribution
tools/
codex.ts antigravity.ts status.ts common.ts
tests/ 252 tests, mocked processes, no quota used
scripts/smoke.mjs real MCP end-to-end check
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。