A local HTTP proxy that routes OpenClaw requests through Anthropic's official Claude Agent SDK, enabling compliant API usage.
OpenClaw SDK Wrapper acts as a bridge between OpenClaw and Anthropic's API. Instead of OpenClaw connecting directly to api.anthropic.com (which violates Anthropic's ToS), it connects to this local proxy on localhost:3099. The proxy then routes requests through the sanctioned Claude Agent SDK using your OAuth credentials from claude login.
OpenClaw → localhost:3099 → Claude Agent SDK → claude binary → Anthropic API
- Single-turn inference only — no tools, just LLM responses
- OAuth-based authentication — uses your
claude loginsession - Request/response logging — SQLite database with cost tracking
- Streaming and non-streaming support — compatible with OpenClaw's API expectations
- Node.js (version 14 or higher)
- Claude CLI installed and authenticated:
# Install Claude CLI (if not already installed) brew install claude # Authenticate with your Anthropic account claude login
git clone https://github.com/rytis/openclaw-sdk-wrapper.git
cd openclaw-sdk-wrapper
npm install# Run tests to ensure everything works
npm test
# Start the server manually to test
npm startThe server should start on port 3099. You can test it with:
curl http://localhost:3099/healthTo run the service automatically on startup:
# Copy the plist file to LaunchAgents
cp openclaw-sdk-wrapper.plist ~/Library/LaunchAgents/com.rytis.openclaw-sdk-wrapper.plist
# Load and start the service
launchctl load ~/Library/LaunchAgents/com.rytis.openclaw-sdk-wrapper.plist
launchctl start com.rytis.openclaw-sdk-wrapperAdd this configuration to your ~/.openclaw/config.json5:
{
models: {
providers: {
"claude-local": {
baseUrl: "http://localhost:3099",
apiKey: "local", // Any value works - no validation required
api: "anthropic-messages",
models: [
{
id: "claude-sonnet-4-6",
name: "Claude Sonnet 4.6 (local)",
reasoning: true,
input: ["text", "image"],
contextWindow: 200000,
maxTokens: 64000
},
{
id: "claude-opus-4-6",
name: "Claude Opus 4.6 (local)",
reasoning: true,
input: ["text", "image"],
contextWindow: 200000,
maxTokens: 32000
}
]
}
}
},
agents: {
defaults: {
model: { primary: "claude-local/claude-sonnet-4-6" }
}
}
}# Development mode (manual start)
npm start
# Background service (if installed via launchctl)
launchctl start com.rytis.openclaw-sdk-wrapper- POST /v1/messages — Anthropic Messages API compatible endpoint
- GET /health — Health check and version info
- GET /stats — Usage statistics and cost tracking
Create a .env file (copy from .env.example) to customize behavior:
# Optional: Override OAuth token (normally read from claude login)
CLAUDE_CODE_OAUTH_TOKEN=your_token_here
# Optional: Change server port (default: 3099)
PORT=3099
# Optional: Skip OAuth verification (for debugging)
SKIP_SMOKE_TEST=1- Service logs:
~/.openclaw-sdk-wrapper/daemon.log(when running as service) - Call database:
~/.openclaw-sdk-wrapper/calls.db(SQLite) - Stats endpoint:
curl http://localhost:3099/stats
# Re-authenticate with Claude CLI
claude logout
claude login
# Verify authentication
claude --version# Check if port 3099 is in use
lsof -i :3099
# View service logs
tail -f ~/.openclaw-sdk-wrapper/daemon.log
# Manually start to see errors
cd ~/dev/openclaw-sdk-wrapper
npm start- Verify the proxy is running:
curl http://localhost:3099/health - Check OpenClaw config points to correct
baseUrl: "http://localhost:3099" - Ensure model IDs match between config and proxy
# Stop the service
launchctl stop com.rytis.openclaw-sdk-wrapper
# Unload from LaunchAgents
launchctl unload ~/Library/LaunchAgents/com.rytis.openclaw-sdk-wrapper.plist
# Remove plist file
rm ~/Library/LaunchAgents/com.rytis.openclaw-sdk-wrapper.plist# Remove application directory
rm -rf ~/dev/openclaw-sdk-wrapper
# Remove data directory (optional - contains logs and usage database)
rm -rf ~/.openclaw-sdk-wrapperEdit ~/.openclaw/config.json5 to remove or comment out the claude-local provider configuration.
npm testsrc/
├── server.js # HTTP server (port 3099)
└── shared/
├── model-utils.js # Model aliasing and provider detection
├── interaction-store.js # SQLite logging with cost estimation
├── anthropic-agent-sdk.js # OAuth + SDK integration
└── llm-router.js # Request routing by provider
The proxy supports these aliases for easier configuration:
opus-4→claude-opus-4-6sonnet-4→claude-sonnet-4-6haiku-3.5→claude-haiku-3-5
ISC
For issues related to:
- Proxy functionality: File issues in this repository
- OpenClaw integration: Check OpenClaw documentation
- Claude CLI authentication: See Anthropic's documentation