Skip to main content
Glama

codex-claude-mcp

A local stdio MCP server that lets Codex ask Claude Code for an independent opinion or delegate a task, then follow up on the same Claude conversation. Adapted from cc-codex-mcp by NtTestAlert (MIT).

  • claude_ask: start a session in a project directory.

  • claude_followup: resume an explicit bridge-owned session.

  • Isolated CLAUDE_CONFIG_DIR (default ~/.claude-reviews). Claude login credentials are never copied.

  • Per-call subprocesses, cross-process session locks, progress, timeout/cancellation with process-tree cleanup, partial results and large-answer files.

  • No enforced read-only sandbox. Claude's permission mode is selected on session creation and preserved on follow-up. Read-only enforcement is on the roadmap.

Setup

Requires Node.js >=20.3 and a separately installed Claude Code CLI. The initial compatibility baseline is Claude Code 2.1.277. Use your existing Claude Code authentication method; the isolated configuration needs its own login.

git clone https://github.com/NtTestAlert/codex-claude-mcp.git
cd codex-claude-mcp
npm install
npm run build
node dist/index.js --doctor

Doctor resolves the executable, validates the isolated home, syncs configuration, and checks claude auth status --json in that home. It makes no model call and reports only authentication status/method, not account details. It prints the login command. node dist/index.js --auth-status checks authentication alone (exit 0 authenticated, 1 unauthenticated, 2 unknown/check failed). Doctor stays usable before login. On Windows, powershell -File scripts/login.ps1 performs that login. On POSIX:

CLAUDE_CONFIG_DIR="$HOME/.claude-reviews" claude auth login

Add to Codex's config.toml, using absolute paths (a real Node executable is recommended on Windows to avoid version-manager shim behavior):

[mcp_servers.claude]
command = "C:/path/to/node.exe"
args = ["C:/path/to/codex-claude-mcp/dist/index.js"]
startup_timeout_sec = 20
tool_timeout_sec = 3700

Restart the Codex session after registration. See AGENTS.snippet.md for optional project instructions.

Related MCP server: claude-consult-mcp

Tools

Both tools accept prompt, optional model, optional effort (low, medium, high, xhigh, max) and timeout_sec (10–3600, default 900). Model/effort support is validated by Claude itself; values are not translated from Codex reasoning levels.

claude_ask also requires cwd and accepts permission_mode: manual (the default), default (legacy alias for manual), acceptEdits, auto, plan, dontAsk, or bypassPermissions. Claude itself enforces model/account availability and organization policy for auto mode. Noninteractive calls cannot display interactive approvals: operations requiring approval may be denied. bypassPermissions explicitly opts out of Claude's permission prompts. It is not enabled automatically.

Optional allowed_tools supplies explicit Claude permission rules at session creation, for example ["Bash(git diff *)", "Bash(git status *)"]. These are preserved on follow-ups and restart. They pre-approve matching actions; they do not restrict tool visibility or enforce read-only access. No rules are granted implicitly. Do not rely on Claude's built-in read-only command checks: the live manual-mode test denied our Git diff command without an explicit allow rule. Organization denies and other Claude policy still apply.

claude_followup requires session_id from an earlier ask. It restores the session's cwd, permission mode and explicit tool rules; optional model/effort overrides persist in bridge metadata. These overrides intentionally change that session's subsequent defaults; pass another override to change them again. A missing cwd is an error, never a fallback to another project. Different sessions can run concurrently; calls on the same session are serialized.

Results contain session_id, answer, duration_sec, warnings, activity, and, when applicable, error and answer_file. Errors are also MCP tool errors. Interrupted calls retain their bridge ID, but resuming is possible only if Claude created its underlying transcript before interruption. Long answers are retained in a temporary file; callers are responsible for removing retained answer files.

Example result (illustrative):

{
  "session_id": "7c280530-f6b8-4cc7-8759-929966932dfa",
  "answer": "The change replaces addition with subtraction.",
  "duration_sec": 8.2,
  "warnings": ["MCP server documentation startup failed"],
  "activity": { "commands": 1, "mcp_tool_calls": [], "subagent_events": 0 }
}

MCP startup failures and authentication-required statuses in Claude's init events are reported in warnings even when stderr is empty. Error payloads that may contain configuration secrets are omitted from these startup warnings. Login advice is attached only to errors recognized as authentication failures.

Timeouts

timeout_sec is the bridge's call budget, including waiting for a session lock. On timeout, cancellation, shutdown, or client stdin EOF the active process tree is terminated. Cleanup can take a few additional seconds. Codex's tool_timeout_sec is a separate outer deadline: 3700 seconds accommodates the bridge's maximum 3600-second run plus cleanup. Progress notifications give visibility; they are not assumed to extend Codex's deadline.

