cc-proxy-plugin CLAUDE.md

Project instructions for maintaining cc-proxy, a local HTTP proxy that routes Claude Code requests to different AI model providers.

In plain words
What is it for?
Use them when modifying cc-proxy, especially its request forwarding, providers, tests, or operational documentation.
Why use it?
They document the proxy’s architecture, operating rules, tests, provider-specific checks, and related files so changes do not break its routing behaviour.

Instructions file

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add instructions/betmoar/cc-proxy-plugin/claude-md
Clone the repo
git clone --depth 1 https://github.com/betmoar/cc-proxy-plugin
Per session 5,296 This file is loaded in full into every session.
When invoked 5,296 The same file — it is already loaded in full.
Security scan B 1 finding. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.05296 $0.05296
Opus 5 $0.02648 $0.02648
Sonnet 5 $0.01059 $0.01059
Haiku 4.5 $0.00530 $0.00530

Measured 2d ago against content hash 7459a651c238, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade B, and why

cc-proxy-plugin CLAUDE.md scanned grade B with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 2d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Reads agent configuration directoriesmediumAgent snooping

.claude/, .codex/, .gemini/ hold keys, settings and other credentials a mod has no legitimate need for.

| 7 | `skills/setup/SKILL.md` | corrupts the user's `~/.claude/settings.json` |
CLAUDE.md · 288 lines

How it starts

The opening of the file, as written. The whole thing — 288 lines — stays where its author put it; the contents beside it link to each section on GitHub.

cc-proxy — maintainer handoff

A local HTTP proxy that lets Claude Code use GLM (Z.ai), OpenRouter, DeepSeek, Qwen, LM Studio (self-hosted, lmstudio:-selector-only), and Claude in one session. Claude Code points ANTHROPIC_BASE_URL at it; the proxy routes each request by model name and forwards. That's the whole product. Resist making it more than that.

Read next: docs/ARCHITECTURE.md (design + why), docs/OPERATIONS.md (runtime facts, debugging), docs/BACKLOG.md (open work + why past decisions went the way they did — probe matrices, measurements, refuted alternatives), CONTRIBUTING.md (add-a-provider procedure).

Gates

pnpm check (= pnpm lint && pnpm test) before any commit; CI runs the same. The suite spins real local HTTP backends — if you change forwarding and no test fails, you haven't tested it; add one.

pnpm probe:vendors is the MANUAL gate for claims about someone else's server. It is never in pnpm check (real keys, real quota) and exits 1 when a vendor stops behaving the way a source comment says it does. Run it when you touch routing/forwarding, or when a probe date in a comment looks old.

Invariants (breaking one is a design decision, not a refactor)

Each is locked by tests; the test names tell you what you broke.

  1. Transparent pipe. Auth/headers only. Full inbound path including the query string reaches upstream; bodies forwarded byte-for-byte. THREE body exceptions (thinking-strip, <provider>: selector-strip, [1m] variant- suffix strip) and TWO header exceptions (hop-by-hop dropped — CL+TE together trips smuggling rejection; and the upstream's own x-request-id dropped from every forwarded response, 0.8.0 — writeHead REPLACES what setHeader put there, so a vendor that emits one took over the proxy's correlation id). The third body strip was added in 0.6.3 on a measurement, not a preference: both Z.ai and the Qwen plan 400 on a suffixed id, so forwarding CC's display spelling means routing correctly and then failing at the vendor. All three strips share one shape — a spelling the CLIENT uses that no BACKEND knows. → server.test.js "query string is preserved…", "provider selector strip…", "routing log annotates the normalized id…", "keeps the proxy's x-request-id when the upstream sets its own…" (and its two size-cap passthrough siblings — each writeHead is a separate chance to leak the vendor's id)
  2. Stateless. No breakers, no on-disk state, no in-proxy waiting. Rate limits inject Retry-After and let the client back off. → "…1302 … gets a Retry-After", "1313 … no Retry-After"
  3. Credential isolation. Inbound Authorization/x-api-key never reach a third party; the Claude route passes them through (OAuth). Never set ANTHROPIC_API_KEY in settings templates — it shadows OAuth. → providers.test.js "…drops an inbound x-api-key…"
  4. claude-haiku-* pins to Claude so internal ops never burn paid quota. The pin tests the STRIPPED tail — pinning the raw id lets glm:claude-haiku-… skip it. → router.test.js
  5. Anthropic Messages only. No OpenAI↔Anthropic translation layer, ever. The media tunnel (POST /api/v1/services/aigc/multimodal-generation/generation, 0.7.0) is NOT an exception and must not become one: it forwards a DashScope-shaped body byte-for-byte to a DashScope endpoint and returns the vendor's own response. The proxy knows neither schema; it adds the credential. An /v1/images/generations in front of every backend that can draw — the version of this that WOULD argue with the invariant — was declined. → models.test.js "media generation tunnel (issue #40)"
  6. Client abort propagates upstream, or a cancelled turn bills into a dead socket. → "client abort mid-stream aborts the upstream request"
  7. Loopback bind by default. PROXY_HOST is the explicit opt-out. → config.test.js

Read the full file on GitHub · 288 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 2d ago First seen · 288 lines · 5,296 tokens per session scan B 7459a651c238

Subscribe to this mod's changes

cc-proxy-plugin CLAUDE.md is an instructions file published in the GitHub repository betmoar/cc-proxy-plugin (2 stars, last pushed 2d ago), licensed MIT. It adds 5,296 tokens to every session, about $0.0265 per session on Opus 5. A static security scan graded it B with 1 finding (reads agent configuration directories). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.