Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@sghanavati/relay-mcp) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
relay-mcp
MCP server that lets Claude Code delegate work to Codex, OpenRouter, and LM Studio through one MCP tool.
Prerequisites: For
provider: "codex", install Codex CLI >= 0.39.0 (npm install -g @openai/codex) and authenticate (codex login). Forprovider: "openrouter"setOPENROUTER_API_KEY. Forprovider: "lmstudio"run LM Studio and setLMSTUDIO_ENDPOINTif needed.
Related Docs
Quick Start
Add this to your Claude Code .mcp.json, then restart Claude Code:
{
"mcpServers": {
"relay-mcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@sghanavati/relay-mcp"]
}
}
}Installation
@sghanavati/relay-mcp is a zero-install MCP server when launched with npx.
- No global install of
relay-mcpis required. npx -y @sghanavati/relay-mcpdownloads and runs the published package directly.- You need provider-specific runtime setup (Codex CLI for
codex, API key foropenrouter, local endpoint forlmstudio).
Claude Code Registration
npx (recommended)
Use this in your .mcp.json:
{
"mcpServers": {
"relay-mcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@sghanavati/relay-mcp"]
}
}
}local dev variant (from repository root)
Use this when iterating on local source before publishing:
{
"mcpServers": {
"relay-mcp": {
"type": "stdio",
"command": "node",
"args": ["dist/index.js"]
}
}
}Timeout strategy (DOCS-03)
relay-mcp accepts timeout_ms per delegate call. Use this strategy:
- Keep server registration static in
.mcp.json. - Set timeouts per task based on expected scope.
- Start with
300000(5 minutes) for medium tasks. - Default timeout is
600000(10 minutes) when omitted.
Example delegate call with explicit timeout:
delegate({
task: "Refactor auth middleware and update tests",
workdir: "/path/to/repo",
timeout_ms: 300000
});Claude Desktop Registration
On macOS, edit:
~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"relay-mcp": {
"command": "npx",
"args": ["-y", "@sghanavati/relay-mcp"],
"env": {
"RELAY_CODEX_PATH": "/usr/local/bin/codex"
}
}
}
}Find your Codex binary path with:
which codexClaude Desktop does not inherit your shell PATH reliably, so RELAY_CODEX_PATH should be set explicitly.
Usage
In Claude Code, ask for a delegated action, for example:
Use the delegate tool to add a README to /path/to/my-projectClaude Code will issue a tool call like:
delegate({
task: "Add a README.md with setup instructions",
workdir: "/path/to/my-project"
});Delegate Tool Parameters
task(required, string): The instruction passed to the delegated worker.workdir(required, string): Absolute or relative working directory for the delegated run.context(optional, string): Additional context to prepend to the worker prompt.provider(optional, string): Provider to use (codex,openrouter, orlmstudio). Defaults tocodex.model(optional forcodex, required foropenrouter/lmstudio): Model identifier for the selected provider. Known Codex models:gpt-5.3-codex(default, xhigh reasoning),gpt-5.4(latest, xhigh reasoning). When omitted forcodex, the model from~/.codex/config.tomlis used.timeout_ms(optional, number): Per-call timeout in milliseconds. Defaults to600000.images(optional, array of strings): Image URLs included in the request. Only applies toopenrouterandlmstudiowith vision-capable models. Ignored forcodex.Example:
delegate({ provider: "openrouter", model: "google/gemini-2.5-pro", task: "Critique this UI screenshot against the rubric", workdir: "/path/to/repo", images: ["https://example.com/screenshot.png"] });
mcps(optional, array of strings): MCP server URLs to attach to the Codex worker. Each entry must be anhttp://orhttps://URL. Only applies whenprovider: "codex". Arbitrary endpoints are user-controlled — connect only to servers you trust.Example: '{ "mcps": ["https://mcp.figma.com/mcp"] }'
Typical response payload:
{
"status": "success",
"output": "...",
"files_changed": ["README.md"],
"meta": {
"duration_ms": 45000,
"truncated": false,
"warnings": [],
"model": null,
"token_estimate": 1200,
"exit_code": 0,
"provider": "codex",
"log_file": "~/.relay-mcp/run-<hash>.log"
}
}delegate_parallel
Fan out multiple tasks in parallel with a single MCP call. Returns results in request order with per-task status, output, and metadata.
Parameters:
| Field | Type | Default | Description |
|---|---|---|---|
tasks |
array | required | Array of task objects (see below) |
continue_on_error |
boolean | true |
Keep dispatching remaining tasks after a failure |
max_failures |
integer | none | Stop dispatching after N non-success results (error + timeout count) |
max_concurrency |
integer | 5 |
Max simultaneous in-flight tasks |
When continue_on_error is false or max_failures is set, relay-mcp enforces strict stop semantics by dispatching sequentially, even if max_concurrency is higher.
Per-task fields (tasks[]):
| Field | Type | Description |
|---|---|---|
task |
string | Task prompt |
workdir |
string | Absolute working directory |
provider |
string | Provider (default: codex) |
model |
string | Model override |
timeout_ms |
integer | Per-task timeout |
images |
string[] | Image URLs for multimodal requests (openrouter/lmstudio only) |
mcps |
string[] | MCP server URLs (codex only; requires Codex CLI support for --mcp-server) |
task_label |
string | Optional label echoed in result for traceability |
codex_approval_policy |
string | Codex approval policy override (codex only; ignored with warning for other providers) |
Response:
{
"status": "success",
"items": [
{
"task_id": 0,
"task_label": "build-auth",
"task_excerpt": "Implement JWT middleware...",
"run_id": "uuid",
"status": "success",
"output": "...",
"files_changed": ["src/middleware/auth.ts"],
"meta": { ... }
}
],
"summary": {
"success_count": 3,
"error_count": 0,
"timeout_count": 0,
"total_duration_ms": 4200
}
}status is "success" only if all items succeed. items are always returned in request order.
Example — parallel component builds:
{
"tasks": [
{ "task": "Build LoginForm component", "workdir": "/project", "task_label": "login-form" },
{ "task": "Build UserProfile component", "workdir": "/project", "task_label": "user-profile" },
{ "task": "Build NavBar component", "workdir": "/project", "task_label": "navbar" }
],
"max_concurrency": 3,
"continue_on_error": true
}Use Cases
1. Context-Preserving Orchestration
Keep Claude's planning session lean by delegating implementation work to Codex. Claude holds the architecture; Codex executes the sub-tasks without polluting the orchestrator's context window.
delegate({
task: "Implement the auth middleware per the spec in PLAN.md",
workdir: "/path/to/repo"
});2. Batch Code Generation
Generate multiple independent artifacts — components, migrations, API routes — each in a fresh Codex context. The orchestrator's growing session history never bleeds into the worker's input.
delegate({
task: "Generate CRUD routes for users, posts, and comments in src/routes/",
workdir: "/path/to/repo"
});3. Test Generation from Spec
After a feature is built, delegate test writing as a standalone, self-contained task.
delegate({
task: "Write Jest unit tests for src/auth/middleware.ts covering success, expired token, and missing token cases",
workdir: "/path/to/repo"
});4. Scoped Refactoring
Delegate well-defined refactors without polluting the main session with diff noise.
delegate({
task: "Migrate all fetch() calls in src/api/ to use the axios client",
workdir: "/path/to/repo"
});5. Documentation Generation
Auto-generate JSDoc, API docs, or README sections for a module after implementation.
delegate({
task: "Add JSDoc comments to all exported functions in src/utils/",
workdir: "/path/to/repo"
});6. Plan-Driven Execution (Orchestrator Pattern)
Use Claude as the planning engine and relay-mcp as the execution bridge.
Each task in a written plan maps to a delegate call; Claude reviews files_changed
before moving to the next task.
Plan phase → Claude writes task specs
Execute → delegate each task to Codex
Review → Claude reads files_changed, verifies output
Repeat → next taskWhen not to use it
- Tasks that require back-and-forth decisions mid-execution (Codex runs
--full-auto) - Work that needs full conversation context (Codex sees only what you pass in
task/context) - Very short one-liners where the delegation roundtrip (Codex startup + execution) exceeds the time to do it inline
Orchestration with tmux + dmux
dmux (npm install -g dmux) arranges a tmux layout where Claude Code
orchestrates from one pane while Codex sessions run in adjacent panes.
tmux window
├── pane 0 Claude Code — GSD orchestrator, relay-mcp registered
├── pane 1 tail -f <relay-log> live output from task 1
├── pane 2 tail -f <relay-log> live output from task 2
└── ...The loop:
- CC writes a plan (GSD), then fires
delegatecalls — one per task - relay-mcp executes each call with the selected provider and returns
files_changed+ output - Each task writes to a provider run log file (
meta.log_file); adjacent panes cantail -flogs live - CC reads
files_changedand output, verifies results, then moves to the next task - You supervise only CC while providers run unattended
Context Injection (AGENTS.md and ART_DIRECTION.md)
relay-mcp automatically injects two context files into every worker delegation when they exist in or above the workdir.
AGENTS.md— coding conventions, architecture notes, project standards. Read before every task.ART_DIRECTION.md— design quality standards, Impeccable command vocabulary, critique rubric, anti-patterns, revision spec format. Injected for all providers including OpenRouter and LM Studio.
Both files are resolved by walking up from workdir to the git root, using the nearest non-empty file found. If neither file exists, nothing extra is injected.
This means any worker (Codex, OpenRouter, LM Studio) that receives a delegated task will automatically receive your project's standards as part of its prompt — no extra setup required.
Configuration
| Variable | Default | Description |
|---|---|---|
RELAY_CODEX_PATH |
codex from PATH |
Full path to Codex binary for PATH-limited environments (especially Claude Desktop). |
RELAY_LOG_LEVEL |
info |
Startup log verbosity control. error suppresses the ready banner; other values show it. |
RELAY_CODEX_NETWORK_MODE |
off |
Codex network/sandbox mode for provider: "codex": off (default --full-auto), search (--full-auto + --search), dangerous (--dangerously-bypass-approvals-and-sandbox). |
RELAY_ALLOWED_ROOTS |
unset | Optional allowlist for delegate workdir. Path-delimited list (: on macOS/Linux, ; on Windows). If set, workdirs outside these roots are rejected. |
RELAY_SKIP_GIT_CHECK |
0 |
Set to 1 to add --skip-git-repo-check to Codex runs. Default keeps repo check enabled. |
OPENROUTER_API_KEY |
unset | Required for provider: "openrouter". |
LMSTUDIO_ENDPOINT |
http://localhost:1234 |
Base URL for LM Studio OpenAI-compatible server. |
LMSTUDIO_API_KEY |
unset | Optional bearer token for LM Studio endpoint. |
RELAY_EVENTS_LOG_PATH— Override the default telemetry log path (~/.relay-mcp/events.jsonl). Useful for custom log routing, tmux/dmux setups, or testing. Example:RELAY_EVENTS_LOG_PATH=/var/log/relay-events.jsonl
Codex network modes
off(default): runs Codex with--full-auto.search: runs Codex with--full-auto --search(web-search tool enabled if supported by your Codex CLI).dangerous: runs Codex with--dangerously-bypass-approvals-and-sandbox.
Use dangerous only for trusted repos and tasks; it intentionally relaxes guardrails.
If your .mcp.json needs visible mode choices, JSON comments are not supported. Use multiple named entries with different RELAY_CODEX_NETWORK_MODE values (for example relay-mcp-off, relay-mcp-search, relay-mcp-dangerous).
Provider model requirement
provider: "codex":modelis optional.provider: "openrouter"orprovider: "lmstudio":modelis required.provider: "openrouter"andprovider: "lmstudio"are generation-only and always returnfiles_changed: [].
Provider examples
delegate({
provider: "openrouter",
model: "google/gemini-2.5-pro",
task: "Review this implementation and return a concise risk list",
workdir: "/path/to/repo"
});delegate({
provider: "lmstudio",
model: "qwen2.5-coder-32b-instruct",
task: "Draft unit tests for src/auth.ts",
workdir: "/path/to/repo"
});Troubleshooting
1) PATH issues (Codex not found)
Symptom:
Error: Codex binary not found ...
Fix:
which codexThen add that path to RELAY_CODEX_PATH in your MCP server config env block.
2) Auth failures
Symptom:
Error: Codex not authenticated
Fix:
codex loginThen restart Claude Code or Claude Desktop.
3) Network/DNS failures
Symptom:
status: "error" with error.code: "CODEX_ERROR" during delegation.
Fix:
- Retry the same delegate call.
- If using
provider: "codex", checkRELAY_CODEX_NETWORK_MODE.offmay not have internet access in your Codex runtime. - Use
searchif you need Codex web-search support, ordangerousonly when you explicitly want sandbox bypass behavior. - Confirm network/DNS connectivity and any proxy requirements in the runtime environment.
- Re-run
codex loginif your session may have expired.
4) Missing model for OpenRouter or LM Studio
Symptom:
status: "error" with error.code: "INVALID_ARGS" and message that model is required.
Fix:
- Add
modelwheneverproviderisopenrouterorlmstudio. - Example:
model: "google/gemini-2.5-pro"for OpenRouter.
5) npx from this package's own repo root
Symptom:
sh: relay-mcp: command not found when running npx -y @sghanavati/relay-mcp from inside the relay-mcp source checkout.
Fix:
- For local development in this repo, run
node dist/index.jsinstead. - For published-package verification, run from any other directory (or use
npm --prefix /tmp exec --yes --package=@sghanavati/relay-mcp -- relay-mcp --version).
Security
workdirvalues are canonicalized withpath.resolve()before subprocess execution.- Optional
RELAY_ALLOWED_ROOTSenforces an explicit allowlist for delegateworkdir. - For
provider: "codex",RELAY_CODEX_NETWORK_MODEcontrols runtime behavior:off:--full-autosearch:--full-auto --searchdangerous:--dangerously-bypass-approvals-and-sandbox
--skip-git-repo-checkis disabled by default and only enabled whenRELAY_SKIP_GIT_CHECK=1.- Run/event logs are written under
~/.relay-mcp(directory mode700, file mode600best-effort). relay-mcpdoes not store credentials, API keys, or session tokens; authentication remains in Codex CLI.
Threat model: relay-mcp is designed for trusted local developer use. Guardrails (workdir allowlist, log permissions, git check gating) defend against accidental prompt-driven mistakes and path escapes — not adversarial attacks. MCP endpoints passed via mcps are fully trusted; connect only to servers you control.
License
MIT. See LICENSE.