Claude Code#

Claude Code talks to Anthropic, so it uses Lockpin’s Anthropic route, http://127.0.0.1:8787/anthropic. Use an Anthropic API key: these steps are for API billing, where a dollar cap means something.

Connect with one command#

lockpin connect claude

It adds ANTHROPIC_BASE_URL to the env block of ~/.claude/settings.json, so every Claude Code session on this machine, background agents included, goes through Lockpin.

  • It shows the change and asks first, keeps the old file as a backup, and changes no other key.

  • It refuses when no Lockpin is running, since Claude Code could not reach the model until one is. -force connects anyway.

  • It refuses when the machine’s managed settings already set the address.

  • -project writes this folder’s .claude/settings.local.json instead. It never writes the shared .claude/settings.json, which goes to everyone who clones the repository.

  • -dry-run only shows the change.

To undo it, run lockpin disconnect claude. A session that is already open keeps Lockpin’s address until you restart it.

A company points everyone’s Claude Code at its Lockpin with Claude Code’s managed settings (managed-settings.json or device management), which no developer can override. connect leaves those alone.

Set the base URL yourself#

export ANTHROPIC_BASE_URL=http://127.0.0.1:8787/anthropic
export _CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL=1
export ANTHROPIC_API_KEY=...     # your own key; Lockpin passes it on
claude
$env:ANTHROPIC_BASE_URL = "http://127.0.0.1:8787/anthropic"
$env:_CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL = "1"
$env:ANTHROPIC_API_KEY = "..."   # your own key; Lockpin passes it on
claude

To have Lockpin hold the key instead, leave ANTHROPIC_API_KEY unset on the client and set it in the shell that starts Lockpin.

lockpin run -- claude sets the same variables for one run only.

Why the second variable#

Behind any base URL that is not Anthropic’s, Claude Code stops marking its standard prompt for Anthropic’s shared prompt cache, and sends inline the tools it would otherwise load when needed. Each session then pays to write about 30,000 tokens that it would otherwise read for a tenth of the price. In one measured session, Claude Code cost 2.7 times as much through Lockpin as without it.

Lockpin forwards Anthropic calls unchanged, so lockpin connect claude and lockpin run -- claude also set _CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL=1. This Claude Code setting keeps its requests as they are without a base URL. It is undocumented and could change in a later Claude Code. Lockpin logs a warning once when Claude Code arrives without the shared cache, and lockpin doctor warns when the setting is missing.

With the setting, Claude Code also sends its API key to Anthropic’s own servers for its settings, policy and feature lookups, as it does without Lockpin. Model calls still go through Lockpin.

On a team server#

Set ANTHROPIC_BASE_URL to the server, for example https://lockpin.example.com/anthropic, and use your lp_... key as the API key, in ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN. Lockpin reads the key from either. Claude Code may ask once whether to use a custom API key: say yes.

Do not set _CLAUDE_CODE_ASSUME_FIRST_PARTY_BASE_URL with an lp_... key. That key must not go to Anthropic’s servers, so connect leaves the setting off for team keys, and team sessions miss the shared cache. See Set up a team.

Task name and budget#

Each session is its own task, with nothing to set. Claude Code sends an X-Claude-Code-Session-Id header with every call (version 2.1.86 and later). A call that names no task is charged to its session, as a task such as claude-3f9a2c1b (the first 8 characters of the id). So each session has its own budget, -default-budget ($1.00 unless you change it), and its own line in the meter. The session’s subagents and background calls carry the same id and count toward it. -session-tasks=false puts all sessions on the shared default task instead.

To name the task yourself, or give it a lower budget, put the headers in ANTHROPIC_CUSTOM_HEADERS, one Name: Value per line:

