cd /news/developer-tools/exporting-anthropic-base-url-does-no… · home topics developer-tools article
[ARTICLE · art-98133] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Exporting ANTHROPIC_BASE_URL does not reach the Claude Code panel in VSCode

A developer has created a toolkit to synchronize environment variables between the Claude Code CLI and the VSCode extension panel, addressing the issue that the panel ignores shell exports like ANTHROPIC_BASE_URL. The toolkit manages a specific set of six variables in VSCode's settings.json with backup and restore, while the CLI wrapper routes per-process without persisting changes. The solution is designed around the asymmetry between the terminal's process scope and the panel's machine scope.

read3 min views1 publishedAug 15, 2026

export ANTHROPIC_BASE_URL=http://127.0.0.1:20128

in your shell routes the claude

CLI to a local endpoint. Open the Claude Code panel in VSCode in the same project and it still talks to Anthropic directly. The two live on different environment surfaces, and that is the whole problem.

The CLI reads the environment of the process you started it from. The VSCode panel does not: the extension spawns its agent process from the VSCode window process, so its environment is whatever VSCode itself was started with — the desktop/login environment, not the shell you typed export

into five seconds ago.

Two consequences that bite in opposite directions:

The escape hatch the extension gives you is a settings key, claudeCode.environmentVariables

, which is a list of {name, value}

pairs injected into the agent process. You can check what your panel actually sees right now — this runs anywhere jq

does:

S="$HOME/Library/Application Support/Code/User/settings.json"

jq -r '.["claudeCode.environmentVariables"] // []
  | if length == 0
    then "panel env: (none set) -> extension inherits the VSCode process env"
    else (.[] | "\(.name)=\(if .name|test("TOKEN|KEY") then "***" else .value end)")
    end' "$S"

On a machine that has never been switched, that prints the (none set)

line. That is the honest answer to "why is my panel ignoring the variable".

claudeCode.environmentVariables

is a plain array in your user settings.json

, and hand-editing it has three failure modes I hit before writing anything:

ANTHROPIC_BASE_URL

behind while removing the token and the panel points at a router with no credential.NODE_EXTRA_CA_CERTS

— is one careless overwrite away from gone.So the toolkit I ended up with treats the array as partly owned. It manages exactly six names:

ANTHROPIC_BASE_URL
ANTHROPIC_AUTH_TOKEN
ANTHROPIC_API_KEY
ANTHROPIC_MODEL
ANTHROPIC_SMALL_FAST_MODEL
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC

Entries whose name is not on that list are read, kept aside, and written back untouched. Before any write it copies settings.json

to settings.json.bak-claude-router

, and if serialisation throws it restores the backup and exits non-zero rather than leaving you with half a settings file.

& "$env:USERPROFILE\.claude\9router\vscode-switch.ps1" on      # inject the six
& "$env:USERPROFILE\.claude\9router\vscode-switch.ps1" status  # print base URL + model, never the token
& "$env:USERPROFILE\.claude\9router\vscode-switch.ps1" off     # remove only the six

on

and off

need a Developer: Reload Window afterwards — the agent process reads its environment once at spawn.

For the CLI the right scope is the narrow one, so there routing is per-process and nothing is persisted:

claude                    # default Anthropic connection
claude-9router            # same CLI, routed
claude-9router --resume   # normal Claude CLI arguments pass through

claude-9router

sets the variables inside its own process, unsets ANTHROPIC_API_KEY

so a leftover key cannot win over the router token, then execs claude

. Close the window and the routing is gone. Nothing in ~/.claude

is rewritten.

That asymmetry is deliberate and it is the actual design decision: the terminal gets process scope because a shell is cheap to start, the panel gets machine scope with an explicit on/off because the extension gives no narrower hook. Cost of the second: you cannot have one routed window and one direct window at the same time. If you need both, use the panel for one and claude-9router

in a terminal for the other.

The endpoint is a 9Router instance, whose Anthropic-compatible /v1/messages

fronts a long list of providers. The toolkit hard-codes none of them; it reads a gitignored local file:

{
  "baseUrl": "http://127.0.0.1:20128",
  "authToken": "your-9router-api-key",
  "mainModel": "provider/model-id",
  "smallFastModel": "provider/smaller-model-id"
}

Limits, stated plainly:

Code, tests and setup guide: ** https://github.com/vinhnguyenthanhdn/claude-router** (MIT).

The open gap is the platform one: the Windows paths are the only ones implemented and tested, and porting is work I have not done. Three issues are scoped and open:

claude-9router.ps1

If you only want to confirm the diagnosis rather than write code: run the jq

snippet above on your machine and tell me what your panel is actually inheriting. That answer is useful on its own.

── more in #developer-tools 4 stories · sorted by recency
── more on @anthropic 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/exporting-anthropic-…] indexed:0 read:3min 2026-08-15 ·