Skip to content

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.

From source:

Terminal window
npm install
npm run build

Run the CLI from this package:

Terminal window
node dist/cli.js doctor --json

When linked locally, the command is:

Terminal window
codex-with-claude doctor --json

Start the localhost adapter:

Terminal window
codex-with-claude serve

On 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:

Terminal window
codex-with-claude install \
--codex-home /tmp/codex-home \
--base-url http://127.0.0.1:47777/v1

By 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:

Terminal window
codex-with-claude install \
--codex-home /tmp/codex-home \
--base-url http://127.0.0.1:47777/v1 \
--set-default

The 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 = false

Serve options:

Terminal window
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.

The server exposes only:

  • GET /healthz
  • POST /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_bridge MCP server
  • permissionMode: "dontAsk"
  • allowedTools limited to generated mcp__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.

Run:

Terminal window
codex-with-claude doctor --json

With a sandbox Codex home:

Terminal window
codex-with-claude doctor --codex-home /tmp/codex-home --json

With a running adapter:

Terminal window
codex-with-claude doctor \
--codex-home /tmp/codex-home \
--base-url http://127.0.0.1:47777/v1 \
--json

doctor 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.

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-sdk 0.3.202, license published by Anthropic in the package license file.
  • @anthropic-ai/sdk 0.110.0, MIT.
  • @modelcontextprotocol/sdk 1.29.0, MIT.
  • smol-toml 1.x, MIT.
  • zod 4.4.3, MIT.

Remove the provider from the same Codex home used during install:

Terminal window
codex-with-claude uninstall --codex-home /tmp/codex-home

Install always creates a backup before writing:

<CODEX_HOME>/config.toml.codex-with-claude.<timestamp>.bak

It also records install ownership in:

<CODEX_HOME>/codex-modules/with-claude-install.json

uninstall 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:

Terminal window
cp <backup-path> <CODEX_HOME>/config.toml