Configuration and isolation

Variable

Meaning

CLAUDE_BRIDGE_HOME

Isolated config/state directory; default ~/.claude-reviews

CLAUDE_BRIDGE_SOURCE_HOME

Source Claude directory; otherwise inherited CLAUDE_CONFIG_DIR or ~/.claude

CLAUDE_BRIDGE_CLAUDE_PATH

Explicit Claude executable or supported npm shim/JS entrypoint

CLAUDE_BRIDGE_MCP_EXCLUDE

Comma-separated source MCP server names to omit

Before every run the bridge refreshes generated settings and MCP configuration. It inherits the source model/effort and eligible user MCP servers, excluding both bridge directions to avoid recursion. It never copies credentials, sessions, hooks or permission settings. Source configuration is read-only. Generated files from doctor and session metadata live under .codex-claude-mcp inside the isolated home. Calls use separate configuration snapshots under <isolated home>/.codex-claude-mcp/runs/, removed after the run, including when a large answer file is retained. MCP configuration is no longer written to the system-wide temporary directory. Re-reading config per call is deliberate for freshness; each subprocess gets its own snapshot to avoid concurrent overwrite.

Remote MCP OAuth connections need their own authorization in the isolated home. For a synced server named documentation, register its generated definition in the isolated profile, then log in from an interactive terminal. Claude's MCP management subcommands do not use the bridge's per-call --mcp-config file:

node dist/index.js --doctor
$env:CLAUDE_CONFIG_DIR = "$HOME\.claude-reviews"
$config = Get-Content "$env:CLAUDE_CONFIG_DIR\.codex-claude-mcp\mcp.json" -Raw | ConvertFrom-Json
$entry = $config.mcpServers.documentation | ConvertTo-Json -Depth 100 -Compress
claude mcp add-json --scope user documentation $entry
claude mcp login documentation

On POSIX (using jq to extract the definition):

export CLAUDE_CONFIG_DIR="$HOME/.claude-reviews"
entry=$(jq -c '.mcpServers.documentation' "$CLAUDE_CONFIG_DIR/.codex-claude-mcp/mcp.json")
claude mcp add-json --scope user documentation "$entry"
claude mcp login documentation

Use your configured bridge home if it differs from the default. Doctor generates the referenced file without modifying the source configuration. Skip add-json if this server is already registered in the isolated profile. For headless terminals, claude mcp login --no-browser documentation prints the authorization URL instead of launching a browser.

Claude still loads applicable project instructions/settings according to its own rules. Configuration isolation is not filesystem sandboxing. The bridge passes an explicit MCP configuration with --strict-mcp-config instead of automatically loading project MCP servers. Parent environment credentials remain available to Claude; an API key can select API billing rather than subscription authentication.

Development

npm test

Tests use temporary directories and fake Claude processes, not paid model calls. The explicit npm run test:live command makes two real Claude calls using the isolated login: a review of a disposable Git diff and a follow-up after fixing it. It uses manual mode with the explicit Bash(git diff *) allowance and no permission bypass. Add --without-allow-rules to reproduce the baseline permission check. Use npm run test:live -- --permission-mode=plan to check plan mode separately. The default live-test model is sonnet; CLAUDE_BRIDGE_LIVE_MODEL overrides it. Live transcripts stay in the isolated profile; the disposable project is removed. Windows is the primary target. POSIX process-group cleanup is implemented but requires validation on macOS/Linux. As in the original bridge, a parent crash before cleanup can leave a grandchild behind on Windows (no Job Object).

Roadmap: enforced read-only profile, broader platform validation, configuration watching (currently refreshed per call), and optional asynchronous job tools.

Verification record

Checked against installed Claude Code 2.1.277: print mode, stream-json output, explicit session IDs and resume, model/effort flags, manual/auto permission modes, allowedTools, strict MCP config, and auth status --json. Automated tests exercise the real MCP transport against fake Claude subprocesses, including restart, EOF cancellation, permission-rule persistence, startup diagnostics and auth checks.

Live checks on Windows, 2026-10-21, Claude Code 2.1.277, sonnet, low effort:

Check

Result

Isolated-profile auth status --json

Authenticated after separate login

Manual review without allow rules

Git diff denied; surfaced as Permission denied: Bash

Manual review with Bash(git diff *)

Git diff ran and regression identified; same-session follow-up confirmed fix (15.1s / 14.1s)

Plan review with Bash(git diff *)

