ccproxy intercepts your own LLM traffic and rewrites it between providers
Build mods for Claude Code: Hook any request, modify any response, /model "with-your-custom-model", intelligent model routing using your logic or ours
At a glance
- What is it?
- A mitmproxy and WireGuard based interceptor for LLM clients, originally built for Claude Code and now working with anything that speaks HTTP. It runs a fixed twelve stage addon chain, and its namespace jail needs Linux kernel features that macOS does not have.
- Who is it for?
- Reach for ccproxy if you need to see and reshape the requests your own LLM client sends, want one endpoint in front of several providers, or need MCP features a given client does not implement. Do not reach for it expecting a packaged Windows or Android proxy application, since the name collides with unrelated software, and do not plan on `ccproxy run --capture` outside Linux or WSL2.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 63 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Two listeners, and macOS only gets one of them
Traffic enters through one of two listeners, and which ones you can use depends on the kernel underneath. The reverse proxy listens on port 4000 and works on Linux, on Windows under WSL2, and on macOS. The WireGuard namespace jail, which is what `ccproxy run --capture` uses, works on Linux and WSL2 and does not work on macOS. The reason given is specific rather than a general portability complaint: the jail needs unprivileged user and network namespaces, `slirp4netns`, and `iptables` NAT, none of which has a macOS equivalent. macOS is not left broken. `ccproxy start` plus SDK use against `ANTHROPIC_BASE_URL=http://localhost:4000` behave the same there, and no system packages are required. The failure mode is chosen on purpose too: `ccproxy run --capture` fails fast with an error listing the missing Linux-only tools instead of starting and behaving strangely.
Ubuntu 24.04 AppArmor blocks the jail before ccproxy starts
The Linux path has a prerequisite that bites on current Ubuntu. The jail needs a small set of tools on `PATH`: `slirp4netns`, `wireguard-tools` for `wg`, `iproute2` for `ip`, `iptables`, `util-linux` for `unshare` and `nsenter`, and `procps` for `sysctl`. Install commands are given for Debian and Ubuntu, Fedora and Arch, with NixOS covered through the project devShell. Then there is the AppArmor problem. On Ubuntu 24.04 and newer, unprivileged user namespaces are restricted by default, which is exactly what the jail is built on. The documented fix is a one-off:
sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0or a path-scoped AppArmor profile, if you would rather not relax the restriction system wide. Expect to hit this before anything else that the jail does.
The addon chain is twelve stages in a fixed order
Once traffic is inside, it passes through a fixed sequence: ReadySignal, InspectorAddon, FingerprintCaptureAddon, MultiHARSaver, ShapeCaptureAddon, then the inbound DAG, the transform stage, then the outbound DAG, then TransportOverrideAddon, AuthAddon, GeminiAddon, PerplexityAddon and EgressSanitizerAddon. The order is fixed rather than configurable. Two observers sit early, InspectorAddon and FingerprintCaptureAddon, with a HAR saver behind them, so capture happens before anything rewrites a body. The two DAG hook sets bracket the transform, which is what gives the pipeline its shape: a hook can run on the way in and another on the way out, with conversion happening in between.
The hooks are the extension point for building mods. Three capabilities are named: routing or transforming requests between Anthropic, Gemini, OpenAI, DeepSeek, Perplexity Pro and Anthropic-compatible forks; compliance shaping, which replays packaged sanitized SDK compliance envelopes for built-in providers while injecting your actual request content at runtime; and MCP bridging, which adds sampling to any client via sentinel key detection, bridges server notifications into the LLM context through a `/mcp` endpoint, and carries experimental tasks support.
AuthAddon and GeminiAddon sit after the outbound pipeline
Two addons are deliberately placed downstream, and the stated reason is visibility: they need to see requests and responses as ccproxy finalised them, not as they arrived. Each owns a specific failure mode rather than a general concern. AuthAddon handles 401 detect, then refresh, then replay, which is the loop you want when a credential expires partway through a session instead of a hard failure. GeminiAddon owns capacity fallback with a sticky retry and a fallback chain on 429 or 503, plus unwrapping of the cloudcode-pa envelope. PerplexityAddon follows, and EgressSanitizerAddon closes the chain, so provider specific work happens on traffic that has already been shaped and converted. In 2.0 that arrangement carries the Codex and OpenAI Responses support with packaged request shaping, and DeepSeek V4 routing for Anthropic-format requests through DeepSeek's `/anthropic/v1/messages` endpoint.
lightllm replaces a LiteLLM subprocess, and splits the conversion work
Cross-provider body conversion belongs to `lightllm`, described as a surgical adapter and streaming FSM layer inside ccproxy. Two things follow from that. There is no LiteLLM proxy subprocess and no gateway server, so no second process sits between you and the provider. And the responsibilities are split rather than merged: `lightllm` owns wire-format conversion for request and response bodies, while URL rewriting and auth injection are owned by the inspector route and the `Provider` configuration. Streaming is handled by finite state machines rather than by buffering a whole response, so a stream can be converted as it arrives. LiteLLM itself is not a runtime dependency, even though `ccproxy init` still writes a sibling `config.yaml` in a LiteLLM-compatible shape, and those model declarations are compiled rather than resolved at startup.
ccproxy init writes two YAML files, and exit 3 means nothing is running
`ccproxy init` writes two files rather than one: `ccproxy.yaml` and a LiteLLM-compatible `config.yaml`. `ccproxy start` then brings up the proxy and inspector stack in the foreground. Using an SDK is a matter of pointing it at the listener:
export ANTHROPIC_BASE_URL=http://localhost:4000
claude -p "hello"Transparent capture wraps a command in the namespace jail instead, so every packet it sends is intercepted:
ccproxy run --capture -- claude -p "hello"The verify step has a documented exit code, which is unusual enough to be worth copying exactly:
ccproxy --help
ccproxy init
ccproxy status --proxy --inspect # exit 3 = both down (expected, nothing running yet)Exit 3 on a fresh machine is the expected result, not something to debug.
The distribution is ai-ccproxy, the licence is AGPL, the branch is dev
Three packaging facts are worth checking before you install anything. The distribution name is `ai-ccproxy`, not `ccproxy`, which is why both `uv tool install ai-ccproxy` and `pip install ai-ccproxy` are the documented commands while the command you then run is `ccproxy`:
uv tool install ai-ccproxy
# or
pip install ai-ccproxyThe licence declared in pyproject.toml is `AGPL-3.0-or-later`, while the repository's own licence field reads as no assertion, so the pyproject text is the one to rely on. And the default branch is `dev`, not `main`, which matters if you pin a revision. Python 3.13 or newer is required.
Windows support is tiered rather than conditional, which is worth reading before you install. On Windows the recommended install is the `ccproxy.wsl` distro artifact built on NixOS-WSL rather than a package manager, and it needs Store WSL 2.4.4 or newer. Tier 1 is Windows 11 22H2 or later with Store-distributed WSL2, systemd enabled, and mirrored networking recommended. Windows 10 and older WSL networking are described as best-effort, while WSL1 and native Windows without WSL are unsupported. Advanced users can still run Ubuntu on WSL2 with systemd and Nix, but the release artifact is called out as the primary out-of-box path.
mypy and ty both run, and observability is an optional extra
Two things about the project's own tooling are unusual. Type checking runs twice with different checkers, `uv run mypy src/ccproxy tests --no-incremental` alongside `uv run ty check src tests --output-format concise`, wired into a single recipe. And observability is entirely optional, split across extras: an `otel` extra carrying the OpenTelemetry API, SDK, OTLP proto gRPC exporter and semantic conventions, a `journal` extra pulling `systemd-python`, and an `sdk` extra for `google-genai` and `openai`. The repository ships a `docker-compose.yaml` running Jaeger in all-in-one mode for trace viewing, bound to 127.0.0.1 on 4317, 4318 and 16686 with in-memory span storage, plus a `.env.example` holding LangFuse keys. End-to-end tests are credential-gated and self-skip when credentials or a running proxy are absent.
Editorial conclusion
Reach for ccproxy if you need to see and reshape the requests your own LLM client sends, want one endpoint in front of several providers, or need MCP features a given client does not implement. Do not reach for it expecting a packaged Windows or Android proxy application, since the name collides with unrelated software, and do not plan on `ccproxy run --capture` outside Linux or WSL2. Four things to check first. That you have Python 3.13 or newer and install the distribution named `ai-ccproxy`, since that is the name pip and uv know, while `ccproxy` is the command it gives you. That your distribution carries AGPL-3.0-or-later, which is what pyproject declares. That on Ubuntu 24.04 or newer you address the AppArmor restriction on unprivileged user namespaces before the jail will start. And that you pin a revision deliberately, because the default branch is `dev`. Releases are v1.2.0 from December 2025 and v2.0.0-rc1 from April 2026, with no newer tag, and the last push to the default branch is dated 10 August 2026.
Frequently asked questions
What is ccproxy and what does it intercept?
It is a transparent network interceptor for LLM tooling, built on mitmproxy and WireGuard with full TLS inspection. Traffic enters through a reverse proxy on port 4000 or through a WireGuard namespace jail, passes a fixed addon chain, and exits directly to the provider API. It was purpose-built for Claude Code but works with any client that speaks HTTP.
Does ccproxy work on macOS?
Only the reverse proxy does. `ccproxy start` and SDK use against ANTHROPIC_BASE_URL=http://localhost:4000 work the same as on Linux with no system packages needed. `ccproxy run --capture` does not, because the namespace jail needs Linux kernel features with no macOS equivalent, and it fails fast listing the missing tools.
How do I install ccproxy on Linux?
Install the system tools the jail needs (slirp4netns, wireguard-tools, iproute2, iptables, util-linux, procps), then install the distribution with uv tool install ai-ccproxy or pip install ai-ccproxy. On Ubuntu 24.04 and newer you also need to address the AppArmor restriction on unprivileged user namespaces.
What does ccproxy run --capture do that ccproxy start does not?
`ccproxy start` brings up the proxy and inspector stack, and clients connect to it deliberately, for example through ANTHROPIC_BASE_URL=http://localhost:4000. `ccproxy run --capture` instead runs a command inside a rootless WireGuard namespace so that all of its traffic is intercepted without the client being configured.
What licence is ccproxy released under, and which Python does it need?
pyproject.toml declares AGPL-3.0-or-later, though the repository's own licence field reads as no assertion. It requires Python 3.13 or newer, is published as the distribution name ai-ccproxy, and its default branch is dev rather than main.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/starbaser-ccproxy)