{
  "markdown": "# agent-mcp-hub\n\nOne MCP server that bridges multiple CLI coding agents — **Codex**, **Cursor**,\n**OpenCode**, **Claude**, and **Antigravity** — into any MCP client.\n\n> **stdio only — by design.** The hub ships no Docker image and no HTTP\n> transport (both were removed during the 0.5.x line). A containerised or remote\n> server cannot see the caller's repository path and cannot reuse the caller's\n> CLI logins — it would break the product contract on both halves. The hub runs\n> as a child process of your MCP client, on your machine, as you.\n\n## Tools\n\n| Tool | Description |\n|---|---|\n| `codex` | Delegate a prompt to `codex exec` (prompt piped via stdin) |\n| `cursor` | Delegate a prompt to `cursor-agent -p` (prompt piped via stdin) |\n| `opencode` | Delegate a prompt to `opencode run` |\n| `claude` | Delegate a prompt to the Claude Code CLI (prompt piped via stdin) |\n| `agy` | Delegate a prompt to Google Antigravity (`agy --print=…`, prompt passed as a flag value) |\n| `run_all` | Same prompt to all agents in parallel, results side by side |\n| `list_agents` | Which agent CLIs are installed and on PATH |\n| `ping` | Health check |\n\nAgent tools accept `prompt` (required), `model`, `cwd`, `timeoutMs` (total runtime\ncap, default 1800000 = 30 min), and `idleTimeoutMs` (inactivity cap, default 300000\n= 5 min). See [Long-running tasks & timeouts](#long-running-tasks--timeouts).\n\nKnown limitation: `opencode` prompts may not start with `-` (its CLI could parse\nthem as flags); the tool returns an actionable error instead of guessing.\n\n### Choosing models per agent\n\n**Model ids are agent-specific and do not overlap.** `o3` means nothing to\n`agy`, `gemini-3.6-flash-low` means nothing to `codex`, and `opencode` namespaces\nits own (`opencode/big-pickle`). So a single `model` value is valid for at most\none agent in a fan-out.\n\n- `run_all` takes **`models`** — a per-agent map. Agents you don't list fall back\n  to `model`, then to their own CLI default.\n- `review_change` takes **`runnerModel`** and **`reviewerModel`**, so the agent\n  writing the change and the agent judging it can use different engines *and*\n  tiers. `model` remains a fallback for both.\n\n```json\n{\n  \"tool\": \"run_all\",\n  \"arguments\": {\n    \"prompt\": \"Explain the retry logic in src/exec.ts\",\n    \"models\": { \"codex\": \"o3\", \"agy\": \"gemini-3.6-flash-low\", \"claude\": \"haiku\" }\n  }\n}\n```\n\nAn unknown agent name in `models` is rejected with the list of enabled agents —\na typo never silently falls back to the default model.\n\nWhere to find valid ids: `opencode models`, `cursor-agent models` and\n`agy models` list them. `codex` and `claude` have no such command — codex reads\nits default from `~/.codex/config.toml`, and claude accepts the documented\naliases (`opus`, `sonnet`, `haiku`, `fable`). Note `claude models` is **not** a\nsubcommand: it is treated as a prompt, so its \"model list\" is generated text,\nnot a source of truth.\n\n### Error handling\n\nWhen a wrapped CLI fails, the hub classifies the failure and returns a clean,\nANSI-free, actionable `isError` result — never a raw terminal dump — naming the\nclass and the exact fix:\n\n| Class | Example remediation |\n|---|---|\n| `not_installed` | install the CLI (e.g. `npm i -g @openai/codex`) / fix PATH |\n| `not_authenticated` | `codex login` · `cursor-agent login` · `opencode auth login` · `claude` → `/login` · `agy` → sign in on first run (or set the matching API key) |\n| `not_configured` | set a model/provider in the CLI's config |\n| `timed_out` | raise `timeoutMs`, or check the agent/model is responsive |\n| `stream_stalled` | the agent reached the network but its stream keeps dropping (e.g. `cursor` behind a TLS-intercepting proxy) — treat that agent as unavailable; raising `timeoutMs` will not help |\n| `server_busy` | retry shortly (upstream rate-limit, or the local agent-spawn queue is full) |\n| `tool_failure` | generic non-zero exit — the message includes `(exit N)` and a trimmed output tail |\n\nFor example, an unauthenticated `cursor` no longer returns its ANSI \"press any\nkey to sign in\" banner — it returns `cursor is not authenticated … Fix: run\n`cursor-agent login``.\n\n### Review a change (`review_change`)\n\nRuns a `runner` agent in a git `cwd` to make a change, captures the actual\n`git diff` of what changed, then has a `reviewer` agent judge that diff. Returns\nthe runner's output, the diff (`--stat`), and a **PASS / WARN / FAIL** verdict\nwith findings.\n\n**Inputs:** `runner`, `reviewer` (agent names), `prompt`, `cwd` (must be a git\nworktree), optional `runnerModel`, `reviewerModel`, `model` (fallback for both),\n`timeoutMs`.\n\n**Key notes:**\n\n- Cross-agent by design — e.g. `codex` writes, `claude` reviews.\n- Returns the concrete diff that the plain agent tools don't expose.\n- Newly-created (untracked) files are surfaced to the reviewer **with their\n  contents** (bounded: 64 KiB per file, 50 files; excess is truncated and\n  flagged). `git diff` alone would omit them entirely.\n- If the worktree was already dirty, the diff may include pre-existing changes\n  (noted in the output).\n- Complements — does not replace — client-side stop-hooks or PR-time CI review.\n- The confirm gate (`MCP_CONFIRM`) applies.\n- **The reviewer runs least-privilege — but how much that guarantees depends on the\n  agent.** The reviewer's prompt embeds an attacker-influenced diff, so it is run\n  read-only rather than with the write grant the runner gets. Only two of the five\n  are real restrictions:\n\n  | Reviewer | Read-only mechanism | Enforced? |\n  |---|---|---|\n  | `codex` | `-s read-only` | **Yes — OS-level sandbox** |\n  | `claude` | `--disallowedTools Write,Edit,…,Bash` | **Yes — harness-level deny** |\n  | `cursor` | `--trust --mode plan` (no `--force`) | No — model-advisory only |\n  | `agy` | permission grant withheld | Partly — headless auto-deny, not a sandbox |\n  | `opencode` | *none available* | **No — unrestricted** |\n\n  Pick `codex` or `claude` as the reviewer if you want the restriction to be real.\n  This is defense-in-depth alongside the nonce-fenced diff and the throwaway temp\n  cwd; none of it is a sandbox.\n\n```json\n{\n  \"tool\": \"review_change\",\n  \"arguments\": {\n    \"runner\": \"codex\",\n    \"reviewer\": \"claude\",\n    \"prompt\": \"Add retry with exponential backoff to the API client\",\n    \"cwd\": \"/Users/you/projects/my-app\"\n  }\n}\n```\n\n## Prerequisites\n\nInstall and authenticate the CLIs you want to use (any subset works):\n\n- Codex: `npm i -g @openai/codex && codex login`\n- Cursor: `curl https://cursor.com/install -fsS | bash && cursor-agent login`\n- OpenCode: `npm i -g opencode-ai && opencode auth login`\n- Claude Code: `npm i -g @anthropic-ai/claude-code && claude` (first run logs in)\n- Antigravity: install the Antigravity CLI (e.g. `brew install --cask antigravity-cli`),\n  then run `agy` once and sign in — it has no `login` subcommand and stores\n  credentials in the OS keyring, so there is no API-key env var to set\n\n## Install\n\n**Recommended — global install (fast, reliable startup):** install the pinned\nversion once, then point your client at the `agent-mcp-hub` binary. Startup is\ninstant and the client connects reliably.\n\n```bash\nnpm i -g agent-mcp-hub@0.5.0\n```\n\n### Claude Code\n\n```bash\nclaude mcp add agent-hub -- agent-mcp-hub\n```\n\n### Cursor / generic mcp.json\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-hub\": {\n      \"command\": \"agent-mcp-hub\"\n    }\n  }\n}\n```\n\n### Zero-install alternative (npx)\n\nNo global install, but npx re-resolves the package on every launch, so first\nstart is slower and can occasionally trip a client's connection-probe timeout\n(the server itself is fine — just retry). Prefer the global install for a\npersistent setup.\n\n```bash\nclaude mcp add agent-hub -- npx -y agent-mcp-hub@0.5.0\n# mcp.json:  \"command\": \"npx\", \"args\": [\"-y\", \"agent-mcp-hub@0.5.0\"]\n```\n\n> **Pre-release / fallback:** To test an unreleased commit, run directly from\n> GitHub: `npx -y github:blackaxgit/agent-mcp-hub#<tag-or-sha>`. This builds\n> from source on first fetch, so under npm v12+ you must allow the `prepare`\n> script.\n\n## Configuration\n\n**`MCP_AGENTS`** — comma-separated allowlist of the agents to expose\n(`codex,cursor,opencode,claude,agy`). Unset or empty exposes all agents. Disabled\nagents get no tool and are absent from `list_agents`/`run_all`. An unknown name\nfails at startup with an error listing the valid names, so typos never silently\ndisable an agent.\n\nFor stdio, set it in the client's `mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-hub\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"agent-mcp-hub@0.5.0\"],\n      \"env\": { \"MCP_AGENTS\": \"codex,claude\" }\n    }\n  }\n}\n```\n\n### Confirm before running an agent — `MCP_CONFIRM`\n\nSet `MCP_CONFIRM=1` (values `1`/`true`/`on`/`all`; default off) to require a\nconfirmation before any agent tool — and `run_all` — actually spawns a CLI. The\nserver sends a brief summary (agent · prompt · cwd · model) and waits: **accept**\nruns the agent, **decline** runs nothing and returns a terminal cancellation.\n\nThis uses the standard MCP **elicitation** capability, so it is **client/IDE-agnostic** —\nit works with any MCP client that supports form elicitation (Claude Code, Cursor,\nVS Code, Zed, Windsurf, custom SDK clients, …); the gate keys on the protocol\ncapability, never a product name. Clients that don't support elicitation\ntransparently run without a prompt (no hang, no error).\n\n```json\n{\n  \"mcpServers\": {\n    \"agent-hub\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"agent-mcp-hub@0.5.0\"],\n      \"env\": { \"MCP_CONFIRM\": \"1\" }\n    }\n  }\n}\n```\n\n### Long-running tasks & timeouts\n\nA complex agent task can run for many minutes. The hub bounds each run with two\nindependent timers so a productive long run survives while a genuinely stuck one\nfails fast:\n\n- **Idle (inactivity) timeout** — `idleTimeoutMs` (per call) / `MCP_AGENT_IDLE_TIMEOUT_MS`\n  (env), default **300000 (5 min)**. The timer resets on every chunk of output the\n  CLI produces, so an agent that keeps working (streaming output) never trips it. An\n  agent that goes silent — e.g. `opencode` stuck on an unreachable model backend —\n  is killed after the idle window with an actionable \"no output — the agent may be\n  hung or its model/backend is unreachable\" error, instead of burning the full cap.\n- **Total runtime cap** — `timeoutMs` (per call) / `MCP_AGENT_TIMEOUT_MS` (env),\n  default **1800000 (30 min)**. A hard upper bound regardless of activity.\n\nWhichever fires first kills the agent's process group. **Tradeoff:** the idle reset\nassumes the CLI streams intermediate output. `codex` and `opencode` do; `claude -p`,\n`cursor-agent -p` and `agy --print` may emit only the final result, so a long\n**silent** task on those can be idle-killed at 5 min — raise `idleTimeoutMs` /\n`MCP_AGENT_IDLE_TIMEOUT_MS` for such tasks, or rely on the total cap.\n\n`agy` is the strongest case here: it emits its entire answer in one flush at the\nend (measured — every line of a 12-line reply arrived at the same instant), and\nthe hub raises its internal `--print-timeout` to 48h so that agy's own 5-minute\ndefault can never truncate a run. The idle timer is therefore agy's only\nprotection against a genuine hang; budget `idleTimeoutMs` accordingly for long\nautonomous agy tasks.\n\nWhile an agent runs, the hub emits MCP **progress notifications** to clients that\nrequest them (`_meta.progressToken`) — live feedback during long runs. Note: on\n**Claude Code (stdio)** the per-server request `timeout` in `.mcp.json` (or the\n`MCP_TOOL_TIMEOUT` env var it honors) is a hard wall-clock that progress does\n**not** reset (default ~28h) — raise it if you lowered it below your longest run.\n\n## Upgrading\n\n**Global install:** install the new version — the pinned `agent-mcp-hub` command\nin your MCP config picks it up on the next client start:\n\n```bash\nnpm i -g agent-mcp-hub@0.6.0\n```\n\n**npx (pinned):** bump the pinned version in your MCP config — e.g. change\n`agent-mcp-hub@0.5.0` to `agent-mcp-hub@0.6.0` everywhere.\n\n**Always-latest (not recommended for shared configs):** use `agent-mcp-hub@latest`\ninstead of a pinned version. Note that `npx` caches by version — it may serve a\nstale copy. Force a fresh fetch with `npx --prefer-online agent-mcp-hub` or\n`npx clear-npx-cache`.\n\nPinning is reproducible and recommended for team-wide or checked-in\n`mcp.json` files.\n\n## Development\n\n```bash\nnpm install\nnpm test           # vitest\nnpm run typecheck  # strict TS over src + tests\nnpm run dev        # run from source over stdio\nnpm run build      # emit dist/\n```\n\n## Architecture\n\nPure adapters (`src/adapters/*` — prompt → `{args, stdin?}`, no I/O) → one\nsubprocess boundary (`src/exec.ts`) → MCP stdio server (`src/server.ts`). Adding\nan agent = one ~15-line adapter file + one line in `src/registry.ts`.\n\n## License\n\n[Mozilla Public License 2.0](./LICENSE) (MPL-2.0).\n\nVersions **before 0.5.2 were released under the MIT license**; that grant stands\nfor those versions. MPL-2.0 applies from 0.5.2 onward.\n",
  "bytes": 12924,
  "sha": "1e0ba8899f3801865014ca6d9c2050d0a4e32afc585a0ddce50f806a8bd751c0",
  "repo_slug": "blackaxgit/agent-mcp-hub",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_blackaxgit_agent_mcp_hub_7a5f92cd/readme"
}