mcp-agent-relay
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-agent-relaydispatch a code review to codex"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-agent-relay
Durable MCP dispatch for explicit CLI executors.
mcp-agent-relay lets one MCP client hand a job to a locally installed CLI agent and retrieve a durable result. It keeps the queue, state, leases, cancellation, and review policy in one MCP-native relay while delegating each turn to a small, allowlisted executor adapter.
It is designed for a practical local workflow: Codex can request an independent read-only review from Codex, Claude Opus, or Claude Fable without turning the relay into a remote shell.
Status: research preview / single-machine relay. The durable queue and executor adapters are production-shaped; wake-up integration with Claude Code depends on Claude Code preview capabilities.
Why use it?
The hard part of agent-to-agent work is not starting a command. It is retaining a correct answer when processes restart, jobs collide, a worker loses its lease, or a caller gives up waiting.
The relay provides:
Durable dispatch. File-backed jobs survive server and worker restarts. A
request_idmakes dispatch idempotent.Explicit routing. The
tofield selects one allowlisted worker id; it cannot select a binary, arguments, Claude agent, or environment.Safe execution defaults. Jobs are read-only by default. Codex writes require an explicit worker opt-in; Claude writes are rejected in this release.
Correct worker coordination. Workers claim jobs using leases, fencing tokens, heartbeats, cancellation, timeout handling, and recovery states.
MCP-first integration. Any MCP client can
dispatch,poll,dispatch_wait, or inspect the compact terminalaudit. A running Claude Code session can also be notified when a job changes state.Auditable executor profiles. Requested model policy, effective-model evidence, CLI version, timestamps, and exit status are recorded without accepting model selection from the payload.
Related MCP server: peer-relay
At a glance
Need | Use |
Quick read-only review with Codex |
|
Deep Claude review with the local |
|
Independent Claude review with the local |
|
Wait for one result in the tool call |
|
Submit now and inspect later |
|
Inspect executor/model evidence after result retention |
|
Make a Codex change in an isolated worktree |
|
Architecture
MCP client durable relay worker
────────── ───────────── ──────
dispatch(to, task, request_id) ──▶ queue + request-id dedup
claim + lease + fencing ───────────▶ adapter.runTurn()
poll(job_id) ◀─── result + execution evidence ◀────── Codex or Claude CLI
audit(job_id) ◀─── compact terminal ledgerLayer | Responsibility |
| Durable queue, locking, deduplication, leases, fencing, expiry, cancellation, recovery, review state, and compact audit ledger |
| MCP stdio facade, inbox resources, synchronous wait, and optional Claude channel |
| Claim loop, heartbeat, timeout, cancellation, worktree orchestration, and durable completion |
| Central allowlist from worker id to an adapter and its fixed configuration |
| One isolated CLI turn with output collection and process-group shutdown |
The executor boundary is deliberately narrow: the relay is executor-agnostic, not command-agnostic.
Available executors
Worker id / | Adapter | Fixed model policy | Policy kind | Write policy |
| Codex CLI |
| Pinned profile | Denied unless that worker has |
| Claude Code |
| Latest Opus alias | Always rejected |
| Claude Code |
| Pinned model id | Always rejected |
For the Claude routes, the local Claude Code installation must already be authenticated and must have the corresponding agent definitions:
~/.claude/agents/deep-reasoner
~/.claude/agents/fable-reasonerClaude runs in non-interactive stream-json mode. The initial structured event is the evidence source for the effective model, and the terminal structured event carries the final response and session id. The -- delimiter ensures a prompt cannot be parsed as a Claude CLI option.
claude-opus deliberately means the CLI's opus latest-model alias; it is not a claim that a specific numbered Opus release ran. claude-fable is currently pinned to the full claude-fable-5 model id. Payload fields such as command, args, agent, model, and environment settings cannot alter either profile.
Quick start: connect Codex
1. Clone the relay and verify Node
git clone https://github.com/brenoperucchi/mcp-agent-relay.git
cd mcp-agent-relay
node --version # Node 18.18 or newerNo package installation or build step is required.
2. Register the MCP server
Register a global Codex MCP server, or put the equivalent configuration in a trusted project if it should be project-scoped:
codex mcp add agentrelay \
--env RELAY_WORKER_AUTOSPAWN=1 \
--env RELAY_WORKER_AGENTS=codex,claude-opus,claude-fable \
-- node /absolute/path/to/mcp-agent-relay/server.mjsIf a CLI is installed outside the inherited environment, provide a minimal explicit PATH for the relay process:
codex mcp add agentrelay \
--env PATH=/home/you/.local/bin:/usr/local/bin:/usr/bin:/bin \
--env RELAY_WORKER_AUTOSPAWN=1 \
--env RELAY_WORKER_AGENTS=codex,claude-opus,claude-fable \
-- node /absolute/path/to/mcp-agent-relay/server.mjsConfirm the registration:
codex mcp listWhen the server receives a job, autospawn starts one short-lived worker per configured executor id as needed. You can instead run workers yourself; see Running workers.
3. Dispatch a read-only review
In a Codex session, call dispatch_wait with an explicit executor id:
{
"to": "claude-opus",
"task": {
"prompt": "Review the current diff for correctness, regressions, and missing tests. Report only actionable findings."
},
"request_id": "review-current-diff-opus-1",
"timeout_ms": 120000
}For the Fable-backed Claude agent:
{
"to": "claude-fable",
"task": {
"prompt": "Independently review the current diff. Focus on security and reliability risks."
},
"request_id": "review-current-diff-fable-1",
"timeout_ms": 120000
}If claude is missing, not on PATH, unauthenticated, or its named local agent is unavailable, the job reaches a clear failed state with the CLI error. The relay never installs Claude, changes global settings, or creates credentials.
MCP tools and job lifecycle
Submit now, retrieve later
dispatch creates (or deduplicates) a durable job and returns immediately:
// dispatch
{
"to": "codex",
"task": { "prompt": "Review the current diff for correctness." },
"request_id": "review-current-diff-codex-1"
}
// response
{ "job_id": "relay-…", "deduped": false, "state": "queued" }Call poll until it reaches a terminal state:
// poll
{ "job_id": "relay-…" }
// response
{
"found": true,
"state": "completed",
"result": { "output": "…" },
"attempts": 1,
"execution": {
"executorId": "claude-opus",
"requestedModelPolicy": "opus",
"modelPolicyKind": "latest_alias",
"effectiveModel": "claude-opus-…",
"modelEvidence": "claude-stream-json:init",
"cliVersion": "…",
"exitCode": 0
}
}The same request_id returns the same job rather than scheduling the work twice.
Submit and wait
dispatch_wait follows the same idempotent path but waits for a terminal result, up to timeout_ms:
{
"to": "codex",
"task": { "prompt": "Review the current diff for correctness." },
"request_id": "review-current-diff-codex-2",
"timeout_ms": 120000
}If the caller timeout expires first, the result says timed_out: true and reports the current queued or running state. The job continues server-side; retrieve it later with poll.
Audit executor and model evidence
poll and dispatch_wait expose execution while the job is retained. The audit tool keeps a compact terminal history independently of normal job/result retention:
// audit
{ "job_id": "relay-…" }
// response
{
"found": true,
"job_id": "relay-…",
"records": [
{
"state": "completed",
"to": "claude-opus",
"execution": {
"requestedModelPolicy": "opus",
"modelPolicyKind": "latest_alias",
"effectiveModel": "claude-opus-…",
"modelEvidence": "claude-stream-json:init"
},
"resultSha256": "…"
}
]
}The audit ledger stores no prompt, raw result, raw error, working-directory path, or request id. It stores hashes for correlation plus allowlisted execution metadata. It is bounded to the latest 5,000 terminal records per workspace. Existing version-1 stores migrate automatically with an empty audit history.
requestedModelPolicy says what the registry requested. effectiveModel is populated only when the CLI provides structured evidence; otherwise it remains null. In particular, passing -m gpt-5.6-sol proves the Codex policy requested by the relay, not a private backend rollout identifier.
Job states
State | Meaning |
| Waiting for a worker |
| Claimed by one worker with an active lease |
| Durable final result available |
| The adapter or policy rejected the job |
| Cancellation was accepted |
| A write-capable run lost its lease; it is never silently re-executed |
| A human decision is required before or after execution |
Security model
The relay assumes task prompts are untrusted data. It does not treat them as a shell request.
The central registry owns the executable, fixed CLI arguments, Claude agent/model policy, and the Codex
gpt-5.6-sol/highprofile.A Codex task may omit
modelandeffort; if it supplies either, it must exactly match that fixed profile. A downgrade or arbitrary model selection fails before the CLI starts.Claude tasks may omit
model; any conflicting payload model is rejected before the CLI starts. Agent, binary, arguments, and environment always come from the registry.A job can choose only an exact, known
toid. Unknown ids fail safely.Claude adapters inherit a reduced environment and do not take payload environment values.
All Claude jobs are read-only in this version.
write: truefor either Claude worker is an explicit failure before a CLI process starts.Codex writes are deny-by-default and require both a
write: truejob and a worker launched with--allow-writes.Write jobs with an expired lease go to
needs_recoveryinstead of being replayed.Worktree execution is available for eligible Codex writes, so the main worktree stays untouched.
Wake-up notifications contain only a minimal job envelope, never untrusted prompt text or model output.
This protects the relay’s command-selection boundary. It does not make a prompt harmless to the model receiving it; write careful task prompts and inspect all results.
Running workers
Autospawn is convenient for local MCP use, but explicit workers work the same queue and are useful for long-lived or supervised setups.
# Claim at most one queued job, execute it, then exit.
node worker.mjs --agent codex --once
# Keep a read-only Claude worker running.
node worker.mjs --agent claude-opus --interval 1000
node worker.mjs --agent claude-fable --interval 1000
# Permit Codex write jobs (still requires task.write: true).
node worker.mjs --agent codex --allow-writes --interval 1000
# Stop after five minutes with no jobs processed.
node worker.mjs --agent codex --idle-timeout 300000
# Fail a read-only turn that still runs after ten minutes. A timed-out write
# job is preserved in needs_recovery instead of being replayed.
node worker.mjs --agent claude-opus --timeout 600000Worker selection is always based on --agent and the registry. It is never taken from a job payload.
dispatch_wait.timeout_ms limits only the MCP caller's wait. The worker has a separate
per-turn budget (--timeout or RELAY_WORKER_TIMEOUT_MS, default 600000 ms); a read-only
turn that exhausts it fails terminally rather than being re-run, while a write turn enters
needs_recovery.
Store location
By default, state is stored beneath:
~/.mcp-agent-relay/stateSet RELAY_DATA_DIR to choose another durable local location. Every process that participates in the same relay—the MCP server, workers, and optional hooks—must use the same store location.
The version-2 store embeds a bounded audit ledger alongside the active/retained job collection so terminal transition and audit evidence are committed by the same atomic store write.
Codex writes in isolated worktrees
Codex is the only executor that can write in this first release. To opt in, start the Codex worker with --allow-writes and request an isolated worktree:
{
"to": "codex",
"task": {
"prompt": "Implement TASK-192 and add focused tests.",
"write": true,
"worktree": true
},
"request_id": "implement-task-192-1"
}The relay creates a branch and git worktree based on the caller’s current HEAD. The result includes worktree.path, worktree.branch, and worktree.baseSha for manual review and merge. Nothing merges automatically.
If a write turn makes no change, its temporary worktree and branch are removed. If it fails after making changes, the worktree is preserved and its path is included in the error for manual recovery.
A worktree starts from the last commit, not from uncommitted edits in the caller’s main worktree.
Human review gate
Jobs can require a human decision rather than running or completing autonomously.
Add a non-empty
requireReviewreason to a task to put it inneeds_reviewbefore execution.An executor can self-flag an ambiguous or sensitive task with
RELAY_NEEDS_REVIEW: <reason>in the final response; its partial result is retained for inspection.Resolve gates only from the local review CLI, never through MCP tools:
node bin/relay-review.mjs list
node bin/relay-review.mjs approve <jobId> --by "reviewer" --note "approved after inspection"
node bin/relay-review.mjs reject <jobId> --by "reviewer" --note "not safe to run"Predeclared approval returns a job to queued so it can run. Approval of a self-flagged result accepts that captured result. Rejection marks the job failed.
The CLI gate prevents a normal MCP client from approving its own job through the tools it already holds. It is not a complete process-isolation boundary: a local process with shell access can invoke the review CLI. Stronger approval authority requires a separate credential or isolation boundary.
Claude Code integration
The relay can be used from Claude Code either as a plugin or as a plain MCP server.
Plugin install
claude plugin marketplace add <your-org>/mcp-agent-relay
claude plugin install mcp-agent-relayThe plugin declares agentrelay in .mcp.json and includes relay slash commands. The supplied commands dispatch to codex:
/mcp-agent-relay:review <path> [focus]requests a read-only Codex review./mcp-agent-relay:implement <task>requests an isolated Codex worktree run; it needs a Codex worker allowed to write.
Plain Claude MCP install
claude mcp add --scope user agentrelay \
node /absolute/path/to/mcp-agent-relay/server.mjs \
-e RELAY_AGENT=claude-main \
-e RELAY_WORKER_AUTOSPAWN=1 \
-e RELAY_WORKER_AGENTS=codex,claude-opus,claude-fablePlugin and plain-server installations expose different MCP names:
Installation | Tool prefix | Channel source |
Plugin |
|
|
Plain |
|
|
Optional wake-up channel
Set a logical RELAY_AGENT identity on the Claude session and launch it with its corresponding development channel:
# Plugin installation
RELAY_AGENT=claude-main claude \
--dangerously-load-development-channels plugin:mcp-agent-relay@mcp-agent-relay
# Plain MCP installation
RELAY_AGENT=claude-main claude \
--dangerously-load-development-channels server:agentrelayThe channel sends only a small job_id and state notification. Claude then uses poll to obtain the normal structured result. When CLAUDE_CODE_SESSION_ID is available, notifications are narrowed to the specific session that dispatched the job.
Stop hook alternative
The channel is optional. A Stop hook checks the store as Claude is about to end a turn and gives it one more turn to poll a newly completed job:
# Add project settings. Use --global for ~/.claude/settings.json.
node bin/relay-install-hook.mjsThe helper is idempotent. Use --print to preview or --remove to undo it. The hook needs the same RELAY_AGENT and RELAY_DATA_DIR configuration as the MCP server. It fails open, so an internal hook error never blocks a Claude session from ending.
Requirements and limitations
Node.js 18.18 or newer. The runtime has no npm dependencies.
The
codexworker needs the Codex CLI available on itsPATH.Claude workers need an existing local, authenticated Claude Code CLI plus the allowlisted agent definitions. The relay does not provision either.
Claude jobs are read-only only. There is no Claude write mode in this release.
claude-opustracks the Claude CLIopusalias. Useexecution.effectiveModeloraudit, not the route name, when you need to know what the CLI reported for one completed run.effectiveModelmay benullwhen an executor does not provide structured evidence. The relay never turns a requested alias into a fabricated effective version.The store is a local file-backed queue coordinated by an interprocess lock. It is designed for one machine, not a multi-host queue.
The development channel is a Claude Code preview feature and may require the explicit channel flag. The queue, polling, and Stop hook remain usable without it.
Development
node --testThe suite covers the store and MCP facade, worker lifecycle, review and worktree protections, Codex compatibility, executor-registry resolution, and mocked Claude CLI success, failure, cancellation, and payload-isolation behavior.
License
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-qualityDmaintenanceA flexible MCP server enabling multiple Claude AI sessions to coordinate work across machines through shared state management.Last updated1
- Alicense-qualityCmaintenanceA message relay MCP server enabling two separate Claude Code instances to exchange direct questions and answers asynchronously without sharing context.Last updated7MIT
- Alicense-qualityAmaintenanceRelay MCP server enabling synchronous multi-turn communication between Hermes agents, allowing one agent to delegate tasks and await replies without third-party dependencies.Last updated38MIT
- Alicense-qualityBmaintenanceA transport-agnostic MCP seam for messages, context sharing, and task hand-off between humans, chat bots, and coding agents. Supports multiple backends like SQLite, Redis, Matrix, NATS, and XMPP to bridge Claude chat with Claude Code.Last updated37,958MIT
Related MCP Connectors
Durable agent-to-agent handoffs and shared scratchpad for multi-agent workflows.
Agent-native collaboration network: orchestrate a team of long-running agents from any MCP client.
Coordinate multiple AI agents over MCP: atomic claims, leases, shared ledger, handoffs, tasks.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/brenoperucchi/mcp-agent-relay'
If you have feedback or need assistance with the MCP directory API, please join our Discord server