export ANTHROPIC_CUSTOM_HEADERS=$'X-Lockpin-Task: refactor-auth\nX-Lockpin-Budget-Usd: 0.50'
claude
$env:ANTHROPIC_CUSTOM_HEADERS = "X-Lockpin-Task: refactor-auth`nX-Lockpin-Budget-Usd: 0.50"
claude
  • A new task name is a new budget.

  • The header can only lower a budget. For more than -default-budget, start Lockpin with a higher one, or raise the task in the meter.

  • The same variable can go in the env block of a project’s Claude Code settings file, to give one project one task name.

  • Claude Code’s background calls, such as summaries on a small, fast model, carry the same headers, so they count toward the same task.

If your version ignores ANTHROPIC_CUSTOM_HEADERS, cap it with a key instead: start Lockpin with -default-budget 0 and give Claude Code its own key with a -day or -month limit. See Keys.

When the cap hits#

Lockpin answers HTTP 402 in Anthropic’s error shape, with type budget_exceeded and a message that starts with lockpin:. Claude Code shows the API error, so you see the lockpin: text with the numbers. The call never reached Anthropic, so it cost nothing.

To go on, raise the task in the meter, use a new task name, or wait for the key limit to reset (resets_at in the body). If the meter, VS Code or the overlay is open, Lockpin first holds the call and asks there. See Approvals at the cap.

Review prompts before they are sent#

Lockpin can run as Claude Code’s UserPromptSubmit hook and review each prompt after you press Enter, before the model sees it.

lockpin hooks install -agent claude-code -model claude-sonnet-5-5

It prints the change to ~/.claude/settings.json as a diff (the project’s .claude/settings.json with -project) and writes it only after you answer yes. Set -model to the model you use: a new session’s first prompt is priced with it. Add -lint to also add the lint check below. lockpin hooks uninstall -agent claude-code takes it out. Lockpin never changes these files on its own.

To add it by hand:

{
  "hooks": {
    "UserPromptSubmit": [
      { "hooks": [ { "type": "command", "command": "lockpin hooks review -hook claude-code -model claude-sonnet-5-5", "timeout": 10 } ] }
    ]
  }
}

For each prompt it reads the session’s transcript to find the model, how many calls a turn has taken lately and how large the context already is. Then:

  • No findings: it prints nothing, and the prompt goes as it is.

  • Small findings: the prompt goes, and Claude Code shows you the findings. The model does not get them, so they add no cost.

  • A secret, or fixes that would save at least $0.10 or 20,000 tokens this turn: the prompt is blocked, and Claude Code shows the findings with your prompt so you can copy and change it. Add lockpin:ok to a prompt to send it as it is. A secret blocks even then.

Each message is a few lines, with a link to a highlighted review page and a trimmed copy to paste. -block-usd and -block-tokens change the thresholds.

Note

Claude Code still writes a blocked prompt to the session’s transcript file on disk. If you pasted a real key, rotate it, even though it was never sent.

Lint check#

lockpin hooks lint -hook claude warns you, without telling the model, when:

  • the conversation has been idle longer than the prompt cache lasts, so this turn sends the whole conversation again at full price (it shows the cost both ways);

  • the message is large, 8,000 tokens or more by Lockpin’s estimate (-large N), so it is sent again on every later turn;

  • the message repeats a paragraph.

With -block, a large or repeated message is stopped instead. Send it again unchanged to send it anyway. The check runs on your machine, makes no network call, and lets the prompt through if it cannot run. Prices are list prices: on a Claude subscription they show what the turn would cost through the API, not what you pay.

For a company#

An admin can put the same "hooks" block in Claude Code’s managed settings, so it runs on every machine. Users can add hooks of their own but cannot remove a managed one. Install the lockpin program on every machine’s PATH with the same tool you use for the settings.

Models#

A model with no price is refused with HTTP 400 unknown_model, so the cap cannot be skipped. lockpin providers -models lists the priced models. To add one, see Prices.

Verify#

  • lockpin doctor shows Claude Code sending its calls through Lockpin, with no warning about the shared cache.

  • After one prompt, the meter shows a task named claude- and 8 characters, or the name you set.