Major architectural upgrade: - Replace pool system with on-demand spawning (eliminates crash loops, DEGRADED states, and stdin timeout errors from v1.x) - Add session management with --resume support (reduces token waste on multi-turn conversations) - Expand default allowed tools (Bash, Read, Write, Edit, Glob, Grep, WebSearch, WebFetch, Agent) with configurable CLAUDE_ALLOWED_TOOLS - Add system prompt pass-through (CLAUDE_SYSTEM_PROMPT) - Add MCP config support (CLAUDE_MCP_CONFIG) - Add concurrency control (CLAUDE_MAX_CONCURRENT, default 5) - Add periodic auth health monitoring - Add session API endpoints (GET/DELETE /sessions) - Improve /health with full diagnostics (stats, sessions, errors, config) - Fix timeout race condition (graceful SIGTERM → SIGKILL) - Fix ERR_HTTP_HEADERS_SENT by checking headersSent in all response helpers - Document coexistence with Claude Code interactive mode (Telegram, IDE) - No conflict with CC: different ports, protocols, and process models Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
openclaw-claude-proxy
Already paying for Claude Pro/Max? Use it as your OpenClaw model provider — $0 extra API cost.
A lightweight, zero-dependency proxy that lets OpenClaw agents talk to Claude through your existing subscription. One command to set up, one file to run.
v2.0.0 — Major Upgrade
What's new:
- On-demand spawning — eliminates the pool crash loops, DEGRADED states, and stdin timeout errors from v1.x. Each request spawns a fresh
claude -pprocess with stdin written immediately. No more stale workers, no more backoff spirals. - Session management — multi-turn conversations use
--resumeto avoid resending full history. Reduces token waste and enables Claude Code's built-in context compression on long conversations. - Full tool access — expanded default tools (Bash, Read, Write, Edit, Glob, Grep, WebSearch, WebFetch, Agent). Configurable via
CLAUDE_ALLOWED_TOOLSor bypass all checks withCLAUDE_SKIP_PERMISSIONS=true. - System prompt pass-through — set
CLAUDE_SYSTEM_PROMPTto inject context into every request. - MCP config support — set
CLAUDE_MCP_CONFIGto load MCP servers (Telegram, etc.) into claude -p calls. - Concurrency control —
CLAUDE_MAX_CONCURRENTprevents runaway process spawning (default: 5). - Auth health monitoring — periodic
claude auth statuschecks with status exposed on/health. - Session API —
GET /sessionsto list,DELETE /sessionsto clear active sessions. - Improved diagnostics —
/healthendpoint shows stats, active sessions, recent errors, auth status, and full config.
Coexistence with Claude Code interactive mode: OCP and Claude Code (interactive/Telegram) run on completely different paths and can coexist on the same machine without conflict:
- OCP:
localhost:3456(HTTP) → spawnsclaude -pprocesses (per-request, stateless) - CC: MCP protocol (in-process) → persistent interactive session
- No shared ports, no shared processes, no shared sessions
Daemon advantage over CC: OCP runs as a system daemon (launchd/systemd) that auto-starts on boot and auto-recovers from crashes. Unlike Claude Code interactive mode, OCP does not require a terminal session to stay open — it survives disconnects, reboots, and SSH drops. Combined with OpenClaw's memory system, this means your agents never lose continuity.
How it works
OpenClaw Gateway → proxy (localhost:3456) → claude -p CLI → Anthropic (via OAuth)
The proxy translates OpenAI-compatible /v1/chat/completions requests into claude -p CLI calls. Anthropic sees normal Claude Code usage under your subscription — no API billing, no separate key.
Prerequisites
- Node.js >= 18
- Claude CLI installed and authenticated (
claude login) - OpenClaw installed
Quick Start (Node.js)
git clone https://github.com/dtzp555-max/openclaw-claude-proxy.git
cd openclaw-claude-proxy
# Auto-configure OpenClaw + start proxy + install auto-start
node setup.mjs
That's it. The setup script will:
- Verify Claude CLI is installed and authenticated
- Add
claude-localprovider toopenclaw.json - Add auth profiles to all agents
- Start the proxy
- Install auto-start on login (launchd on macOS, systemd on Linux)
Then set your preferred Claude model as default:
openclaw config set agents.defaults.model.primary "claude-local/claude-opus-4-6"
openclaw gateway restart
Session Management (v2.0)
Multi-turn conversations can use sessions to avoid resending full message history on every request.
How to enable: Include a session_id or conversation_id field in your request body, or set the X-Session-Id / X-Conversation-Id header.
{
"model": "claude-opus-4-6",
"session_id": "conv-abc-123",
"messages": [
{"role": "user", "content": "Hello"},
{"role": "assistant", "content": "Hi there!"},
{"role": "user", "content": "What did I just say?"}
]
}
First request with a new session_id: all messages are sent, session is persisted via --session-id.
Subsequent requests with the same session_id: only the latest user message is sent via --resume, reducing token consumption.
Sessions expire after 1 hour of inactivity (configurable via CLAUDE_SESSION_TTL).
API endpoints:
GET /sessions— list all active sessionsDELETE /sessions— clear all sessions
Security
- Localhost only — the proxy binds to
127.0.0.1and is not exposed to the internet or your local network - Bearer token auth (optional) — set
PROXY_API_KEYto require a Bearer token on all requests (except/health). When unset, auth is disabled for backwards compatibility - No API keys for Claude — authentication to Anthropic goes through Claude CLI's OAuth session, no Anthropic credentials are stored in the proxy
- Auto-start via launchd/systemd —
node setup.mjsinstalls a user-level launch agent (macOS) or systemd user service (Linux) so the proxy starts automatically on login - Remove auto-start at any time:
node uninstall.mjs
Manual Install
1. Start the proxy
node server.mjs
# or in background:
bash start.sh
2. Configure OpenClaw
Add to ~/.openclaw/openclaw.json under models.providers:
"claude-local": {
"baseUrl": "http://127.0.0.1:3456/v1",
"api": "openai-completions",
"apiKey": "<your PROXY_API_KEY, or omit if auth disabled>",
"models": [
{
"id": "claude-opus-4-6",
"name": "Claude Opus 4.6",
"reasoning": true,
"input": ["text"],
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 },
"contextWindow": 200000,
"maxTokens": 16384
},
{
"id": "claude-sonnet-4-6",
"name": "Claude Sonnet 4.6",
"reasoning": true,
"input": ["text"],
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 },
"contextWindow": 200000,
"maxTokens": 16384
},
{
"id": "claude-haiku-4",
"name": "Claude Haiku 4",
"reasoning": false,
"input": ["text"],
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 },
"contextWindow": 200000,
"maxTokens": 8192
}
]
}
3. Set as default model
openclaw config set agents.defaults.model.primary "claude-local/claude-opus-4-6"
openclaw gateway restart
Available Models
| Model ID | Claude CLI model | Notes |
|---|---|---|
claude-opus-4-6 |
claude-opus-4-6 | Most capable, slower |
claude-sonnet-4-6 |
claude-sonnet-4-6 | Good balance of speed/quality |
claude-haiku-4 |
claude-haiku-4-5-20251001 | Fastest, lightweight |
Environment Variables
| Variable | Default | Description |
|---|---|---|
CLAUDE_PROXY_PORT |
3456 |
Listen port |
CLAUDE_BIN |
(auto-detect) | Path to claude binary |
CLAUDE_TIMEOUT |
300000 |
Request timeout (ms) |
CLAUDE_ALLOWED_TOOLS |
Bash,Read,...,Agent |
Comma-separated tools to pre-approve |
CLAUDE_SKIP_PERMISSIONS |
false |
Set true to bypass all permission checks |
CLAUDE_SYSTEM_PROMPT |
(empty) | System prompt appended to all requests |
CLAUDE_MCP_CONFIG |
(empty) | Path to MCP server config JSON file |
CLAUDE_SESSION_TTL |
3600000 |
Session expiry in ms (default: 1 hour) |
CLAUDE_MAX_CONCURRENT |
5 |
Max concurrent claude processes |
PROXY_API_KEY |
(unset) | Bearer token for API authentication |
API Endpoints
GET /v1/models— List available modelsPOST /v1/chat/completions— Chat completion (streaming + non-streaming)GET /health— Comprehensive health check (stats, sessions, auth, config)GET /sessions— List active sessionsDELETE /sessions— Clear all sessions
Authentication
The proxy supports optional Bearer token authentication via the PROXY_API_KEY environment variable.
When PROXY_API_KEY is set, all requests (except GET /health) must include a valid Authorization: Bearer <token> header. Requests with a missing or invalid token receive a 401 Unauthorized response.
When PROXY_API_KEY is not set, authentication is disabled and all requests are accepted.
# Start with auth enabled
PROXY_API_KEY=my-secret-token node server.mjs
Architecture: v1 vs v2
| v1.x (pool) | v2.0 (on-demand) | |
|---|---|---|
| Process lifecycle | Pre-spawn idle workers | Spawn per request |
| Crash handling | Backoff → DEGRADED → manual restart | No crash loops (no idle workers) |
| Session support | None (stateless) | --resume with session tracking |
| Tool access | 6 tools hardcoded | Configurable, expanded defaults |
| System prompt | None | CLAUDE_SYSTEM_PROMPT env |
| MCP support | None | CLAUDE_MCP_CONFIG env |
| Concurrency | Unlimited (dangerous) | CLAUDE_MAX_CONCURRENT limit |
| Auth monitoring | None | Periodic health checks |
| Diagnostics | Basic /health | Full stats, sessions, errors |
Coexistence with Claude Code
OCP and Claude Code interactive mode (including Telegram bots) are completely independent:
| OCP (this proxy) | CC interactive | |
|---|---|---|
| Protocol | HTTP (localhost:3456) | MCP (in-process) |
| Process model | Per-request spawn | Persistent session |
| Lifecycle | Daemon (auto-start, auto-recover) | Requires terminal |
| Permission model | Pre-approved tools | Interactive prompts |
| Use case | Automated agent work | Human-in-the-loop |
Both can run on the same machine simultaneously. No shared state, no port conflicts.
Recovery after OpenClaw upgrade
OpenClaw upgrades (npm update -g openclaw) do not overwrite the user config at ~/.openclaw/openclaw.json. However, if the claude-local models stop working after an upgrade:
One-command recovery
cd ~/.openclaw/projects/claude-proxy # or wherever you cloned it
git pull # pull latest version
node setup.mjs # reconfigure OpenClaw + start proxy
openclaw gateway restart
Notes
- Cost shows as $0 because billing goes through your Claude subscription
- Each request spawns a
claude -pprocess; concurrent requests are capped byCLAUDE_MAX_CONCURRENT - The proxy must run on the same machine as the Claude CLI (uses local OAuth)
- Session data is stored by Claude CLI on disk; session map is in-memory (lost on proxy restart)
License
MIT