Use your Claude Max/Pro subscription as an OpenAI-compatible API — with full tool support.
Unlike other proxies that wrap the Claude Code CLI in --print mode (text-only), this proxy uses the official Claude Agent SDK which gives Claude access to real tools — file I/O, shell commands, web search, and more. Claude runs your tasks, not just answers your questions.
| Feature | claude-max-api-proxy |
This proxy |
|---|---|---|
| OpenAI-compatible API | ✅ | ✅ |
| Uses Claude Max subscription | ✅ | ✅ |
| Tool calling (file read/write) | ❌ | ✅ |
| Shell command execution | ❌ | ✅ |
| Web search & fetch | ❌ | ✅ |
| Official SDK | ❌ (CLI hack) | ✅ (claude-agent-sdk) |
| Streaming | ✅ | ✅ |
- Node.js 18+
- Claude Code CLI — authenticated with your Claude Max or Pro subscription:
npm install -g @anthropic-ai/claude-code claude auth login
- Claude Agent SDK:
npm install -g @anthropic-ai/claude-agent-sdk
# Clone the repo
git clone https://github.com/0x0ndra/claude-max-openai-proxy.git
cd claude-max-openai-proxy
# Start the proxy
node server.mjsThe proxy starts on http://127.0.0.1:3456 by default.
curl -X POST http://localhost:3456/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4",
"messages": [{"role": "user", "content": "What files are in the current directory?"}]
}'Claude will actually run ls and tell you what's there. That's the difference.
All configuration is via environment variables:
| Variable | Default | Description |
|---|---|---|
PORT |
3456 |
Port to listen on |
HOST |
127.0.0.1 |
Host to bind to (use 0.0.0.0 for all interfaces) |
PROXY_CWD |
Current directory | Working directory for Claude's tools |
MAX_TURNS |
15 |
Max tool-calling rounds per request |
ALLOWED_TOOLS |
Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch |
Comma-separated list of allowed tools |
Example with custom config:
PORT=8080 MAX_TURNS=5 ALLOWED_TOOLS="Read,Glob,Grep,WebSearch" node server.mjsOpenAI-compatible chat completions endpoint. Supports:
messages— array of{role, content}messagesmodel— model name (see below)stream—truefor SSE streamingmax_turns— override max tool-calling rounds
Returns available models.
Health check with status, tools, and model info.
| Model name | Maps to |
|---|---|
claude-opus-4 |
claude-opus-4-20250514 |
claude-sonnet-4 |
claude-sonnet-4-5-20250929 |
claude-sonnet-4-5 |
claude-sonnet-4-5-20250929 |
claude-haiku-4 |
claude-haiku-4-5-20251001 |
claude-haiku-4-5 |
claude-haiku-4-5-20251001 |
You can also use the full model ID directly.
Claude can use these tools internally while processing your request:
| Tool | Description |
|---|---|
| Bash | Execute shell commands |
| Read | Read file contents |
| Write | Create/overwrite files |
| Edit | Edit existing files (search & replace) |
| Glob | Find files by pattern |
| Grep | Search file contents |
| WebFetch | Fetch and process web pages |
| WebSearch | Search the web |
Tools run inside the proxy — your client just gets the final text response. No need to implement the OpenAI tool-calling protocol on your side.
This proxy was built to power OpenClaw bots using a Claude Max subscription instead of API credits. Config example:
{
"models": {
"providers": {
"claudemax": {
"baseUrl": "http://localhost:3456/v1",
"apiKey": "not-needed",
"api": "openai-completions",
"models": [
{ "id": "claude-opus-4", "name": "Claude Opus 4", "contextWindow": 200000, "maxTokens": 8192 },
{ "id": "claude-sonnet-4", "name": "Claude Sonnet 4", "contextWindow": 200000, "maxTokens": 8192 }
]
}
}
},
"agents": {
"defaults": { "model": { "primary": "claudemax/claude-opus-4" } },
"list": [{
"id": "personal",
"tools": { "byProvider": { "claudemax": { "deny": ["*"] } } }
}]
}
}Note: Deny OpenClaw's built-in tools for the
claudemaxprovider — the proxy handles tools internally via Claude Code's own toolset.
Create a LaunchDaemon for auto-start:
sudo tee /Library/LaunchDaemons/com.claude-max-openai-proxy.plist << EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.claude-max-openai-proxy</string>
<key>UserName</key>
<string>$(whoami)</string>
<key>ProgramArguments</key>
<array>
<string>$(which node)</string>
<string>$(pwd)/server.mjs</string>
</array>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>$(dirname $(which claude)):$(dirname $(which node)):/usr/bin:/bin</string>
<key>HOME</key>
<string>$HOME</string>
</dict>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
EOF
sudo launchctl load /Library/LaunchDaemons/com.claude-max-openai-proxy.plistYour App ──POST /v1/chat/completions──▶ Proxy ──query()──▶ Claude Agent SDK
│
┌───────┴───────┐
│ Claude Code │
│ subprocess │
└───────┬───────┘
│
Uses Claude Max/Pro
subscription (OAuth)
│
┌───────┴───────┐
│ Claude AI │
│ (Anthropic) │
└───────┬───────┘
│
Tool calls handled
internally (Bash,
Read, Write, etc.)
│
Your App ◀──── Final text response ──── Proxy ◀── result ─────────┘
- Your app sends an OpenAI-format request
- The proxy converts messages to a prompt and calls
query()from the Claude Agent SDK - The SDK spawns Claude Code as a subprocess (authenticated with your subscription)
- Claude processes the request, using tools as needed (reading files, running commands, etc.)
- The proxy collects Claude's final text response and returns it in OpenAI format
- Bind to localhost by default — the proxy is not exposed to the network
- Claude runs tools with your user's permissions — be careful with
BashandWritetools - No API keys needed — authentication is handled by Claude Code's OAuth
- To restrict tools, set
ALLOWED_TOOLS=Read,Grep,WebSearch(no write/exec access)
- No OpenAI-style tool calling protocol — tools run inside the proxy, not via
tool_callsresponses. Your client gets the final text only. - Token usage not tracked — the
usagefield in responses shows zeros (Claude Code doesn't expose token counts via the SDK in a usable format for the OpenAI schema). - One request at a time — each request spawns a Claude Code subprocess. Concurrent requests work but may hit subscription rate limits.
- Claude Max/Pro subscription required — this is not a free API. You're using your own subscription.
MIT — see LICENSE.
0x0ndra — github.com/0x0ndra