Coding Agents
Route Claude Code, Codex, OpenCode, Kimi Code, Kilo Code, MiMo Code, ZCode, Oh My Pi and other coding agents through LockLLM by changing one base URL and one API key. Requests are scanned before they reach the model, with optional scanning of tool calls and tool results.
Link to section: Why Route a Coding Agent Through LockLLMWhy Route a Coding Agent Through LockLLM
A coding agent has more reach than a normal application. It reads your repository, runs shell commands, opens web pages, installs packages, and then acts on whatever comes back. A single poisoned README, dependency changelog, issue comment, or web page can carry instructions the agent treats as work to do.
Every one of those agents talks to its model through one HTTP endpoint, and nearly all of them let you change it. Point that endpoint at LockLLM and every request the agent makes is scanned first. Nothing else changes: same commands, same models, same streaming output, same editor integration.
Two settings do it:
- Base URL - point it at a LockLLM proxy URL
- API key - use your LockLLM API key instead of the provider key
What you get once it is wired up:
- Prompt injection and jailbreak detection on the requests your agent sends
- Optional scanning of tool definitions, tool-call arguments, and tool results, which is how indirect attacks usually reach an agent
- Custom content policies applied to your own rules
- PII redaction, so personal data in a prompt is replaced with placeholders before the request is forwarded to the model
- One activity log covering every agent you use, not one dashboard per tool
Link to section: Before You StartBefore You Start
1. Get your LockLLM API key. Sign in to the dashboard and open the API Keys section. This is the key every agent below will use.
2. Decide how the model calls are paid for.
| Mode | What you configure | Who pays for the model |
|---|---|---|
| LockLLM credits (recommended) | Nothing extra. Use the universal proxy URL | Billed to your LockLLM credits, at the model's own cost |
| BYOK | Add your own provider key once in the dashboard under Proxy Settings, then use that provider's proxy URL | You pay the provider directly |
The model itself costs the same either way, because LockLLM does not add a margin to model usage. Credits mode is the one to start with: it needs no provider key, and from Tier 2 onwards it comes with free monthly credits that rise with your tier. Use BYOK when you already hold a provider key and would rather keep billing with that provider.
3. Keep your provider key out of the agent. Once the provider key lives in the LockLLM dashboard, remove it from your shell profile and your agent config. The agent should only ever hold your LockLLM key.
Link to section: Choosing Your Base URLChoosing Your Base URL
Pick the row that matches the API format your agent speaks.
| Agent speaks | Base URL | Requires |
|---|---|---|
Anthropic format (/v1/messages) | https://api.lockllm.com/v1/proxy/anthropic | An Anthropic key added in the dashboard |
| OpenAI format, your own key | https://api.lockllm.com/v1/proxy/openai | An OpenAI key added in the dashboard |
| OpenAI format, LockLLM credits | https://api.lockllm.com/v1/proxy | Nothing. Uses your credits |
| Another provider you hold a key for | https://api.lockllm.com/v1/proxy/{provider} | That provider's key added in the dashboard |
LockLLM supports 17+ providers. Slugs for the last row: openai, anthropic, gemini, cohere, openrouter, perplexity, mistral, groq, deepseek, together, xai, fireworks, anyscale, huggingface, azure, bedrock, vertex-ai. Every one of them also accepts a custom endpoint URL, which you set alongside the key in the dashboard, so self-hosted and regional deployments work through the same path.
The OpenAI and Anthropic URLs tolerate a trailing /v1. Agents disagree about whether the base URL should end in a version segment, and for these two either spelling reaches the same place:
https://api.lockllm.com/v1/proxy/openai
https://api.lockllm.com/v1/proxy/openai/v1
For every other provider, use the plain slug URL and let the agent append its usual path. Adding a version segment of your own to the other providers produces a doubled path that the provider rejects.
If your agent appends /v1/chat/completions, use a provider URL such as /v1/proxy/openai, which handles that spelling. The credits URL expects a client that appends /chat/completions only, and there is no credits URL that accepts the /v1 spelling. Note that the provider URL needs that provider's key in your dashboard, so this route means BYOK.
azure, bedrock and vertex-ai are not drop-in base URLs for an agent that appends /chat/completions. They keep their own path shapes, which are covered in Proxy Mode.
Link to section: The One Rule That Applies to Every AgentThe One Rule That Applies to Every Agent
Your LockLLM API key must arrive in the Authorization header as a bearer token:
Authorization: Bearer YOUR_LOCKLLM_API_KEY
Most tools do this for you when you paste a key into their API key field. A few tools that were built for a specific provider send the key in that provider's own header style instead. When a tool offers both an "API key" setting and an "auth token" setting, choose the one that sets Authorization. Each section below names the right setting for that tool.
Link to section: Settings Worth Turning On for AgentsSettings Worth Turning On for Agents
By default LockLLM scans and warns without blocking anything, which is a safe place to start. These headers are the ones that matter most for agent traffic. Most of the agents below have somewhere to put custom headers, and each section shows where. Where a tool has no such field, its section says so.
| Header | Value | Why it matters for a coding agent |
|---|---|---|
x-lockllm-tool-scan | true | Scans tool definitions, tool-call arguments, and tool results, not just your message. This is the single most useful setting here, because the text an agent fetches from a file or a web page is where injected instructions usually arrive |
x-lockllm-scan-action | block | Stops a flagged request instead of forwarding it with a warning. Start with the default warning mode, then switch once you have seen your own traffic |
x-lockllm-pii-action | strip | Replaces personal data in the prompt with placeholders before the request is forwarded to the model |
x-lockllm-policy-action | block | Enforces your own custom policies, for example rules about which internal systems may be discussed |
x-lockllm-sensitivity | low | Worth trying if you work on security code. Agents that read exploit write-ups or authentication logic legitimately handle text that looks adversarial |
x-lockllm-end-user | Your own opaque id | Attributes activity per developer on a shared key. Use an internal identifier, never a name or an email address |
Two behaviours worth knowing before you rely on this. Scanning the model's reply is a separate opt-in feature and is skipped entirely for streamed replies, and coding agents stream by default, so on agent traffic it is the request-side scanning and tool scanning above that protect you. Model listing endpoints are not proxied either, so if your agent shows an empty model dropdown, take the model ID from the Model List page and type it in by hand. On the credits URL it has to match exactly.
Link to section: Claude CodeClaude Code
Claude Code speaks the Anthropic format, so it needs the Anthropic proxy URL and an Anthropic key stored in your dashboard.
The important detail is which environment variable you use for the key. ANTHROPIC_AUTH_TOKEN is the one that sets the Authorization header, which is what LockLLM reads.
export ANTHROPIC_BASE_URL="https://api.lockllm.com/v1/proxy/anthropic"
export ANTHROPIC_AUTH_TOKEN="YOUR_LOCKLLM_API_KEY"
unset ANTHROPIC_API_KEY
Then run claude as usual. Models, slash commands, subagents, and streaming all behave exactly as before.
To make it permanent for every project, put it in ~/.claude/settings.json instead:
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.lockllm.com/v1/proxy/anthropic",
"ANTHROPIC_AUTH_TOKEN": "YOUR_LOCKLLM_API_KEY",
"ANTHROPIC_CUSTOM_HEADERS": "x-lockllm-tool-scan: true\nx-lockllm-pii-action: strip"
}
}
ANTHROPIC_CUSTOM_HEADERS takes one Header-Name: value pair per line, which is where your LockLLM settings go. Scope it to a single repository by using that project's .claude/settings.json rather than the global file.
Tool scanning is worth enabling here specifically. Claude Code reads files, runs commands, and fetches pages on your behalf, and those results come back into the conversation as tool output.
Link to section: OpenAI Codex CLIOpenAI Codex CLI
Codex defines providers in ~/.codex/config.toml. Add one that points at LockLLM and select it.
With your own OpenAI key:
model_provider = "lockllm"
model = "gpt-5.2"
[model_providers.lockllm]
name = "LockLLM"
base_url = "https://api.lockllm.com/v1/proxy/openai"
env_key = "LOCKLLM_API_KEY"
wire_api = "responses"
http_headers = { "x-lockllm-tool-scan" = "true", "x-lockllm-pii-action" = "strip" }
Two things to get right:
env_keynames the environment variable Codex reads the key from, so exportLOCKLLM_API_KEYin your shell. Codex sends it as a bearer token, which is what LockLLM expects.wire_apimust beresponses. Current Codex versions rejectwire_api = "chat"when the config loads, and that failure stops Codex from starting at all rather than just disabling one provider.
Use env_http_headers instead of http_headers when you would rather read a header value from the environment.
Codex needs BYOK. Because Codex only speaks the Responses format, the LockLLM credits URL is not an option for it, so this is the one agent on this page that requires an OpenAI key in your dashboard.
Link to section: Kimi CodeKimi Code
Kimi Code keeps providers and model aliases in ~/.kimi-code/config.toml. Add a provider pointing at LockLLM, then a model alias that uses it:
default_model = "lockllm/main"
[providers.lockllm]
type = "openai"
base_url = "https://api.lockllm.com/v1/proxy"
api_key = "YOUR_LOCKLLM_API_KEY"
[models."lockllm/main"]
provider = "lockllm"
model = "MODEL_ID_FROM_MODEL_LIST"
max_context_size = 262144
capabilities = [ "tool_use" ]
display_name = "LockLLM"
Keep type = "openai", which is the setting that sends your key as a bearer token. Kimi Code's anthropic provider type sends the key as x-api-key instead and has no field for overriding that, so an Anthropic-format provider pointed at LockLLM is rejected with a 401 on every request.
That file already contains the providers Kimi Code shipped with, so if your version spells a field differently, copy the shape of the entries next to yours. kimi provider list confirms the provider was picked up.
Kimi Code cannot send the LockLLM setting headers. Its provider block has no custom-header field, and a headers key added to it passes validation while being dropped from the request. Tool scanning and the other header settings above are therefore unavailable here, and the defaults apply instead.
Link to section: Oh My PiOh My Pi
Use the Anthropic route. ANTHROPIC_CUSTOM_HEADERS is the setting that lets you control the Authorization header directly, which is what LockLLM reads:
export ANTHROPIC_BASE_URL="https://api.lockllm.com/v1/proxy/anthropic"
export ANTHROPIC_API_KEY="placeholder"
export ANTHROPIC_CUSTOM_HEADERS="Authorization: Bearer YOUR_LOCKLLM_API_KEY
x-lockllm-tool-scan: true"
omp -p "hi"
ANTHROPIC_API_KEY has to be set to something or Oh My Pi stops before sending anything, reporting that it found no API key. Its value is never used: the Authorization header above carries your LockLLM key, and the model call uses the Anthropic key stored in your dashboard.
Do not use
OPENAI_BASE_URLwith Oh My Pi. It is ignored for its built-in models, and the request goes to the provider directly. That failure is silent: the agent works normally and nothing reaches LockLLM, so there is no error to tell you the scanning never happened. Confirm your setup in the dashboard Activity Logs rather than assuming it applied.
Link to section: OpenCode, Kilo Code and MiMo CodeOpenCode, Kilo Code and MiMo Code
These three share OpenCode's configuration shape, so the same block works in all of them. The block below is verified against OpenCode itself; Kilo Code and MiMo Code track the same schema, so if your version spells something differently, follow the entries already in your own file. Only the path differs:
| Agent | Config file |
|---|---|
| OpenCode | ~/.config/opencode/opencode.jsonc |
| Kilo Code | ~/.config/kilo/kilo.jsonc |
| MiMo Code | ~/.config/mimocode/mimocode.jsonc |
Add a provider block:
{
"provider": {
"lockllm": {
"npm": "@ai-sdk/openai-compatible",
"name": "LockLLM",
"options": {
"baseURL": "https://api.lockllm.com/v1/proxy",
"apiKey": "{env:LOCKLLM_API_KEY}",
"headers": {
"x-lockllm-tool-scan": "true",
"x-lockllm-pii-action": "strip"
}
},
"models": {
"MODEL_ID_FROM_MODEL_LIST": {
"name": "LockLLM",
"tool_call": true,
"limit": { "context": 400000, "output": 128000 }
}
}
}
}
}
Swap baseURL for https://api.lockllm.com/v1/proxy/openai to bill the model call to your own OpenAI key instead of LockLLM credits.
List your models explicitly, as shown above. These agents cannot discover models through the proxy, and an empty models map leaves you with an empty picker. Set the context and output limits to match the model you chose.
Link to section: ZCodeZCode
Add a custom model provider in ZCode's settings and fill in:
- Format: Anthropic, or OpenAI-compatible
- Base URL:
https://api.lockllm.com/v1/proxy/anthropicfor the Anthropic format, orhttps://api.lockllm.com/v1/proxyfor the OpenAI-compatible format - API key: your LockLLM API key
- Model: type the model ID from the Model List rather than relying on in-app discovery, which the proxy does not serve
The same thing can be edited directly in ~/.zcode/v2/config.json, which is useful if you want to version-control the setup. Providers there follow this shape, and the headers map is where the LockLLM settings go:
{
"provider": {
"lockllm": {
"kind": "anthropic",
"options": {
"baseURL": "https://api.lockllm.com/v1/proxy/anthropic",
"apiKey": "YOUR_LOCKLLM_API_KEY",
"headers": { "x-lockllm-tool-scan": "true" }
}
}
}
}
Use "kind": "openai-compatible" with the /v1/proxy base URL to run on LockLLM credits instead.
Link to section: DeepSeek, Groq, Mistral and Other Provider CLIsDeepSeek, Groq, Mistral and Other Provider CLIs
Command line tools published by a single provider almost always expose a base URL override next to the API key setting, either as a config field or an environment variable such as DEEPSEEK_BASE_URL or MISTRAL_BASE_URL. Point it at that provider's LockLLM URL and put your LockLLM key in the key field:
https://api.lockllm.com/v1/proxy/deepseek
https://api.lockllm.com/v1/proxy/groq
https://api.lockllm.com/v1/proxy/mistral
https://api.lockllm.com/v1/proxy/xai
Each one needs that provider's key stored in your dashboard. Custom endpoints are supported too, so a self-hosted or regional deployment of the same provider still works: set the endpoint URL alongside the key in the dashboard and keep using the same proxy URL in the tool.
Link to section: Editor Extensions and Other AgentsEditor Extensions and Other Agents
Cline, Roo Code, Continue, Aider, Zed, Cursor and similar tools all expose the same two fields somewhere in their model settings. The recipe does not change:
- Choose the provider type that matches the format you want, usually the one labelled OpenAI Compatible, or Anthropic if the tool offers it
- Set the base URL from the table above
- Paste your LockLLM API key into the API key field
- Type the model ID manually instead of using a "fetch models" button
- Add
x-lockllm-tool-scan: truein the custom headers field if the tool has one
If a tool only lets you pick from a fixed provider list with no editable base URL, it cannot be pointed at LockLLM at all, and no proxy in front of it changes that. Your options there are to ask the vendor for a custom endpoint setting, or to keep that tool outside LockLLM and protect the code paths you control with the SDKs.
Link to section: Verify It WorksVerify It Works
Before wiring up an agent, confirm the URL and key work on their own:
curl -sS -D - -o /dev/null https://api.lockllm.com/v1/proxy/chat/completions \
-X POST \
-H "Authorization: Bearer $LOCKLLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"MODEL_ID_FROM_MODEL_LIST","messages":[{"role":"user","content":"hello"}]}'
The URL here is the base URL you gave the agent plus the path the agent appends, which for the credits URL is /chat/completions. For BYOK, use your provider URL plus the same path, for example https://api.lockllm.com/v1/proxy/openai/chat/completions, or https://api.lockllm.com/v1/proxy/anthropic/v1/messages for the Anthropic format. In the response headers, look for:
X-LockLLM-Scanned: true
X-LockLLM-Safe: true
X-Request-Id: ...
X-LockLLM-Scanned: true is the confirmation that the request went through the gateway rather than straight to the provider.
Once the agent itself is running, open the Activity Logs page in your dashboard. Every request the agent makes appears there, so if the log stays empty the agent is still talking to the provider directly and its base URL did not take effect.
Link to section: Shared and Team SetupsShared and Team Setups
- Give each developer their own LockLLM API key rather than sharing one. Revoking one key then costs one person a minute, not the whole team a morning.
- Set
x-lockllm-end-userto an internal identifier so activity is attributed per developer. Use an opaque id you control, such as an internal user id, so no personal data is sent. - Keep policies and routing rules in an organization so every agent on the team enforces the same rules without anyone copying config around.
- Check in the agent config with a placeholder, never the key itself. All the formats above can read the key from an environment variable.
Link to section: TroubleshootingTroubleshooting
| What you see | What it means |
|---|---|
401 unauthorized | The key did not arrive as Authorization: Bearer. Check you used the auth token setting rather than the provider API key setting |
400 with code no_byok_key | You used a provider URL without that provider's key in the dashboard. Add the key, or switch to the credits URL |
402 | Out of credits. Top up in Billing. This can happen on BYOK too, because detection fees are charged to your balance whichever URL you use |
404 not_found | The agent called something outside the proxy, usually a model list. Type the model ID manually |
An HTML page instead of a reply, on any status including 200 | The path shape is wrong for that URL, so the provider answered with its own web page. Recheck the base URL against the table above |
400 with code prompt_injection_detected | Blocking is on and the request was flagged. The dashboard log shows which request it was |
403 with code pii_detected | PII blocking is on. Switch to strip if you would rather redact than reject |
403 with code policy_violation | One of your custom policies blocked the request. The log names the policy |
429 | Either the rate limit for your tier, which rises with usage, or a monthly billing limit you set. Check Billing before assuming it is the rate limit. See pricing |
| Empty model list in the agent | Expected. Model discovery is not proxied. Enter the model ID by hand |
| Requests still not in your logs | The base URL did not apply. Many agents cache config or need a restart, and a shell export only affects the shell it was run in |
Link to section: What It CostsWhat It Costs
Scanning a safe prompt is free, no matter how many requests your agent makes. You are charged only when something is found:
| Event | Cost |
|---|---|
| Safe request | Free |
| Threat detected | $0.0001 |
| Policy violation | $0.0001 |
| PII detected | $0.0001 |
| Routing to a cheaper model | 5% of what it saved you |
| Routing to a same or more expensive model | Free |
| Model usage, BYOK | Free. You pay your provider directly |
| Model usage, LockLLM credits | The model's own cost |
A day of ordinary agent work where nothing is flagged costs nothing beyond the model calls themselves. From Tier 2 onwards you also receive free monthly credits, and the amount rises with your tier.
Link to section: Security NotesSecurity Notes
- Your provider keys are encrypted at rest, never returned by the API, and never written to logs or error messages.
- Your prompts are not used to train models, and the dashboard records that a request happened and what was found rather than the contents of your code. See Privacy and Security for how request data is handled.
- Rotating a provider key is a dashboard change. No agent config has to be touched, because none of them hold that key.
- Tool scanning is the setting that matters most for agents, and it is off by default. Turn it on with
x-lockllm-tool-scan: truebefore you rely on this for anything that browses the web or reads untrusted repositories.
Related reading: Proxy Mode for the full header reference, Threat Detection for what the scanner looks for, and Best Practices for production guidance.