npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mcp-baggage

v0.1.1

Published

What each MCP server carries into your context window, and how much of it you actually use.

Readme

Baggage

npm ci

What each MCP server carries into your context window, and how much of it you actually use.

Installing an MCP server is free. Keeping one is not. Every tool a server declares is sent to the model on every single request — its name, its description and its whole JSON schema — whether or not anything ever calls it. Ten servers is a few thousand tokens off the top of every turn, in every session, forever. Nobody shows you that number.

npx mcp-baggage
  server               tools   tokens  of ctx    used

  playwright              24     8.9k    4.5%    0/24  never called
  github                  35     6.1k    3.1%    3/35
  filesystem              14     2.4k    1.2%    9/14
  sentry                  12     1.4k    0.7%    1/12
  postgres                 6      702    0.4%     4/6
  broken                   —        —       —       —  server exited (1): MCP_TOKEN is not set

  total                   91    19.5k    9.8%

every request carries 19.5k tokens of tool definitions — 9.8% of a 200k window,
before a line of your own code is read. (estimated — --exact counts)

12.7k of it — 65% — has not been called in 30 days.

nothing at all has been called from:

  playwright               8.9k  ~/.cursor/mcp.json

and these tools, in servers you do use:

  mcp__github__create_or_update_file               287
  mcp__github__list_workflow_runs                  241
  mcp__github__update_pull_request_branch          224
  … and 29 more

The two halves of that table are the whole idea. The left is what you pay on every request. The right is what you got for it. Nobody sets out to spend a tenth of their context on a browser automation server they last used in March — it is just that the cost is invisible and the decision was never put in front of them.


What it does

  • Finds every MCP config on the machine — Claude Code, Cursor, Codex, VS Code, Windsurf — and reads whichever exist.
  • Starts each server, asks it what it carries, and closes the connection. No tool is ever called.
  • Weighs each tool as the model will be shown it: mcp__server__tool, the description and the input schema, serialized the way the request serializes it.
  • Reads your Claude Code transcripts for tool_use blocks, so every tool gets a count of the times it was actually reached for.
  • Folds duplicates: the same server in three configs is weighed once and the report names all three.

What it does not do

It does not call tools, write files, change any config, or send your schemas anywhere — except under --exact, which posts the tool definitions to Anthropic's token-counting endpoint and nothing else. It has no dependencies. It spawns the servers your own config already tells your editor to spawn, and you can see exactly which ones first:

npx mcp-baggage --list

The number

There is no public tokenizer for Claude, so the default figure is an estimate. It is not length / 4: tool definitions are JSON, and JSON is mostly punctuation, indentation and short identifiers, which that ratio gets wrong in both directions at once. Instead the text is cut into runs — letters, digits, whitespace, punctuation — and each is priced the way a byte-pair tokenizer is known to treat it.

It is a model of a tokenizer, not the tokenizer, and it is good enough for the question it is for: which of these is the big one. When the number itself has to be right:

ANTHROPIC_API_KEY=... npx mcp-baggage --exact

That sends each server's tool definitions to /v1/messages/count_tokens, which returns what the model would actually be charged — framing, separators and all — and subtracts a baseline call with no tools. It runs no inference and bills nothing.

Usage

mcp-baggage [options]

  --tools            list every tool with its own weight
  --list             show the servers found, without starting any of them
  --json             machine-readable output
  --exact            count with the Anthropic API instead of estimating

  --days <n>         days of transcripts to read for usage (default 30)
  --no-usage         skip transcripts entirely
  --window <n>       context window to measure the share against (default 200000)
  --client <name>    only servers from one client
  --all              include servers the config has switched off
  --timeout <ms>     how long a server gets to answer (default 20000)
  --cwd <path>       treat another directory as the project

Progress goes to stderr and the report to stdout, so mcp-baggage --json > baggage.json gives you the figures and still shows you what is happening while a dozen servers start up.

Where it looks

| Client | User | Project | | --- | --- | --- | | Claude Code | ~/.claude.json | .mcp.json | | Cursor | ~/.cursor/mcp.json | .cursor/mcp.json | | VS Code | — | .vscode/mcp.json | | Windsurf | ~/.codeium/windsurf/mcp_config.json | — | | Codex | ~/.codex/config.toml | — |

Both transports are spoken: stdio, where the server is a process to spawn, and streamable HTTP, where it is a URL. A server that cannot be reached is a row in the table with its own error, not a failed run — and it is left out of the total rather than quietly counted as zero.

Usage counts come from Claude Code's transcripts, because it is the only client that keeps them in a documented place. With no transcripts, the used column reads —. Unknown is never printed as zero, and a tool that was never measured is never called waste.

In a script

The same figures, without the table:

import { scan } from 'mcp-baggage';

const { tokens, servers } = await scan();
if (tokens > 15_000) {
  console.error(`MCP tool definitions are ${tokens} tokens; budget is 15000`);
  process.exit(1);
}

Install

npx mcp-baggage          # no install
npm i -g mcp-baggage     # or keep it around

Node 20.10 or newer. No dependencies.


MIT © mtalhasahin