Standalone local HTTP proxy that exposes Anthropic-compatible POST /v1/messages
semantics to Claude Code while forwarding requests to OpenAI's Responses API or
OpenAI-compatible upstreams.
- accepts Anthropic-style
POST /v1/messages - forwards to
POST /v1/responses - supports streaming text responses
- translates OpenAI function calls into Anthropic
tool_use - preserves multi-turn tool continuation with
previous_response_id - works with OpenAI and compatible providers that implement the Responses API
- emits one structured log line per request
- Bun
>= 1.3
- Install dependencies:
bun install- Create your env file:
cp .env.example .env- Start the proxy:
set -a
source .env
set +a
bun run startYou can also pass the same values as CLI flags:
bun run start -- \
--listen-port 4141 \
--upstream-url https://api.openai.com \
--upstream-key "$OPENAI_API_KEY" \
--upstream-model gpt-4.1 \
--state-file .openai-responses-anthropic-proxy-state.jsonThe project includes lightweight lifecycle scripts for running the proxy as a background service from the project directory:
./start-proxy.sh
./proxy-status.sh
./stop-proxy.shWhat they do:
start-proxy.shstarts the proxy in the background, writes the PID to.openai-responses-anthropic-proxy.pid, and appends logs to.openai-responses-anthropic-proxy.logproxy-status.shreports whether the proxy isrunning,stale-pid, orstoppedstop-proxy.shstops the running proxy using the saved PID
If needed, you can override the PID file path with
OPENAI_RESPONSES_PROXY_PID_FILE.
Point Claude Code to the local proxy:
export ANTHROPIC_BASE_URL=http://127.0.0.1:4141
export ANTHROPIC_API_KEY=dummy
export ANTHROPIC_MODEL=my-proxy-codexdummy is only a placeholder required by Claude Code. The real upstream key is
configured on the proxy side via .env or CLI flags. ANTHROPIC_MODEL is the
name Claude Code will display locally; the proxy still forwards to the real
upstream model configured with OPENAI_RESPONSES_UPSTREAM_MODEL or
--upstream-model.
By default the proxy persists tool continuation state to
.openai-responses-anthropic-proxy-state.json, so previous_response_id
survives a restart. Override it with OPENAI_RESPONSES_STATE_FILE or
--state-file.
Each POST /v1/messages request emits one structured line to stdout:
[openai-responses-proxy] request {"ts":"2026-04-06T03:06:30.090Z","method":"POST","path":"/v1/messages","model":"claude-sonnet-test","stream":true,"status":200,"upstream_status":200,"duration_ms":1209,"error":null}
This lets you confirm that Claude Code is actually going through the proxy.
The screenshot below shows a real Claude Code session using this proxy to ask
分析这个项目的结构 and receive a normal structured answer instead of a tool
continuation error:
- 2026-04-08
- added richer Responses → Anthropic translation for reasoning summaries, refusal text, cache-token usage fields, and incomplete/max-token stop reason
- expanded streaming SSE handling for reasoning and refusal deltas
- added regression coverage for reasoning, refusal, usage normalization, reasoning effort mapping, and streaming behavior
- added
start-proxy.sh,stop-proxy.sh, andproxy-status.shfor local proxy lifecycle management
- 2026-04-07
- added verified usage screenshot to the README
- fixed tool continuation compatibility for Responses upstreams
- 2026-04-06
- initial standalone proxy release
- added request logging with local timestamps and timezone offset
OPENAI_RESPONSES_PROXY_HOSTOPENAI_RESPONSES_PROXY_PORTOPENAI_RESPONSES_PROXY_PID_FILEOPENAI_RESPONSES_UPSTREAM_URLOPENAI_RESPONSES_UPSTREAM_KEYOPENAI_RESPONSES_UPSTREAM_MODELOPENAI_RESPONSES_STATE_FILE
Build the image:
docker build -t openai-responses-anthropic-proxy .Run it:
docker run --rm \
-p 4141:4141 \
-e OPENAI_RESPONSES_PROXY_HOST=0.0.0.0 \
-e OPENAI_RESPONSES_PROXY_PORT=4141 \
-e OPENAI_RESPONSES_UPSTREAM_URL=https://api.openai.com \
-e OPENAI_RESPONSES_UPSTREAM_KEY="$OPENAI_API_KEY" \
-e OPENAI_RESPONSES_UPSTREAM_MODEL=gpt-4.1 \
openai-responses-anthropic-proxybun run build:binaryThis writes a standalone executable to:
dist/openai-responses-anthropic-proxy
bun run test
bun run typechecksrc/cli.ts
src/server.ts
src/translate.ts
src/state.ts
src/config.ts
src/types.ts
start-proxy.sh
stop-proxy.sh
proxy-status.sh
