deadweight
Your Claude Code setup charges rent. Some of it never shows up for work.
Every skill, subagent and MCP server you install gets loaded into context at the start of every single session — whether you use it or not. You pay for it in tokens, every time, forever.
Nothing tells you which ones you actually use.
$ deadweight
deadweight 62 sessions · /home/user/my-repo
DEAD WEIGHT loaded every session, never called
mcp server jira 11,412 chars (~2,853 tok) never used
mcp server Artlist 2,072 chars (~518 tok) never used
skill dataviz 1,447 chars (~361 tok) never used
agent data-migrator 1,097 chars (~274 tok) never used
skill legacy-deploy 340 chars (~85 tok) never used
… and 12 more
tools 197 of 201 never called 5,998 chars (~1,499 tok) names only; schemas load on demand
22,410 chars (~5,602 tokens) per session for nothing — 61% of the 36,500 you load
HOOKS wall-clock you pay on every run
Stop ~/.claude/stop-hook-git-check.sh 1,842 runs 4m 21s avg 142ms
PostToolUse ~/.claude/format.sh 611 runs 1m 02s avg 101ms
Then you delete what you never use, and get that context back.
There is nothing to install to find out:
git clone https://github.com/hjalti-hub/deadweight && cd deadweight
python3 -m deadweight
Zero dependencies. Nothing leaves your machine.
How it knows
Claude Code already writes down everything you need. Every session is logged to
~/.claude/projects/*/*.jsonl, and those files record two things nobody reads
together:
What got loaded. Each session's transcript stores the actual text of the
skill listing, the subagent listing, the MCP instruction blocks and the tool
roster. So the cost of each item is measured, not estimated — deadweight
counts the characters Claude Code actually put in your context.
What got used. Every tool_use block names the tool that ran. Skills name
themselves when invoked, subagents name themselves when spawned, and MCP tools
carry their server in the name (mcp__jira__create_issue).
Join those two and you get the only question that matters: what am I paying for that has never once done anything?
Privacy
This reads your session history, so it's worth being precise about what it touches.
It never reads message text. Not your prompts, not Claude's replies, not tool inputs, not file contents. The parser skips them entirely — it collects names, counts, character totals and durations, and nothing else. There's a test that asserts exactly this: parse a transcript containing secrets, then assert none of them survive anywhere in the result.
Nothing leaves your machine. No network calls, no telemetry, no API key. It's a local file reader.
Install
A clone is enough — run it as a module from inside the checkout:
git clone https://github.com/hjalti-hub/deadweight && cd deadweight
python3 -m deadweight
To run it from any directory, install it from that clone:
pip install . # or: pipx install .
Requires Python 3.9+.
On PyPI it is
claude-deadweight. PyPI does not allow the bare namedeadweight, sopip install claude-deadweightis what installs it. The command you type is stilldeadweight, and the import is stilldeadweight.
Use
Once installed you can drop the python3 -m prefix; from a clone, keep it.
deadweight # weigh every session on this machine
deadweight --project my-repo # only sessions from a matching directory
deadweight --since 30 # only the last 30 days
deadweight --used # also show what is earning its keep
deadweight --all # every row, not just the top ones
deadweight --json # machine-readable
--project accepts either separator, so my-repo and my/repo both work — the
on-disk encoding can't tell them apart.
What it measures
| MCP servers | Instruction block size per server, and calls resolved from mcp__server__tool names. Usually the biggest single win. |
| Skills | The description each one contributes to the skill listing, against how often it was invoked. |
| Subagents | Listing size against Task invocations by subagent_type. |
| Tools | The deferred roster. Cheap by design — names only, schemas load on demand — so these are collapsed into one row. |
| Hooks | Runs, total wall-clock, average duration and error count, from Claude Code's own hookInfos records. |
That last row is worth calling out. Hook cost is otherwise completely invisible: nothing fails, everything just gets slower, gradually. These are the durations Claude Code itself recorded.
Honest limits
- "Never used" is only as good as your history. In 3 sessions it means nothing; in 200 it means a lot. The report tells you which situation you're in and warns you below 5 sessions.
- It measures what the transcript records. MCP instruction blocks are measured exactly. An MCP server's tool schemas may cost more on top of that, and are not separately itemised.
- Deferred tools are already cheap. Claude Code lists them by name and loads schemas on demand, so 200 tools cost a few thousand characters, not hundreds of thousands. Don't go deleting tools expecting a windfall.
- Something rarely used may still be worth keeping. This tells you the price;
whether it's worth paying is your call. Sort by
cost_per_callin the JSON if you want the borderline cases. - Project names are lossy. Claude Code encodes the working directory with dashes, so a real dash and a path separator look identical. Project labels are for grouping, not for opening.
Library use
from deadweight.transcripts import load
from deadweight.analyze import build
report = build(load(since_days=90))
for item in report.dead:
print(item.kind, item.name, item.chars, "chars/session, never called")
Related
whyskill answers the other half of the same question. It reads your configuration and proves a skill can't fire — truncated descriptions, name collisions, shadowing. This one reads your history and shows what doesn't fire, and what that costs you.
Static proof, and empirical evidence.
Contributing
The transcript format isn't a published API, so the most useful contribution is a failing test with a real (redacted) transcript shape that this parser gets wrong.
python3 -m unittest discover -s tests -t .
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claude_deadweight-0.1.0.tar.gz.
File metadata
- Download URL: claude_deadweight-0.1.0.tar.gz
- Upload date:
- Size: 21.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4539f8305c4df7772deeacbf6c17039889b0f01faa1e153b92380e80310528b1
|
|
| MD5 |
0b096acb291f3eb1b332d3270643c792
|
|
| BLAKE2b-256 |
e8b719b728c05075a2d783b3f8ff585b67a578d1487dae569d162b72d13ec54e
|
Provenance
The following attestation bundles were made for claude_deadweight-0.1.0.tar.gz:
Publisher:
release.yml on hjalti-hub/deadweight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_deadweight-0.1.0.tar.gz -
Subject digest:
4539f8305c4df7772deeacbf6c17039889b0f01faa1e153b92380e80310528b1 - Sigstore transparency entry: 2742422248
- Sigstore integration time:
-
Permalink:
hjalti-hub/deadweight@c12cd28f83b431ed623335b8d127a5573eda8a13 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/hjalti-hub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c12cd28f83b431ed623335b8d127a5573eda8a13 -
Trigger Event:
push
-
Statement type:
File details
Details for the file claude_deadweight-0.1.0-py3-none-any.whl.
File metadata
- Download URL: claude_deadweight-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc9de9b5ddfa543f3613506af353cd1d23a4f53d6ee59c7f6b103472da1d6573
|
|
| MD5 |
065ecef16d7083554b0d5a6ad513307b
|
|
| BLAKE2b-256 |
073934c5de3c8d591aa66d34ca2ea0451c824b82c34ddc7f4d2b8c95073a80e9
|
Provenance
The following attestation bundles were made for claude_deadweight-0.1.0-py3-none-any.whl:
Publisher:
release.yml on hjalti-hub/deadweight
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_deadweight-0.1.0-py3-none-any.whl -
Subject digest:
cc9de9b5ddfa543f3613506af353cd1d23a4f53d6ee59c7f6b103472da1d6573 - Sigstore transparency entry: 2742422277
- Sigstore integration time:
-
Permalink:
hjalti-hub/deadweight@c12cd28f83b431ed623335b8d127a5573eda8a13 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/hjalti-hub
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c12cd28f83b431ed623335b8d127a5573eda8a13 -
Trigger Event:
push
-
Statement type: