ACP Gateway
Let the coding agent you already use delegate work to Claude Code, Codex, and Grok on demand — over MCP + ACP, with persistent sessions, interactive approvals, and no predefined workflows.
ACP Gateway is a local daemon and Model Context Protocol (MCP) server: whichever of Claude Code, Codex, or Grok you talk to uses it to delegate work to the others, and to any other installed agent listed in the official Agent Client Protocol (ACP) registry.
Do you use more than one AI agent?
Do you ask Claude a question, have Codex fix the code, then hand the review to Grok — juggling terminals and conversations the whole time?
Have you ever thought, “Instead of directing each of these agents myself, I wish one agent would just put the others to work for me…”?
That is what this is for.
Overview
ACP Gateway is middleware that lets the AI you talk to directly — the orchestrator — discover the AI Workers installed on your machine, run them over ACP, and manage everything from long-running tasks and permission requests to retrieving the final result. Main, as used in the code and tool descriptions, means this orchestrator role.
- Claude Code, Codex, and Grok are supported as built-in Workers; other ACP-capable AIs installed locally are discovered by matching them against the official ACP registry.
- The daemon keeps ACP sessions and provider processes alive.
- Worker sessions can be recovered even when MCP restarts.
- The orchestrator controls models, permissions, questions, cancellation, and result collection.
- The Gateway strips its token, socket and Main identity from Worker environments, but a Worker that reads files without going through the Gateway can still find the token; see Permission policies.
- Designed for local, single-user, single-machine use.
Use cases
- One conversation, several agents — From Claude Code, have Codex implement a change and Grok review it, without leaving the conversation or switching terminals.
- Follow-ups in the same session — Send feedback to the Worker that did the work instead of starting over. If its session was unloaded while idle, the next prompt reconnects it on providers that support resume or load.
- Approvals from your main agent — Under the
askpolicy, a Worker's permission requests and questions come to the agent you talk to, which approves, denies or answers them, or checks with you first. - Results after a reconnect — After your host reconnects or the Gateway restarts,
agent_acp_inbox {action: "attention"}lists what is still waiting on you and the finished results you have not collected. - Reviews that cannot touch your tree — Open a reviewer with
workspace: "snapshot"so it works in a private copy of the repository, then read its changes as a patch withworkspace_diffand apply only what you want. - Why a session stopped — Each session records the reason for its status, and
agent_acp_session {action: "check"}tells you, without starting anything, whether it can come back.
Quick start
Requirements
Node.js 22 or later, and macOS or Linux.
Install
Install the Gateway from npm, then let the bootstrap set it up for the agents on your machine:
npm install -g acp-gateway-daemon
acp-gateway-bootstrap --install-all --refresh-registry --dry-run
acp-gateway-bootstrap --install-all --refresh-registry
The Claude Worker runs the Claude CLI you have installed: the one CLAUDE_CODE_EXECUTABLE names if it is not blank, otherwise the first claude in an absolute directory on the daemon's PATH (skipping copies inside the Gateway's own dependencies and any binary bundled with the Claude Agent SDK), otherwise ~/.local/bin/claude; if none is found, Claude is reported as not installed.
Of the last two commands, the first is a dry-run that only shows the installation plan, and the second performs the actual installation. --install-all can install or update, globally, the npx and uvx packages named by the official ACP registry, so check the targets and versions in the dry-run output first. The registry manifest is maintained by ACP, but the actual packages and binaries are downloaded from each vendor's distribution site. What the installation changes on your machine is listed in What installation changes on your machine.
By default, --install-all asks which of Codex, Claude, or Grok you want to use as the front door — the agent you talk to. The Control MCP for the orchestrator is registered only with the one you choose, while the read-only Guide MCP and the skill are installed for every discovered agent. In non-interactive installs Codex is the default, and you can choose explicitly like this:
acp-gateway-bootstrap --install-all --front-door codex
acp-gateway-bootstrap --install-all --front-door claude
acp-gateway-bootstrap --install-all --front-door grok
From source
To run the Gateway from a Git checkout instead, for example to change the code, clone and link it:
git clone https://github.com/creverse-ai-lab/agent_gateway.git
cd agent_gateway
npm ci
npm link
acp-gateway-bootstrap --install-all --refresh-registry --dry-run
acp-gateway-bootstrap --install-all --refresh-registry
npm link puts the same commands on your PATH, running straight from the checkout. The last two commands and the front-door choice work exactly as above.
First delegation
The installer also installs the agent-delegator skill for every discovered AI. From your request, the skill works out the Worker, model, and permission scope, and it guides everything from creating a Gateway session and handing over the task to checking progress, handling questions and permission requests, and retrieving the result. After installation you do not need to memorize MCP tool names — just ask the orchestrator in natural language.
For example, you can ask the orchestrator AI you are talking to:
Have Claude Sonnet review the authentication code in this repository, read-only, and summarize the result.
Have Grok 4.5 red-team the security weaknesses of the current design, and check with me on any permission requests.
Internally it works in this order:
agent_acp_setupchecks the providersagent_acp_session_opencreates a Worker session- If needed,
agent_acp_configreads and sets parameters the Worker supports, such as model, mode, and reasoning level agent_acp_runhands over the taskagent_acp_waitwaits until the Worker finishes or needs a response, instead of polling withagent_acp_poll- If needed,
agent_acp_permissionoragent_acp_answerresponds - When done, reuse the session or close it with
agent_acp_session
The bundled agent-delegator is a general-purpose starting point. If you have a Worker you use often, a default model, a permission policy, a review order, or a result format, you can edit the installed skill to fit the way you work. acp-gateway-bootstrap --update and a plain --update-skill do not overwrite your edited copy. Run --update-skill --force explicitly only when you want to reset it to the version bundled with the installed Gateway.
Permission policies
Choose one of the following policies when you open a session.
The Control token, the orchestrator identifier (Main ID), and the Gateway socket path are removed from the ACP Worker's environment, and re-injecting the Control MCP into a Worker session is blocked, whether by its name, its installed path, or the identity in its environment. Nor can a Worker's own CLI start it from your agent configuration, as a Codex Worker would from ~/.codex/config.toml: the Control MCP refuses to run inside a Worker's process tree, and the daemon refuses Control to any caller running under it (WORKER_CONTROL_DENIED). On macOS and Linux, where the process tree cannot be read at all (no /proc, and ps missing or blocked, so the Control MCP cannot read even its own process), both refuse, since a Worker cannot then be told from a Main. Windows has neither, so there nothing is refused for that, and a Worker is told apart only by the ACP_GATEWAY_WORKER variable the Gateway sets on it, or when the agent CLI asking for Control is itself a process the daemon started. The daemon also removes the token and Main ID from its own environment at startup, so nothing it starts, adapter updates through npm or uv included, inherits them. The rest of the daemon's environment, which comes from whatever started it, usually a front door or the installer, still reaches Workers and their terminals, API keys, cloud credentials and SSH_AUTH_SOCK included, so a provider that signs in through its environment keeps working.
File reads and writes the Gateway makes for a Worker (ACP fs/read_text_file and fs/write_text_file) stay inside the session roots and off the protected paths even when the Worker swaps in a symbolic link or another directory while they run. A read also never returns a file that holds the Gateway's Control token, such as a copy of install.json. When the installer replaces install.json, it also empties the old file if a hard link still holds it, as far as it can: not on Windows, which has no open that refuses to follow a link, and not when the old file cannot be opened for writing; such a link keeps the old content, but the Gateway's read still refuses it for the token it holds. On macOS, and on Linux with /proc, a write creates a new file only in the directory that was checked. Elsewhere (Linux without /proc, other systems) such a swap during a write can still leave a new, empty file where the swapped-in link points; the write is refused, nothing is written into that file, and the Gateway does not delete it, since a deletion by name could be redirected the same way. Gateway clients, the Control MCP included, send the token only to a socket owned by the same user, on a path no other user can redirect. Terminals the Gateway opens for a Worker run on macOS in a sandbox that denies the protected paths (~/.acp-gateway, the state directories and the socket); setuid programs such as ps and top cannot start inside it, and a command that cannot start exits with status 71. Where there is no such sandbox, auto_approve sends each terminal to the orchestrator first. Approving a Worker's command lets that exact command through once, word for word, with exactly the same environment variables and values, and in the same working directory: the directory that was at that path when the orchestrator was asked, not another one put there since. Approving an edit lets one write through to each file it named, as long as its path still leads to the file that was there when the orchestrator was asked; where there was no file, the write may only create one. When the edit request showed the orchestrator diffs of a file, the write must also be exactly what those diffs make of the file; any other content is asked about anew. Any other terminal or write reaches the orchestrator with its command, arguments, working directory and environment variables (the values of those that make a program load or run code, such as PATH, PYTHONPATH or LD_PRELOAD, or that the command line uses, and only the names of the rest), or with its path, its size, the SHA-256 of its content and the content itself, up to its first 2 KiB; a terminal approved there runs only in the working directory the orchestrator was shown, and a write goes only into the file that was at its path when the orchestrator was asked or, where there was none, into a file it creates.
This does not keep the token from every Worker: a Worker whose own tools read files without going through the Gateway (measured with Codex, even under read_only) can read the Control token in ~/.acp-gateway/install.json, or in an agent configuration an installer before 1.8.0 wrote it into, and act as a Main. So do not give such a Worker untrusted content, such as repositories, documents or web pages that could carry a prompt injection; for that work, prefer a provider whose file reads the Gateway mediates or sandboxes. The permission_policy_partial alert lists what the Gateway cannot enforce for a session. Stronger isolation is planned for a later release.
Updating
How you update depends on how the Gateway was installed.
npm install — install the new release, then refresh the registrations and restart the daemon:
npm install -g acp-gateway-daemon@latest
acp-gateway-bootstrap --update
For an npm install, --update runs neither Git nor npm itself: it refreshes the ACP registry, the adapters and the MCP registrations, and restarts the daemon on the version npm installed. When a newer release is on npm, the Gateway's health check alert says so.
Source checkout — run just this one command:
acp-gateway-bootstrap --update
App-managed runtime — when a desktop app installed the Gateway for you (under ~/.acp-gateway/runtime/versions/), the app updates it. There, acp-gateway-bootstrap --update leaves the Gateway files alone and only refreshes the registrations.
After updating, reconnect your host (Claude/Codex/Grok/Auggie) session so that the new tools and arguments become visible. For details on how this works, updating the skill, and the reconnection procedure, see the Operations guide.
How it works
flowchart LR
U["User"] <--> M["Orchestrator AI<br/>(Main Agent)"]
M <-->|"Control MCP"| G["ACP Gateway daemon"]
G <-->|"ACP"| C["Claude Worker"]
G <-->|"ACP"| X["Grok Worker"]
G <-->|"ACP"| O["Codex Worker"]
G <-->|"ACP"| A["Other discovered AI Workers"]
G --- S[("Session · Task · Inbox state")]
The orchestrator directs work through MCP, and the Gateway talks to each Worker over ACP. The Gateway daemon manages the Unix socket, ACP connections, sessions, events, permission requests, and the minimal recovery state, so it can keep controlling in-progress Workers even when the orchestrator or the MCP connection restarts.
Work pipeline
- Discovery and installation — The installer finds the local AIs and prepares the matching agents and adapters from the official ACP registry.
- Task creation — The orchestrator opens a session through the Control MCP, specifying the provider, model, working path, and permission policy.
- Worker execution — The Gateway starts that provider's process, or reuses an existing process and session.
- Task handover over ACP — Prompts, file operations, tool events, and intermediate results flow through ACP.
- Permission and question handling — A Worker's permission requests and questions travel through the Gateway Inbox to the orchestrator, and the orchestrator's response goes back to the Worker.
- Result retrieval and reuse — The orchestrator receives status and results by waiting in
agent_acp_wait, or through an MCP Task or poll, and can call the same session again or recover it if needed.
Reliability
The Gateway also tells the orchestrator where delegated work stands, so it does not have to guess after a restart or a long silence.
- Why a session is in its status — Each status change records a reason and a time. A running Worker that has sent nothing for a while (5 minutes by default) is flagged as a possible stall; this is only a hint, and nothing is cancelled.
- What an interruption left unknown — A task cut short by a restart or a lost Worker says whether the Worker may already have acted on the prompt, and what to do next.
agent_acp_session {action: "check"}reports, read-only and without starting anything, whether a session can come back. - Attention inbox —
agent_acp_inbox {action: "attention"}lists the requests waiting on the orchestrator and the finished results it has not received yet;ackmarks them as seen. - Waiting without polling — The orchestrator waits in
agent_acp_wait, which returns as soon as a task it started finishes (with the result) or a Worker asks it something, and otherwise after a heartbeat sized to what its host allows one tool call. Apps such as AgenLynk show an orchestrator that waits this way as waiting on its tasks (main_listand themain_statusevent), not idle. - Declared task links — A run can name the task it follows up (
parentTaskId) and the tasks whose results it used (inputTaskIds). Withscope: "mine", session and task lists show only the calling orchestrator's own work. - Each orchestrator's work stays its own — When several orchestrators share the Gateway (two Claude Code conversations, or two Codex threads), each one sees and acts on only the sessions it opened, with their tasks, requests and results, plus sessions opened by tools that do not name an orchestrator. Apps and admin tools that do not name one, such as AgenLynk, keep the whole view. An orchestrator that comes back as a new conversation takes its earlier sessions back with an explicit
agent_acp_session_restore(provider, acpSessionId, cwd) once the old one is no longer connected. This keeps cooperating agents apart; it is not a security boundary against a process that holds the Control token. See Per-Main isolation. - Quarantine after repeated restore failures — After 3 failed restores in a row (by default), the Gateway stops restoring the session on its own and returns
SESSION_QUARANTINEDwith the remaining options; a successful explicit restore lifts it.
What are ACP and MCP?
ACP (Agent Client Protocol) is a protocol that standardizes communication between code editors or IDEs and AI coding agents. Instead of each editor integrating agents such as Claude, Codex, and Grok separately, they exchange session creation, prompt delivery, tool calls, permission requests, progress events, and results through the common ACP specification.
Under the ACP specification, a local agent is normally run as JSON-RPC over stdio, and a remote agent can use an HTTP or WebSocket connection. The current ACP Gateway implementation covers ACP agents on a single local machine, over a Unix socket. Connecting to remote agents is not supported yet.
- ACP is the specification for running an agent itself, talking to it, and managing its work state.
- MCP (Model Context Protocol) is a common interface for AI to connect to external tools, data, and applications.
- ACP Gateway manages Workers over ACP internally and offers that control to the orchestrator as MCP tools.
In other words, it is not a choice between MCP and ACP. MCP is the entrance through which the orchestrator operates the Gateway, and ACP is the channel through which the Gateway actually works with the other AI agents.
The latest specification is currently MCP 2026-07-28. ACP Gateway does not claim to implement this entire specification; it supports the MCP Tasks extension flow, in which a long-running job is started as a task handle and its status and result are queried again later. The current local stdio MCP server does not apply the stateless HTTP core or OAuth/OIDC authentication. For the full set of changes in MCP 2026-07-28, see the official MCP specification and Anthropic's introduction.
How is this different from using an agent CLI directly or a plain MCP call?
Here, using an agent CLI directly does not mean a person switching between terminals; it means the orchestrator you are talking to runs another AI CLI process, such as claude or grok, through a shell tool and receives the stdout result. A plain MCP call is the common wrapper approach that packages that CLI execution as a single MCP tool.
O means it is supported in the ordinary default usage flow, and X means you would have to build a separate daemon, session store, or bidirectional protocol yourself. It does not describe a theoretical limit of the CLI or of the MCP protocol itself.
What installation changes on your machine
Here is what installing the package and running acp-gateway-bootstrap --install-all actually change. With --dry-run, the bootstrap only prints its plan and makes no actual changes.
-
The Gateway package (npm install) —
npm install -ginstalls the package under npm's global prefix: its files in$(npm root -g)/acp-gateway-daemonand theacp-gateway-*commands in$(npm prefix -g)/bin. The MCP servers registered below run from there. A source install links your checkout into the same places withnpm linkinstead. -
ACP agent/adapter installation — It finds AIs installed on the PATH, in common CLI locations, and among global npm packages, matches them against the official ACP registry, and installs or updates, globally, the
npxanduvxpackages the registry names (npm install --globaloruv tool install --force). AIs that are not in the registry are not registered automatically. -
MCP registration — It registers two MCP servers with each CLI's
mcp addcommand (mcp add-jsonfor Auggie). The orchestrator-only Control MCPagent-acpis registered with just the one CLI you chose as the front door (--front-door; Codex in non-interactive installs), and the read-only Guide MCPagent-acp-guideis registered with every discovered supported CLI (Codex, Claude, Grok, Auggie). The Control MCP is registered without the Control token or the Main ID: the server reads them frominstall.jsonwhen it starts (ACP_GATEWAY_CONTROL_TOKENandACP_GATEWAY_ROOT_IDset in the entry's environment still take precedence), so neither the agent CLI's configuration nor the command line that registers the entry holds the token. Only wheninstall.jsonis not at its default path does the entry carryACP_GATEWAY_INSTALL_STATE, its location. The Control MCP has full control over the Gateway, so install it only on local agents you trust. If an entry with the same name that the installer did not create already exists, it is not overwritten without--force; the installer stops with an error instead. -
Token migration from earlier installs — Before 1.8.0 the installer put the token and the Main ID in the Control MCP entry's environment. An entry the installer can prove it registered (see the ownership checks in the Operations guide) is re-registered without them; one that launched an older Gateway is repointed at this install at the same time. Any other entry that still holds the token (one registered before 1.7.2, one whose environment changed since, or one that launches another Gateway install) is left as it is with a warning, and its configuration file is made readable only by you when it is not (the Grok CLI writes its own 0644);
--forcere-registers it without the token. Backups the agent CLIs made of their configuration (*.bak) may still hold the old token, so after a migration the installer recommends retiring it: stop the Gateway when it is idle (acp-gateway-admin shutdown_if_idle), runacp-gateway-bootstrap --rotate-token, and reconnect your host sessions and apps that keep the identity, such as AgenLynk, since each reads it once, when it starts. It never rotates the token on its own.--rotate-tokenreplaces the identity ininstall.jsononly: entries without the token read the new one when they next start. A rotation that cannot update one of its entries is not committed, andinstall.jsonkeeps the previous identity; every entry the installer rewrote is recorded ininstall.jsonas soon as it is rewritten. -
agent-delegatorskill installation — It copies the skill bundled with the Gateway into each discovered AI's skills directory.When several providers share a path, the skill files are copied only once. The skill is installed only by the first
--install-all, and--updatedoes not touch it. If a skill with the same name that the installer does not manage already exists, it is not overwritten without--force; the installer stops with an error instead. -
State files in
~/.acp-gateway/— It creates these files:install.json(permission0600): the Control token and the Main ID (the only copy the installer keeps, which the Control MCP reads when it starts), records of the MCP servers and skills the installer registered, and the ACP agent auto-update and notification settingsregistry.json: a 24-hour cache of the official ACP registryproviders.json: the execution definitions of the discovered providers
Once the daemon is running, session state (
state.snapshot.json,state.wal.ndjson) and anartifactsdirectory also appear in the same directory. -
Starting the daemon — After installation, a health check starts the Gateway daemon and verifies authentication, and replaces a running daemon if its version differs. You can skip this step with
--skip-health-check.
The Gateway itself changes only when you update it: an npm install with npm install -g, a source checkout with acp-gateway-bootstrap --update, and an app-managed runtime through its app. The installer has no uninstall command, so to undo the changes you have to remove the items above yourself; npm uninstall -g acp-gateway-daemon removes the npm package.
Documentation
- Management API contract — engine settings, provider policy, safe shutdown, waiting on tasks and Main status (
wait,main_list), and the public client contract (acp-gateway-daemon/client;acp-gateway/clientin a runtime an app mounts) - Live use cases (Korean) — a record of use cases run with real Claude, Codex, and Grok Workers
- Operations guide — installer options, updating, host reconnection, Worker parameter control, and session and data management
- Changelog — changes by version
License
Apache License 2.0 — see LICENSE.
Dev by 윤치영