Git diff ran and regression identified; same-session follow-up confirmed fix (14.8s / 13.4s)

These tests used a disposable staged Git fixture, no permission bypass, and an empty source MCP config to keep the check focused on local Git access. They do not certify every synced MCP server or a production repository's policies. Automated suite: 52 passed, 1 platform-specific skip.

Available Tools

2 tools
claude_askAsk ClaudeA
Destructive

Start an independent Claude Code session in a project. Claude can inspect the project and perform the requested task. Returns session_id for follow-ups. There is no enforced read-only sandbox.

ParametersJSON Schema
NameRequiredDescriptionDefault
cwdYes
modelNoClaude model alias or full model ID.
effortNo
promptYesTask or follow-up for Claude. Sent on stdin.
timeout_secNo
allowed_toolsNoExplicit Claude tool permission rules to pre-approve, preserved on follow-up. Example: ["Bash(git diff *)", "Bash(git status *)"]. These grant permissions, not a sandbox or tool visibility restriction.
permission_modeNoClaude permission mode, fixed for this session. default is a legacy alias for manual; auto uses Claude policy. bypassPermissions explicitly skips Claude permission prompts.manual

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true, openWorldHint=true, and readOnlyHint=false, and the description adds meaningful context: 'There is no enforced read-only sandbox,' which reinforces the permission risk. It stops short of explaining what could be destroyed or the implications of permission_mode/bypassPermissions, which would be valuable for a destructive tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, no filler, and the core capability plus the return-value hint are front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter, non-idempotent, destructive, open-world tool with no output schema, the description omits key behavioral context such as permission-mode risk, timeout behavior, and tool-preservation on follow-ups. Adequate but with clear gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 57%, and the description adds no parameter-level detail beyond what the schema provides. It mentions session_id as a return value but doesn't illuminate the model, effort, timeout_sec, or permission_mode semantics that remain only lightly documented in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action (start an independent Claude Code session in a project), names what it enables (Claude can inspect the project and perform the task), and the output (session_id). The mention of session_id for follow-ups implicitly distinguishes it from the claude_followup sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The 'session_id for follow-ups' note implies when to use claude_followup next, but the description never explicitly states when-not to use this tool or the condition that selects the sibling. Usage is left to inference rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

claude_followupFollow up with ClaudeA
Destructive

Continue a session returned by claude_ask, preserving its original directory and permission mode. Concurrent follow-ups on one session are serialized across bridge processes.

ParametersJSON Schema
NameRequiredDescriptionDefault
modelNoClaude model alias or full model ID.
effortNo
promptYesTask or follow-up for Claude. Sent on stdin.
session_idYes
timeout_secNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already declare destructiveHint=true, openWorldHint=true, and idempotentHint=false. The description adds meaningful non-obvious behavior: it preserves the original directory and permission mode and serializes concurrent follow-ups across bridge processes. It does not elaborate on specific side effects, but the annotations carry that safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, both front-loaded with useful information. The core continuation behavior and concurrency constraint are communicated without waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an open-world, destructive, five-parameter session-continuation tool with no output schema, the description covers the main continuation behavior and concurrency semantics. However, it omits return semantics and does not explain model, effort, or timeout behavior, leaving meaningful gaps for an agent invoking it.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 40% across five parameters. The description indirectly indicates that session_id should come from claude_ask and explains session preservation, but it adds no meaning for model, effort, timeout_sec, or the prompt parameter. At this coverage level the description should compensate more, and it does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Continue a session returned by claude_ask.' It explicitly ties the tool to its sibling and distinguishes follow-up behavior from starting a new ask. An agent can identify the tool's role without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives a clear usage condition: continue a session returned by claude_ask. It does not provide explicit when-not guidance or discuss other alternatives beyond the implied claude_ask relationship, but the context is sufficient for correct selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.1.0
    • First observedclaude_ask
    • First observedclaude_followup

TDQS

A4/5.0

Scored across 2 tools

Disambiguation5/5

The two tools are cleanly separated by lifecycle stage: claude_ask starts a new session and claude_followup continues an existing one. There is no plausible confusion about which to call for a given intent.

Naming Consistency5/5

Both names share the identical 'claude_' prefix in snake_case and use parallel action suffixes (ask/followup). The convention is applied uniformly across the entire surface.

Tool Count3/5

Two tools is thin even for a narrow delegation server; only the start/continue pair exists. A focused purpose partly justifies it, but it sits at the borderline of minimalism.

Completeness3/5

The core start-and-continue workflow is covered, but there is no way to list, inspect, or terminate sessions, and no status/result-retrieval operation. These are notable lifecycle gaps for session management.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers