Skip to content

Instantly share code, notes, and snippets.

@AWolf81
Last active October 4, 2025 19:41
Show Gist options
  • Select an option

  • Save AWolf81/a55da051f5e9852aedaf50e0e260a5f8 to your computer and use it in GitHub Desktop.

Select an option

Save AWolf81/a55da051f5e9852aedaf50e0e260a5f8 to your computer and use it in GitHub Desktop.
Claude Code Proxy to Openrouter (running in local Docker)

CLAUDE CODE PROXY setup

If you don't have a file at .claude/settings.local.json --> create one with

{
 "env": {
 },
 "permissions": {
   "allow": [],
   "deny": [],
   "ask": []
 }
}

Why is it needed?

Because openrouter is only using an openai compatible endpoint with this proxy it will be compatible to Anthropic api style /v1/messages I'm testing this right now if I'm exceeding my daily quota.

Usage:

Once you have the docker running with docker run -d -p 5000:3000 --env-file .env ghcr.io/kiyo-e/claude-code-proxy:latest

  1. localhost:5000/ in browser will show that the proxy is started and what is configured.
  2. Start claude code and it will use the proxy if you switched to it.
  3. If you switch back you're having your Claude code subscription (restart the CLI or close/open the extension)

Use ./switch-model.sh to toggle between Claude code subscription and glm via openrouter

The script sets ANTHROPIC_BASE_URL=http://localhost:5000 in the settings file claude code will use or removes it. Port can be adjusted as you like.

Note

Openrouter is not free if you change the models below e.g. to 4.6

License

MIT

Tested

  • Works on Linux (Ubuntu 25.04 (Plucky))

Windows user

  • Need to download jq and add it to PATH (or modify the script to the exe location)
  • Either use WSL or run the script with bash switch-model.sh
# Using https://github.com/kiyo-e/claude-code-proxy
# - Rename the file to .env and place in your project root
# - start: docker run -d -p 5000:3000 --env-file .env ghcr.io/kiyo-e/claude-code-proxy:latest
# Create your key at https://openrouter.ai/settings/keys
CLAUDE_CODE_PROXY_API_KEY=<your-openrouter-api-key>
ANTHROPIC_PROXY_BASE_URL=https://openrouter.ai/api/v1
REASONING_MODEL=z-ai/glm-4.5-air:free
COMPLETION_MODEL=z-ai/glm-4.5-air:free
REASONING_MAX_TOKENS=4096
COMPLETION_MAX_TOKENS=2048
REASONING_EFFORT=high
DEBUG=false
# Switch Claude code CLI between local proxy and no-proxy use
#
# Place this at your project root
# run `chmod +x switch-model.sh` and place the .env also there.
#
# Toggles between Claude supscription/token and local proxy to openrouter
#
#!/usr/bin/env bash
set -e
SETTINGS_DIR=".claude"
LOCAL_FILE="$SETTINGS_DIR/settings.local.json"
# Backup permissions from current local file (if present)
if [ -f "$LOCAL_FILE" ]; then
PERMISSIONS=$(jq '.permissions' "$LOCAL_FILE")
else
PERMISSIONS='{"allow":[],"deny":[],"ask":[]}'
fi
# Detect current mode
detect_mode() {
if [ -f "$LOCAL_FILE" ] && jq -e '.env.ANTHROPIC_BASE_URL == "http://localhost:5000"' "$LOCAL_FILE" >/dev/null; then
echo "glm"
else
echo "claude_sub"
fi
}
# Switch functions
switch_glm() {
echo "πŸ”„ Switching to GLM via local proxy..."
jq -n \
--argjson perms "$PERMISSIONS" \
'{
env: {
ANTHROPIC_BASE_URL: "http://localhost:5000"
},
permissions: $perms
}' > "$LOCAL_FILE"
echo "βœ… Switched to GLM (via local proxy at http://localhost:5000)"
}
switch_claude_sub() {
echo "πŸ”„ Switching to Claude Subscription mode..."
jq -n \
--argjson perms "$PERMISSIONS" \
'{ permissions: $perms }' > "$LOCAL_FILE"
echo "βœ… Switched to Claude Subscription"
}
# Handle args
case "$1" in
glm) switch_glm ;;
claude_sub) switch_claude_sub ;;
status)
echo "πŸ“Œ Current mode:"
detect_mode
jq '.env // {}' "$LOCAL_FILE"
exit 0
;;
"" )
CURRENT=$(detect_mode)
if [ "$CURRENT" = "glm" ]; then
switch_claude_sub
else
switch_glm
fi
;;
*)
echo "Usage: $0 {glm|claude_sub|status}"
exit 1
;;
esac
@AWolf81
Copy link
Author

AWolf81 commented Oct 4, 2025

Note
The last version that is probably supporting this is 1.0.127 until it is fixed - The recent change to 2.x is a problem. Probably settings.local.json or the env handling changed.

Also /status is missing in 2.0.5, so it is hard to test if model selection via our base is working.

Couldn't get it back to work yet. Also pinning the VS Code version was not working for me.
I need to check that again.

I've seen the version topic in issue Claude code #8522

I also have to check the toggeling again and if it is enough to open/close Claude Code extension.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment