Metadata-Version: 2.4
Name: cc-startup-audit
Version: 0.2.0
Summary: Audit what Claude Code loads into context before you type a word.
Project-URL: Homepage, https://github.com/Ankit3794/claude-code-startup-audit
Project-URL: Issues, https://github.com/Ankit3794/claude-code-startup-audit/issues
Author: The System Prompt
License: MIT License
        
        Copyright (c) 2026 Ankit Patel
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: claude,claude-code,context-window,cost,llm,tokens
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: Utilities
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# claude-code-startup-audit

[![CI](https://github.com/Ankit3794/claude-code-startup-audit/actions/workflows/ci.yml/badge.svg)](https://github.com/Ankit3794/claude-code-startup-audit/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/cc-startup-audit?color=E8A33D)](https://pypi.org/project/cc-startup-audit/)
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-3DE887)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/license-MIT-E8A33D)](LICENSE)
[![Dependencies: none](https://img.shields.io/badge/dependencies-none-3DE887)](pyproject.toml)

**What did Claude Code load into your context before you typed a word?**

Claude Code already records the answer. Every API response's `usage` object is
appended to a JSONL file under `~/.claude/projects/`. This reads those files and
tells you what the first request of every session actually cost.

No dependencies. No network. Nothing leaves your machine.

```bash
uvx cc-startup-audit
```

```
  BEFORE YOU TYPE A WORD
  45 sessions · 36 cold starts · 12 projects · Claude Code 2.1.206-2.1.220

    cheapest cold start      22,638 tokens
    median cold start        35,367 tokens   18% of a 200K window
    worst cold start        131,314 tokens   66% of a 200K window · 5.8x the floor

    paid to say hello     $   12.94   across 45 first requests, list price

  TOOL DEFERRAL   same machine, same account
    active   n=31  median   34,175
    absent   n=5   median   71,785   2.10x
```

Then open the full breakdown in a browser:

```bash
uvx cc-startup-audit --serve
```

![The HTML report: headline numbers, cold-start anatomy, tool-deferral split, and a project grid that drills down to individual sessions.](docs/report.png)

Three levels. Overview, click a project for its sessions, click a session for
the component breakdown and the raw `usage` object behind it.

---

## Why not `/context`

`/context` estimates client-side, before anything is sent. When MCP servers are
loaded it sums per-tool `count_tokens` calls and double-charges the shared
schema. Cameron Cooke replicated the counting logic and measured **45,018
reported against 15,282 real** —
[async-let.com](https://www.async-let.com/posts/claude-code-mcp-token-reporting/).

This tool never reads `/context`. Every headline number is the `usage` object
the API returned. It is the invoice, not the estimate.

---

## Install

```bash
uvx cc-startup-audit              # run once, install nothing
uv tool install cc-startup-audit  # or keep it on your PATH
pipx install cc-startup-audit
pip install cc-startup-audit
```

Requires Python 3.9 or newer and nothing else. Full instructions, including
Windows, WSL and headless machines, are in [INSTALL.md](INSTALL.md).

---

## Usage

```
cc-startup-audit                         summary in this terminal
cc-startup-audit --serve                 build the report and open it
cc-startup-audit --html report.html      write the report to a file
cc-startup-audit --anonymize --serve     safe to screenshot or stream
cc-startup-audit --probe-mcp             which MCP server costs you the most
cc-startup-audit --full                  every cold start, one per line
cc-startup-audit --json | jq .           machine-readable
cc-startup-audit --root /path/to/projects
```

### Sharing your numbers safely

`--anonymize` renames every project to `project-a`, `project-b`, deterministically
by sorted path, **before any output exists**. The key is printed to stderr only
and never enters the report. Numbers, shapes and per-session detail all survive.

```bash
cc-startup-audit --anonymize --serve 2>/dev/null
```

Safer than blurring a screen recording, because there is no frame to miss.

### `--serve`

Binds `127.0.0.1` on an unused port, holds the report in memory, and answers
exactly one path. No directory is exposed, nothing is written to disk. `--port`
to pin it, `--no-open` to skip launching a browser.

---

## What it measures

For each transcript, the first `assistant` record carrying a `usage` object,
excluding subagent sidechains. At that moment the only thing in the context
window is what Claude Code put there plus your opening message.

```
total = input_tokens + cache_creation_input_tokens + cache_read_input_tokens
```

A **cold start** has `cache_read_input_tokens == 0`. Warm starts are reported
separately, because a cache hit means part of the prefix was already paid for in
an earlier session.

### Three kinds of number, never blurred

| | Where it comes from | Shown as |
|---|---|---|
| **Totals** | measured — the API's own `usage` | solid, exact |
| **Components** | estimated — 4 chars/token over logged attachments | solid, labelled approximate |
| **System prompt + tool schemas** | inferred — total minus everything logged | **hatched**, never solid |

Claude Code logs the skill catalog, subagent listing, MCP instructions, deferred
tool index and auto-read files as typed attachments. It never logs the system
prompt or the tool schemas. That figure is recovered by subtraction: its size is
known, its composition is not.

On the machine this was built on it was consistently 74–93% of a cold start.

### Which MCP server is the problem

The residual tells you tool schemas are large. It cannot tell you *whose*.
`--probe-mcp` asks each configured server for its tool list over `tools/list`,
which returns the same JSON Claude Code forwards to the API, and counts it.

```
  MCP SERVERS   tool schemas, measured via tools/list
      14,090  ████████████████████████████  tokensave 81 tools ·  62% · user
       8,257  ████████████████············  firecrawl 27 tools ·  36% · project:site
         323  █···························  headroom  3 tools ·   1% · user

      22,670  total, across 3 server(s)
    that is 64% of a typical 35,367-token cold start, if none of it is deferred
```

This is measurement, not inference: the schemas are counted, not subtracted.
Names are counted as `mcp__server__tool`, the namespaced form the API receives.

**It is opt-in because it starts every configured server** as a subprocess or
opens a connection to it. Servers that need auth, or that are unreachable, are
listed with their error and contribute nothing. `--mcp-timeout` bounds each one.

### Tool deferral

Sessions are split on whether a `deferred_tools_delta` entry is present. When it
is missing, every tool schema loads upfront instead of on demand.

That was a **2.10× median difference** on the reference machine — 34,175 against
71,785 tokens, same account, same everyday work.

This is an observed association across your own history, not a randomised trial.
Treat it as a thing to go look at.

---

## Limitations

- **Component tokens are approximate.** Estimated at 4 characters per token to
  stay dependency-free. **Headline totals are exact.**
- **The residual cannot be broken down further** from the transcript alone.
- **Prices are Anthropic list rates** (August 2026). They ignore subscription
  plans, batch discounts and long-context surcharges. Treat cost as an order of
  magnitude, not an invoice.
- **Your numbers are yours.** They depend on your plugins, MCP servers, skills
  and memory files. The method transfers; the numbers do not.
- **New attachment types** appear as their own row rather than being dropped, so
  a Claude Code release cannot silently shrink your measured total.

---

## Privacy

Reads only `~/.claude/projects/**/*.jsonl`, and only the `usage` objects and
attachment sizes. It does not copy message content into any output, makes no
network requests, and writes nothing outside a path you name.

`--serve` binds loopback and serves a single in-memory document.

The whole thing is a few hundred lines of stdlib Python. Read it.

---

## Prior art

Worth reading, and worth crediting:

- **[Systima](https://systima.ai/blog/claude-code-vs-opencode-token-overhead)** —
  measured ~32,800 tokens of first-turn payload on Claude Code 2.1.207 with a
  logging proxy, against ~6,900 for OpenCode. Different method, same ballpark
  as this tool's median.
- **[ACDigest](https://acdigest.substack.com/p/most-of-your-claude-code-tokens-are)**
  — 90 days of full-payload HTTP logging; ~75% of input tokens were overhead.
- **[Async Let](https://www.async-let.com/posts/claude-code-mcp-token-reporting/)**
  — the `/context` over-counting analysis this tool exists to route around.
- **[Anthropic's context window docs](https://code.claude.com/docs/en/context-window)**
  — publishes a per-component startup table. It has no row for tool schemas.

The widely repeated figure of **16,063 tokens before you type** appears in none
of these, nor in the Claude Code changelog, nor in any issue we could locate.
If you find its origin, [open an issue](https://github.com/Ankit3794/claude-code-startup-audit/issues)
— it deserves a citation or a correction.

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). Measurement corrections are especially
welcome; this project makes numeric claims in public.

## License

MIT. See [LICENSE](LICENSE).
