with-claude
codex-with-claude is a personal localhost provider adapter for Codex custom providers. It exposes a local Responses-compatible endpoint that Codex can call with wire_api = "responses" and bridges Codex function-tool turns to Claude through the Claude Agent SDK.
This module is experimental and is not published to npm. Install and verify it from this repository only.
The adapter does not execute Codex tools itself. Claude plans a tool call, the adapter emits a Codex function_call, Codex owns approval and execution, and the adapter passes the returned function_call_output back to the active Claude turn.
Install
Section titled “Install”From source:
npm installnpm run buildRun the CLI from this package:
node dist/cli.js doctor --jsonWhen linked locally, the command is:
codex-with-claude doctor --jsonStart the localhost adapter:
codex-with-claude serveOn startup it prints one JSON line to stdout:
{"baseUrl":"http://127.0.0.1:47777/v1","providerId":"with_claude"}Install the Codex provider block into an explicit Codex home:
codex-with-claude install \ --codex-home /tmp/codex-home \ --base-url http://127.0.0.1:47777/v1By default install only adds the provider block. It does not change the top-level Codex model or model_provider. To make this provider the default for that Codex home:
codex-with-claude install \ --codex-home /tmp/codex-home \ --base-url http://127.0.0.1:47777/v1 \ --set-defaultThe injected provider uses:
[model_providers.with_claude]name = "With Claude"base_url = "http://127.0.0.1:47777/v1"wire_api = "responses"requires_openai_auth = falseServe options:
codex-with-claude serve \ --host 127.0.0.1 \ --port 47777 \ --model with-claude \ --log-level info \ --idle-ttl-ms 1800000 \ --request-timeout-ms 90000 \ --tool-result-ttl-ms 600000--unsafe-log-previews is opt-in. Without it, logs record only event metadata, lengths, and hashes, not request bodies, tool outputs, or raw Claude events.
How It Works
Section titled “How It Works”The server exposes only:
GET /healthzPOST /v1/responses
It binds to 127.0.0.1 by default. Non-local bind hosts are rejected. Browser-origin requests, CORS preflight requests, non-JSON provider requests, and non-streaming provider requests are rejected.
Each Codex request starts a turn-scoped Claude query. The adapter reconstructs the prompt from Codex instructions and input, converts supported Codex function tools into conservative MCP tools, and starts the Claude Agent SDK with locked-down options:
settingSources: []tools: []- one in-process
codex_bridgeMCP server permissionMode: "dontAsk"allowedToolslimited to generatedmcp__codex_bridge__<tool>names
Only Codex function tools with supported JSON Schema are exposed. namespace and web_search tools are not exposed to Claude. Unsupported schemas fail closed and are omitted from the Claude tool catalog.
The adapter keeps an in-memory session registry keyed primarily by Codex thread-id, with fallbacks to session-id, prompt_cache_key, x-client-request-id, and input hash. It stores bounded replayable SSE transcripts so duplicate retries for the same request id do not start another Claude query. Request-run history, retired call ids, text buffering, pending calls, and transcript size all have explicit in-memory limits; an oversized transcript is discarded instead of being partially replayed.
Timeouts and Claude-side errors use the Responses failure lifecycle: response.created, response.failed with status = "failed", then [DONE]. The adapter does not turn backend failures into successful diagnostic text.
Diagnostics
Section titled “Diagnostics”Run:
codex-with-claude doctor --jsonWith a sandbox Codex home:
codex-with-claude doctor --codex-home /tmp/codex-home --jsonWith a running adapter:
codex-with-claude doctor \ --codex-home /tmp/codex-home \ --base-url http://127.0.0.1:47777/v1 \ --jsondoctor checks Node, pinned runtime dependencies, ANTHROPIC_API_KEY shadowing, optional Codex provider config, and optional /healthz. It does not inspect real ~/.codex or ~/.claude unless you explicitly pass a Codex home path or set CODEX_HOME to that path.
If ANTHROPIC_API_KEY is present, serve fails unless ALLOW_ANTHROPIC_API_KEY=1 is also set. This keeps the adapter fail-closed when an environment key would change the Claude Agent SDK authentication path.
Attribution
Section titled “Attribution”The tracked implementation is canonical and was promoted from a repository-local prototype. It has no runtime or verification dependency on ignored .work/ artifacts.
No third-party source code is included in this package.
Runtime dependencies:
@anthropic-ai/claude-agent-sdk0.3.202, license published by Anthropic in the package license file.@anthropic-ai/sdk0.110.0, MIT.@modelcontextprotocol/sdk1.29.0, MIT.smol-toml1.x, MIT.zod4.4.3, MIT.
Uninstall Rollback
Section titled “Uninstall Rollback”Remove the provider from the same Codex home used during install:
codex-with-claude uninstall --codex-home /tmp/codex-homeInstall always creates a backup before writing:
<CODEX_HOME>/config.toml.codex-with-claude.<timestamp>.bakIt also records install ownership in:
<CODEX_HOME>/codex-modules/with-claude-install.jsonuninstall removes only the sentinel-managed provider block. If --set-default was used and the current top-level values still match the installed values, it restores the previous top-level model and model_provider. If the sentinel block changed after install, uninstall refuses to edit and reports the backup path.
Manual rollback:
cp <backup-path> <CODEX_HOME>/config.toml