A small OpenAI-compatible gateway that routes requests through OpenClaw agents.
- Exposes OpenAI-style endpoints:
GET /v1/modelsPOST /v1/chat/completionsPOST /v1/completions
- Routes public models to different OpenClaw agents
- Adds debug headers for actual upstream/provider visibility
- Records per-request usage to local JSONL
- Works well as a shared gateway for SillyTavern and other custom apps
By default the example routing exposes:
openclaw/stopenclaw/mainopenclaw/writeropenclaw/coderopenclaw/research
Tracked in git:
config.example.jsonroutes.example.json.env.exampleclaw-proxy.service.example
Local-only files (ignored by git):
config.jsonroutes.json.envdata/usage.jsonl
cp config.example.json config.json
cp routes.example.json routes.json
cp .env.example .envEdit them for the current machine.
chmod +x deploy-install.sh
sudo ./deploy-install.sh /opt/claw-proxyIf you keep the project somewhere else, pass that directory instead.
{
"host": "0.0.0.0",
"port": 8780,
"apiKey": "change-me",
"corsOrigin": "*",
"agent": "st",
"publicModel": "openclaw/main",
"upstreamModel": "bailian/kimi-k2.5",
"thinking": "",
"defaultMode": "light",
"streamChunkSize": 24,
"timeoutSeconds": 600,
"includeOpenClawMeta": false
}{
"defaults": {
"agent": "main",
"mode": "light"
},
"clients": {
"default": {
"apiKey": "change-me",
"defaultModel": "openclaw/st",
"allowedModels": [
"openclaw/st",
"openclaw/main",
"openclaw/writer",
"openclaw/coder",
"openclaw/research"
]
}
},
"models": {
"openclaw/st": {
"agent": "st",
"mode": "light",
"configuredUpstreamModel": "bailian/kimi-k2.5"
},
"openclaw/main": {
"agent": "main",
"mode": "light",
"configuredUpstreamModel": "998code/gpt-5.4"
}
}
}Each generation response may include:
X-Claw-Proxy-ModeX-Claw-Proxy-AgentX-Claw-Proxy-SessionX-Claw-Proxy-Configured-Upstream-ModelX-Claw-Proxy-Actual-Upstream-ModelX-Claw-Proxy-Actual-ProviderX-Claw-Proxy-Prompt-TokensX-Claw-Proxy-Completion-TokensX-Claw-Proxy-Total-Tokens
GET /debug/usage?limit=50
Notes:
- Only requests made after usage logging was enabled are available
- Existing historical requests are not backfilled
Streaming is still pseudo-streaming for now: the proxy waits for the full result and then replays SSE-style chunks.