ccglass: a logging proxy that intercepts the plain HTTP hop instead of TLS
See what your coding agent (Claude Code, Codex, Kimi) sends to the model — local proxy + web dashboard
At a glance
- What is it?
- A local reverse proxy and dashboard that shows exactly what a coding agent sends to a model, without a certificate authority and without TLS interception. One provider in the list still needs both, and one authentication mode produces a silently empty dashboard.
- Who is it for?
- ccglass fits somebody who suspects a coding agent is sending something they did not expect, because the dashboard shows the full system prompt, every tool schema and a turn-to-turn diff, and the interception method means no certificate work on the host. Skip it if your agent authenticates with a ChatGPT login rather than an API key, or if you want to see Cursor's subscription traffic, since both bypass the proxy by design.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 88 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One install command, then a menu of seven clients
ccglass installs the way other developer CLIs do, from npm or a Homebrew tap, and then you run a single command with no arguments:
npm install -g ccglass # or: brew install jianshuo/tap/ccglass
ccglassWith no arguments it asks which client to inspect and shows a numbered list: Claude Code, Codex from OpenAI, DeepSeek-TUI, Reasonix, Kimi through Claude Code, OpenCode, and CodeBuddy from Tencent. Or you name it directly on the command line, with short aliases like `ccglass claude`, `ccglass codex`, `ccglass deepseek-tui`, `ccglass dsnix` and `ccglass kimi`.
What happens next is the whole point. ccglass starts a proxy, sets the environment variable that the chosen client reads for its base URL, launches that client for you, and opens a dashboard where every request appears in real time: the full system prompt, every tool schema, the message history, token and cache and cost numbers, and a diff between turns.
The dashboard binds to loopback on an ephemeral port, so two instances do not collide and nothing is exposed beyond your machine.
It intercepts the plain HTTP hop, not the TLS connection
The design decision that makes this work without a certificate authority is stated plainly in the project's own reasoning, and it is the reason to prefer this over a packet interceptor.
These command line agents are Node or native applications that ignore `HTTP_PROXY` and `HTTPS_PROXY`. A desktop proxy such as Charles or mitmproxy never sees their traffic, and tools that patch the fetch function break again with every client update. ccglass avoids both problems by inverting the arrangement: the client still performs the TLS handshake with the real API, and only the plain HTTP request to localhost on the way out is intercepted.
So there is no certificate to install, no root authority to trust, and no TLS pinning to defeat. The consequence worth understanding is that the payload is readable because the client has already decrypted it, not because the proxy broke the encryption.
There is one exception, and the table flags it. CodeBuddy's built-in models hardcode their upstream URL, so there is no environment variable to redirect, and that provider runs in a forward-proxy mode with HTTP CONNECT plus TLS man-in-the-middle. For that client alone, the certificate story comes back.
ChatGPT login makes the Codex dashboard silently empty
The provider notes contain the failure mode that will otherwise waste your afternoon.
Codex traffic is captured only when Codex is in API-key mode, driven by an environment variable holding an API key. If Codex is instead authenticated through a ChatGPT login, it uses a WebSocket transport to a chat endpoint that bypasses the base URL variable entirely. Nothing in ccglass errors out in that case; the dashboard simply stays empty, because the requests never touch the proxy.
The documented check is `codex doctor`, which prints the current authentication mode. If it reports a ChatGPT mode, you have to switch the client to API-key mode before ccglass can see anything.
That is the shape of the problem across the whole provider list. Several entries depend on a variable being set before the client starts, and the wrong state produces silence rather than an error message. Kimi expects an auth token pointing at the Moonshot endpoint, DeepSeek and Reasonix expect their key variable, Ollama and LM Studio expect no key at all, and OpenRouter expects its key in the same variable OpenAI-compatible clients use.
Reading those notes before you start is more effective than debugging an empty dashboard afterwards.
Bedrock fails through the proxy, and the tool warns you
Two cloud providers behave differently enough to be worth their own section.
For AWS Bedrock, Claude Code in Bedrock mode does not read the usual Anthropic base URL variable. It reads a separate Bedrock endpoint variable, so setting the Anthropic one has no effect and ccglass would sit there intercepting nothing. Even with the right variable set, direct AWS endpoints fail through the proxy, and the reason is specific: the AWS signing process signs the Host header, and a proxy rewrites it. ccglass detects that situation and prints a warning.
What does work is a Bedrock-compatible gateway using bearer or mutual TLS authentication, because those sign differently.
For Google Vertex AI the model is simpler: set the Anthropic base URL variable to the Vertex endpoint before launching, and the cloud credentials are forwarded as they are. The GLM and Zhipu route is the same idea, pointing the OpenAI base URL at the vendor endpoint and the key in the usual variable.
One more client-specific wrinkle: OpenCode auto-detects its upstream from the OpenAI base URL, but if its provider uses a differently named variable you have to tell ccglass which name to set.
The generic escape hatch takes any base URL variable and any command
When none of the named providers fit, there is a general form that works for any tool which reads a base URL from the environment. You give it an upstream address, the name of the environment variable to set, and the command to launch after a double dash.
ccglass run \
--upstream https://my.custom.api/v1 \
--env-var MY_CUSTOM_BASE_URL \
-- my-tool [args...]There is a shorter spelling where the upstream goes in a base URL flag instead, and a third form that borrows the request format of an existing provider while pointing the upstream somewhere else, which is the one to reach for when a vendor speaks an OpenAI-compatible dialect at an address nobody has written a provider entry for.
That structure is the whole extensibility story. There is no plugin system and no provider registry file; a new target is a command line invocation. For an ecosystem where vendors add new compatible endpoints regularly, that is a reasonable trade, since the alternative is a provider table that needs a release for every new service.
The proxy subcommand starts no child process, which is how IDEs use it
IDE extensions that let you configure a custom API base URL are handled by a separate subcommand. `ccglass proxy --provider openai` or `--provider claude` starts the proxy and the dashboard without spawning any child process, then prints the address for the IDE to point at and a separate address for the dashboard, both on loopback.
Separating the two roles is what makes it usable for an IDE. Every other mode is a wrapper that launches the client for you, which is convenient for a terminal and wrong for an editor you already have running.
The limitation is stated just as clearly. This works only when the extension is configured to use your own API key with a custom base URL, the bring-your-own-key mode. Cursor's built-in subscription models route through Cursor's own backend host and cannot be intercepted this way, so with a subscription login the IDE support simply will not show traffic.
That is the same failure shape as the ChatGPT-login case with Codex: a different authentication path, a different transport, and no error from the tool because nothing it can see failed.
Three dependencies, the node test runner, and releases cut by hand
The package metadata is small enough to describe the project in full. It is an ES module with a single binary, requires Node 18 or newer, and depends on three packages: the MCP SDK, a process-spawning helper and a schema validator. The published file list is the binary directory, the source directory, the web dashboard directory and the README, which is a sensible split for a tool whose UI is static assets served locally.
Testing uses the test runner built into Node, with no framework dependency, and the same command runs as a prepublish hook, so a publish is blocked by a failing test.
The release scripts are the detail worth noting. Rather than a continuous integration workflow that tags and publishes, they are three local commands that bump the version and push tags: patch, minor and major. Releases are therefore cut by the maintainer on a laptop, and the repository has no GitHub releases to match them. The package version in the metadata is the only version history, and a changelog file sits in the repository for the details.
With a last push in July and a small number of open issues, the shape is a focused tool maintained by one person, where the provider table and the auth-mode caveats are effectively the manual.
Editorial conclusion
ccglass fits somebody who suspects a coding agent is sending something they did not expect, because the dashboard shows the full system prompt, every tool schema and a turn-to-turn diff, and the interception method means no certificate work on the host. Skip it if your agent authenticates with a ChatGPT login rather than an API key, or if you want to see Cursor's subscription traffic, since both bypass the proxy by design. Before you point it at a real key, check which auth mode your client is in and read the dashboard with a throwaway credential first.
Frequently asked questions
How do I install and start ccglass?
Install it globally with npm install -g ccglass or from the maintainer's Homebrew tap, then run ccglass with no arguments and pick your client from the menu, or name it directly such as ccglass claude or ccglass codex.
Does ccglass need to install a certificate to see my traffic?
No for most clients. It points the agent at a local base URL so only the plain HTTP hop is intercepted while the client still speaks TLS to the real API. CodeBuddy is the exception, since its upstream URL is hardcoded and that provider uses a forward proxy with TLS interception.
Why is the ccglass dashboard empty for Codex?
Codex is only captured in API-key mode. With a ChatGPT login it uses a WebSocket transport that bypasses the base URL variable, so requests never reach the proxy. Run codex doctor to check which auth mode is active.
Can ccglass inspect an IDE extension such as Cursor or Cline?
Yes, with the proxy subcommand, which starts the proxy and dashboard without launching a client process. It only works when the extension uses your own API key with a custom base URL; Cursor's subscription models go through Cursor's own backend and cannot be intercepted.
What does ccglass need to work with an unfamiliar API provider?
Any tool that reads a base URL from the environment, via the run subcommand: give it an upstream address, the environment variable name to set, and the command to launch after a double dash. You can also borrow an existing provider's request format with --provider.
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/jianshuo-ccglass)