cc-gateway
A local multi-provider gateway that impersonates the Anthropic Messages API for Claude Code, so you can switch between models from different backends at any point in any session.
It forwards the Anthropic dialect only. Every backend must expose an Anthropic-compatible endpoint; there is deliberately no OpenAI translation layer.
Providers
| provider | endpoint | auth |
|---|---|---|
coconut |
http://127.0.0.1:8787 (local daemon) |
Bearer coconut |
glm |
https://open.bigmodel.cn/api/anthropic |
x-api-key, $GLM_API_KEY |
mimo |
https://token-plan-cn.xiaomimimo.com/anthropic |
x-api-key, $MIMO_API_KEY |
Install
Requires Python 3.11+ (tomllib is stdlib there).
uv tool install ccgw
# or
pipx install ccgw
Run
The gateway reads its provider registry from a config.toml, looked up in
this order: $CCGW_CONFIG, ./config.toml, ~/.config/ccgw/config.toml.
export GLM_API_KEY=... # never stored in this repo
export MIMO_API_KEY=...
ccgw # listens on 127.0.0.1:8788
ccgw --port 9000 # or --config /path/to/config.toml
A source checkout can run the same entry point directly:
pip install -r requirements.txt
python serve.py
Point Claude Code at it in ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:8788",
"ANTHROPIC_AUTH_TOKEN": "ccgw",
"ANTHROPIC_API_KEY": "",
"CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY": "1"
}
}
Do not set ANTHROPIC_DEFAULT_*_MODEL or ANTHROPIC_SMALL_FAST_MODEL:
the gateway serves every model from one catalogue, and pinning those variables
would route background traffic around the router.
Model naming
Public ids are generated as claude-<provider>-<slug> plus a [1m] suffix for
models with a 1M context window. Both parts are load-bearing:
- Claude Code's gateway discovery drops any id that does not contain
claudeoranthropic, so the prefix is mandatory for a model to appear in/model. - Claude Code infers a 1M window from a
[1m]substring, which is how the gateway communicates window size./v1/modelscannot carry it: Claude Code's parser keeps onlyidanddisplay_name.
The suffix is presentation only. It is stripped before the request goes
upstream, because neither GLM nor MiMo accepts a [1m] model name on these
endpoints (both reject it outright), even though their Coding Plan docs
describe the suffix.
Behaviour worth knowing
History sanitisation. Every request has thinking and redacted_thinking
blocks stripped from the history, unconditionally. Thinking signatures are
bound to the model and credentials that produced them, and Claude Code replays
the full history verbatim when you switch models, so a stale signature is a 400
that can wedge a session permanently. Stripping is stateless, matches
Anthropic's own guidance for switching models, and is a no-op for backends that
ignore thinking anyway. The top-level thinking parameter is removed in
lockstep, since removing the blocks alone is itself a 400.
Tool repair. Tool ids are normalised to ^[a-zA-Z0-9_-]+$ and dangling
tool_use blocks get a synthetic error result, both of which are otherwise
400s after an interrupted turn.
Errors. Upstream failures are re-shaped into the Anthropic envelope but the upstream message text is preserved verbatim, because Claude Code matches on it to drive automatic capability downgrade and retry.
Streaming. Upstream bytes are relayed unbuffered, with a ping injected
every 15 seconds of silence to stay under Claude Code's 300 second stream
watchdog.
Token counting. /v1/messages/count_tokens is answered locally and never
proxied; coconut does not implement it, and Claude Code falls back to its own
estimate anyway.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ccgw-0.1.0.tar.gz.
File metadata
- Download URL: ccgw-0.1.0.tar.gz
- Upload date:
- Size: 15.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa0938564ce73bb940533f274b103059157f3fa839fdc79f9e9b84af8261580a
|
|
| MD5 |
5a38bf4c567e46dccfc2c54d5e75c1f5
|
|
| BLAKE2b-256 |
3a4a6bc69164a3c52504de83030a24248e254f0abf20b31002674cf3baf63768
|
Provenance
The following attestation bundles were made for ccgw-0.1.0.tar.gz:
Publisher:
publish.yml on XuNeo/ccgw
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ccgw-0.1.0.tar.gz -
Subject digest:
fa0938564ce73bb940533f274b103059157f3fa839fdc79f9e9b84af8261580a - Sigstore transparency entry: 2624543454
- Sigstore integration time:
-
Permalink:
XuNeo/ccgw@29d7ee1aeb8274680c3171a3d586acc377bbaa80 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/XuNeo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@29d7ee1aeb8274680c3171a3d586acc377bbaa80 -
Trigger Event:
push
-
Statement type:
File details
Details for the file ccgw-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ccgw-0.1.0-py3-none-any.whl
- Upload date:
- Size: 17.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
901adf0c385e9783e8f725294b0a289f5d30cd77e604b64dabad1c82510aebd7
|
|
| MD5 |
84f426e1a1e81b7d0932258902dd4085
|
|
| BLAKE2b-256 |
89e2cdecabf9d71d478fc128ad8de7913e6dee7e752f9357df100ccd0a7d0bdf
|
Provenance
The following attestation bundles were made for ccgw-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on XuNeo/ccgw
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ccgw-0.1.0-py3-none-any.whl -
Subject digest:
901adf0c385e9783e8f725294b0a289f5d30cd77e604b64dabad1c82510aebd7 - Sigstore transparency entry: 2624543463
- Sigstore integration time:
-
Permalink:
XuNeo/ccgw@29d7ee1aeb8274680c3171a3d586acc377bbaa80 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/XuNeo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@29d7ee1aeb8274680c3171a3d586acc377bbaa80 -
Trigger Event:
push
-
Statement type: