Skip to main content

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 claude or anthropic, 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/models cannot carry it: Claude Code's parser keeps only id and display_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

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ccgw-0.1.0.tar.gz (15.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ccgw-0.1.0-py3-none-any.whl (17.2 kB view details)

Uploaded Python 3

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

Hashes for ccgw-0.1.0.tar.gz
Algorithm Hash digest
SHA256 fa0938564ce73bb940533f274b103059157f3fa839fdc79f9e9b84af8261580a
MD5 5a38bf4c567e46dccfc2c54d5e75c1f5
BLAKE2b-256 3a4a6bc69164a3c52504de83030a24248e254f0abf20b31002674cf3baf63768

See more details on using hashes here.

Provenance

The following attestation bundles were made for ccgw-0.1.0.tar.gz:

Publisher: publish.yml on XuNeo/ccgw

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for ccgw-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 901adf0c385e9783e8f725294b0a289f5d30cd77e604b64dabad1c82510aebd7
MD5 84f426e1a1e81b7d0932258902dd4085
BLAKE2b-256 89e2cdecabf9d71d478fc128ad8de7913e6dee7e752f9357df100ccd0a7d0bdf

See more details on using hashes here.

Provenance

The following attestation bundles were made for ccgw-0.1.0-py3-none-any.whl:

Publisher: publish.yml on XuNeo/ccgw

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page