@proofofwork-agency/contextrelay
v3.11.0
Published
ContextRelay: local multi-agent coding orchestration for Claude Code and Codex
Maintainers
Readme
ContextRelay
Run Claude Code and Codex as one local coding team.
ContextRelay is a local-only control plane that lets Claude Code and Codex work together on the same repo. It handles live messaging, a durable shared ledger, handoffs, headless reviewers, and a terminal + browser dashboard — all without sending your code anywhere.
One agent codes, another reviews, a headless worker gives a second opinion, and you keep full auditability. Everything stays on your machine.

Local. Auditable. No cloud. No extra accounts.
Quick Start
# 1. Install the agents + ContextRelay
npm install -g @anthropic-ai/claude-code @openai/codex @proofofwork-agency/contextrelay
# 2. Set up the project
ctxrelay init --instructions project
ctxrelay codex-mcp install
# 3. Launch the pair
ctxrelay pairThen inside Claude or Codex:
/contextrelay:handoff review the auth changes
/contextrelay:deliberate is this design sound?See the full install guide or run ctxrelay doctor.
What You Actually Get
| What | Why it matters |
|------|----------------|
| One shared session for two native agents | Claude Code and Codex keep their own UIs and models. ContextRelay just wires them together with one daemon, ledger, coordinator, and task board. |
| Durable shared ledger | Every message, handoff, note, artifact, test report, release gate, and headless result is append-only JSONL in .contextrelay/. Crash? Inspect and resume later. |
| Structured handoffs & deliberation | /contextrelay:handoff or handoff_to_claude passes a concrete ask + files + reason. /contextrelay:deliberate records a short debate before big decisions. |
| Headless reviewers on demand | ctxrelay headless run --target codex (or via the contained_run tool) spins up a fresh-context read-only worker. Supports codex, claude, and opencode (on macOS). |
| Idle nudges | With autonomy on, the daemon can politely ask the idle agent to pull the next task from the busy coordinator. |
| Native TUI + viewer | Full terminal dashboard for status, controls, and activity. Browser "Command Deck" for read-only inspection. |
| Git writes stay with the coordinator | Only the designated coordinator (Claude, Codex, or human) is allowed to commit, push, etc. Everyone else is read-only by default. |
| Gated writes & release evidence | act:write is off by default and runs in a contained worktree. release-gate records proof before you ship. |
| Named sessions & worktrees | Spin up side sessions bound to separate worktrees for parallel review or experiments. |
Daily Workflow
ctxrelay pair # launch Claude + Codex around this project
ctxrelay viewer # open the read-only browser command deck
ctxrelay ledger list # inspect the shared ledger
ctxrelay headless run --target codex --prompt "Review this diff for release blockers"
ctxrelay release-gate # record release evidence
ctxrelay kill # stop this project daemonInside Claude Code:
/contextrelay:handoff review the risky part of this change
/contextrelay:deliberate should this be a protocol change or display-only?
/contextrelay:finalizeFrom Codex, use the MCP tools after ctxrelay codex-mcp install: handoff_to_claude, deliberate_with_claude, contained_run, read_context, record_artifact, propose_final, and the rest of the ContextRelay tool surface.
The everyday loop is simple: one agent does the work, the other reviews or challenges it, and ContextRelay keeps the useful context written down.
Headless Reviews
Headless jobs are one-shot reviewers. They do not join the live pair; they inspect context and return one result.
ctxrelay headless run \
--target codex \
--prompt "Review the current diff for release blockers. Findings first."From MCP, call contained_run:
{
"agent": "claude",
"prompt": "Review src/backup/runner.ts and tests for regressions.",
"context_refs": ["git diff", "src/backup/runner.ts"]
}Renamed: this tool was called
headless_run. It collided with Headless, a separate product that ships an MCP tool of the same name — an agent told to "use headless" would reach for the wrong one. The old name is still accepted for one version and still works inCONTEXTRELAY_MCP_TOOLSallowlists, but it is no longer advertised. ContextRelay's feature is still called headless workers; only the tool identifier changed.
Registered contained adapters are exposed automatically. Built-ins today:
codex:codex exec --sandbox read-onlyclaude:claude -pwith read-only toolsopencode:opencode run --pureinside the Darwin read-only sandbox when the binary and sandbox probe are available
The opencode adapter is optional. If you want to use --target opencode, install and authenticate the opencode CLI first and make sure opencode is on PATH for the daemon or CLI process. ContextRelay registers the adapter automatically only on macOS/Darwin when opencode is present and the sandbox-exec write-denial probe passes. To hide just this adapter, start ContextRelay with CONTEXTRELAY_OPENCODE_ENABLED=0; to disable every headless worker, use CONTEXTRELAY_HEADLESS_ENABLED=0.
opencode gets an extra grounding preamble because it runs in minimal --pure mode. It is told exactly which read-only tools exist and not to claim edits, tests, or shell commands it cannot perform. Codex and Claude are left to their native headless runtimes.
Adapters are source-level extension points, not external runtime plugins. To add another terminal-coder target, open a PR that implements HeadlessAdapter in src/backup, registers it in the in-process adapter registry, and includes containment proof, env allowlist, output parsing, tests, and docs. After review and release, users get the adapter through the normal npm package update.
Pair Work

Claude -> /contextrelay:handoff
reason: finished the token refresh change; want a second opinion before merge
ask: review src/auth/refresh.ts for races and token leak paths
files: src/auth/refresh.ts, src/auth/refresh.test.ts
Codex -> reply
Two issues: refresh is not single-flight, and the old token remains in memory
after rotation. Tests pass, but neither path is covered.
Claude -> append_note
decision: add the single-flight lock, zero the old token, add both tests.Idle Ask-For-Work
When global autonomy is on, ContextRelay can keep the non-coordinator from silently sitting idle.
If Codex is coordinator and currently busy while Claude is idle, the daemon nudges Claude:
[IMPORTANT] ASK_FOR_WORK: You appear idle while the coordinator is actively working.
Ask Codex for the next concrete task now, and include either what you just finished or that you are ready for work.If Claude is coordinator and Codex is idle, the same mechanism injects the nudge into Codex. The feature is automatic, cooldown-limited, and records an idle_ask_for_work artifact in the ledger. It is not a public MCP tool; it is daemon behavior controlled by config.
Enable the autonomy master switch:
ctxrelay autonomy onDisable just this nudge in .contextrelay/config.json:
{
"autonomy": {
"idleScanner": {
"askForWork": {
"enabled": false
}
}
}
}Control Deck
The native TUI opens with contextrelay or ctxrelay tui [--no-start] [--force].
Safety Model
ContextRelay assumes one trusted operator on one workstation.
- The daemon binds to
127.0.0.1. - The viewer cannot dispatch agent work; it can clear current-session history through its authenticated local maintenance endpoint.
- Git writes are policy-routed through one coordinator or the human.
- Autonomy is off by default.
contained_runis read-only and only accepts registered contained adapters.act:writeis default-off and only runs in an ephemeral git worktree behind dual-idle, budget, single-flight, and containment gates.- Provider CLIs still use their own auth and approval systems.
Read docs/THREAT_MODEL.md before relying on any stronger boundary.
Common Commands
contextrelay # open the native ContextRelay TUI
ctxrelay init --instructions project
ctxrelay codex-mcp install|remove|status|server
ctxrelay pair [--dry-run] [--no-tui] [--port-base <port>] [--session <id>]
ctxrelay status [--json]
ctxrelay viewer [--no-open]
ctxrelay release-gate [--json] [--smoke]
ctxrelay headless run --target <codex|claude|opencode> (--prompt <text>|--prompt-file <path>) [--timeout <ms>] [--label <name>] [--json]
ctxrelay kill [--all|--session <id>]The full command, MCP, environment, metrics, and artifact reference lives in docs/REFERENCE.md. Day-to-day recovery lives in docs/RUNBOOK.md.
Documentation
- Docs site
- Docs index
- Operator runbook
- Reference
- Changelog — see v3.10.1 for hygiene and default fixes
- CONTEXTRELAY_V1.md
- ROADMAP.md
- RUNBOOK.md
- SESSION-LIFECYCLE.md
- THREAT_MODEL.md
The compact CLI reference is at the end of this file for sync purposes.
Develop
git clone https://github.com/proofofwork-agency/contextrelay.git
cd contextrelay
bun install
bun run build:cli
bun run build:plugin
bun link
bun link @proofofwork-agency/contextrelay
ctxrelay init --instructions project
ctxrelay codex-mcp install
ctxrelay pairRun the local gate:
bun run checkRun package evidence before publishing:
ctxrelay release-gate --jsonLicense
MIT. See LICENSE. ContextRelay preserves the original AgentBridge MIT copyright notice and adds the ProofOfWork / Danillo Felixdaal copyright notice for this fork's changes.
This section keeps the README synchronized with the public CLI and tool surface. Most readers should use docs/REFERENCE.md instead.
CLI aliases: contextrelay, context-relay, ctxrelay.
contextrelay
ctxrelay tui [--no-start] [--force]
ctxrelay init [--instructions project|global|both|skip]
ctxrelay upgrade [--dry-run] [--no-plugin] [--instructions refresh|project|global|both|skip]
ctxrelay dev
ctxrelay claude [--session <id>] [args...]
ctxrelay codex [--session <id>] [args...]
ctxrelay codex-mcp install|remove|status|server
ctxrelay pair [--dry-run] [--no-tui] [--port-base <port>] [--session <id>]
ctxrelay doctor [--no-auth]
ctxrelay instructions status|install|remove [--scope project|global|both]
ctxrelay coordinator [status|claude|codex|human] [--scope project|global|both]
ctxrelay permissions status|readonly on|off|allow <capability>|deny <capability>|reset [--agent <agentId>]
ctxrelay detach-claude
ctxrelay status [--json]
ctxrelay session list|create|select|archive|rebind [...]
ctxrelay recover [--json]
ctxrelay instances
ctxrelay viewer [--no-open]
ctxrelay autonomy on|off|status
ctxrelay idle-scanner off|suggest|ask|act|status [--why]|check
ctxrelay idle-budget status|reset
ctxrelay idle-eval status|compare
ctxrelay act on|off|status [--budget <usd>]
ctxrelay finalize auto|manual|status
ctxrelay usage status|off|lean|strict
ctxrelay usage hook status|verbose|compact|count|set
ctxrelay usage context off|lean|strict|status
ctxrelay usage ledger compact [--dry-run|--apply] [--session <id>] [--recent <count>] [--preview-chars <count>]
ctxrelay usage ledger clear [--dry-run|--apply] [--session <id>]
ctxrelay hook-compaction status|verbose|compact|count|set
ctxrelay usage-control off|lean|strict|status
ctxrelay ledger list|show|compact|clear [...]
ctxrelay queue list|show|remove|drain [...]
ctxrelay messages status|drain [...]
ctxrelay release-gate [--json] [--smoke]
ctxrelay headless run --target <codex|claude|opencode> (--prompt <text>|--prompt-file <path>) [--timeout <ms>] [--label <name>] [--json]
ctxrelay kill [--all|--session <id>]
ctxrelay standalone on|off|status [--scope project|global|both] [--path <file>]
ctxrelay attach [session-name]
ctxrelay detach
ctxrelay gate-check [--status|--json|--why]Claude MCP tools:
reply
get_messages
wait_for_messages
handoff
deliberate_with_codex
append_note
read_context
session_info
create_session
select_session
archive_session
rebind_session
task_state
record_artifact
ask_codex_backup
backup_status
contained_run
propose_finalCodex MCP tools:
send_to_claude
handoff_to_claude
deliberate_with_claude
read_context
wait_for_claude
append_note
session_info
create_session
select_session
archive_session
rebind_session
task_state
record_artifact
ask_claude_backup
backup_status
contained_run
propose_finalClaude slash commands:
/contextrelay:init
/contextrelay:status
/contextrelay:handoff
/contextrelay:review
/contextrelay:deliberate
/contextrelay:finalize
/contextrelay:on
/contextrelay:offArtifact kinds: patch_summary, release_gate, test_report, command_log, escalation_suggestion, idle_opportunity, idle_ask_for_work, idle_action_result, idle_fleet_result, idle_evaluation_result, idle_write_result, headless_result.
Artifact statuses: passed, failed, blocked, unknown, skipped, timed_out.
Core env vars: CONTEXTRELAY_STATE_DIR, CONTEXTRELAY_CONTROL_PORT, CODEX_WS_PORT, CODEX_PROXY_PORT, CONTEXTRELAY_PORT_BASE, CONTEXTRELAY_PROJECT_ROOT, CONTEXTRELAY_INSTANCE_ID, CONTEXTRELAY_AUTO_CONNECT, CONTEXTRELAY_MODE, CONTEXTRELAY_MCP_TOOLS, CONTEXTRELAY_ALLOW_NAMED_SESSIONS, CONTEXTRELAY_MAX_BUFFERED_MESSAGES, CONTEXTRELAY_IDLE_SCANNER, CONTEXTRELAY_HEADLESS_ENABLED, CONTEXTRELAY_OPENCODE_ENABLED.
Claude Code host env vars read by bundled hooks: CLAUDE_PLUGIN_ROOT, CLAUDE_PROJECT_DIR.
