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

tare-mcp

v0.3.0

Published

Local-first CLI for analyzing MCP context weight and tool ambiguity.

Readme

tare-mcp

Build npm License: MIT

Measure the MCP tool surface your agent is about to send to a model.

npm install tare-mcp
import { measureTools } from "tare-mcp";

const tools = await mcpClient.listTools();
const report = await measureTools(tools, { budget: 40_000 });

console.log(
  `MCP tool surface: ${report.summary.tools} tools, ~${report.summary.estimatedTokens.claude} Claude tokens`
);

if (report.metadata.budgetExceeded) {
  throw new Error("MCP tool surface exceeds budget");
}

MCP made tools easy to connect. It did not make them cheap to carry.

tare-mcp shows, from inside your agent or from the CLI:

  • how many tools your agent sees
  • how much context those tools consume, estimated for Claude and OpenAI cl100k
  • which servers dominate the budget
  • which tools overlap and compete for model attention
  • whether your setup exceeds a context budget

Use the CLI when you want to inspect config-discovered MCP servers locally:

npx tare-mcp

Think of it as du -sh node_modules, but for agent tool context.

Table of Contents

Why this matters

Every MCP tool is context the model has to carry before it can act. Large tool lists and verbose schemas reduce the room left for the actual task, and they can make routing decisions noisier.

tare-mcp makes that weight visible locally, before a coding agent or assistant spends any of its working context on it.

Why token count is not the whole problem

A bloated MCP setup hurts in two ways.

First, it consumes context.

Second, it creates ambiguity.

If three servers all expose tools that look like "search", the model has to choose between them before it can do useful work.

tare-mcp shows both:

  • what your tools weigh
  • where your tools overlap

Using tare-mcp in your agent

Production agents often do not have a stable .mcp.json file to inspect. They connect to MCP servers, call tools/list, and pass those tool definitions to the model on each request.

Use measureTools() when you already have the tool definitions in memory:

import { measureTools } from "tare-mcp";

const tools = await mcpClient.listTools();
const report = await measureTools(tools);

console.log(
  `MCP tool surface: ${report.summary.tools} tools, ~${report.summary.estimatedTokens.claude} Claude tokens`
);

For multiple MCP servers, add server per tool so overlap warnings and per-server totals remain useful:

import { measureTools } from "tare-mcp";

const last9Tools = await last9Client.listTools();
const githubTools = await githubClient.listTools();

const report = await measureTools([
  ...last9Tools.map((tool) => ({ ...tool, server: "last9" })),
  ...githubTools.map((tool) => ({ ...tool, server: "github" }))
]);

For unattributed tools, pass a fallback server name:

const report = await measureTools(tools, {
  serverName: "agent"
});

Budget checks are metadata, not exceptions. That keeps the library easy to use in request paths, logs, and CI:

const report = await measureTools(tools, { budget: 40_000 });

if (report.metadata.budgetExceeded) {
  throw new Error(
    `MCP tool surface exceeds budget: ~${report.summary.estimatedTokens.claude} Claude tokens`
  );
}

Structured logging example:

logger.info("mcp.tool_surface", {
  tools: report.summary.tools,
  servers: report.summary.servers,
  tokens_claude: report.summary.estimatedTokens.claude,
  tokens_openai_cl100k: report.summary.estimatedTokens.openaiCl100k,
  overlap_clusters: report.overlapClusters.length,
  budget_exceeded: report.metadata.budgetExceeded ?? false
});

The programmatic API is local-first. It does not read config files, spawn MCP servers, or call cloud tokenization APIs by default. API-backed Claude token counting is opt-in:

const report = await measureTools(tools, {
  claudeTokenizerMode: "api",
  anthropicApiKey: process.env.ANTHROPIC_API_KEY
});

CLI Quickstart

Run it without installing:

npx tare-mcp

On the first run you should see something like:

tare-mcp — MCP context weight

Config files found: 1
Servers analyzed: 2
Inspection mode: live default
Tools exposed: 47

Estimated context weight:
- Claude estimate:        ~18,400 tokens
- OpenAI cl100k estimate: ~17,800 tokens

Context window usage:
- 200k window:  9%
- 128k window: 14%
- 64k window:  29%

If the output is empty or shows "Config files found: 0", see Config discovery.

Install it in a project:

npm install --save-dev tare-mcp
npx tare-mcp

Install it globally:

npm install --global tare-mcp
tare-mcp

Static-only mode parses config without starting servers or calling hosted endpoints:

npx tare-mcp --no-exec

Set a budget:

npx tare-mcp --budget 40000
npx tare-mcp --budget 40000 --tokenizer openai

Emit JSON for CI or other tools:

npx tare-mcp --json

For local development from this repository:

pnpm install
pnpm build
pnpm dev

Hosted MCP Quickstart

Use this when you want to inspect a real hosted MCP endpoint.

mkdir -p /tmp/tare-mcp-hosted
cd /tmp/tare-mcp-hosted
cat > .mcp.json <<'JSON'
{
  "mcpServers": {
    "last9": {
      "type": "http",
      "url": "https://mcp.last9.io/mcp",
      "headers": {
        "Authorization": "Bearer ${LAST9_MCP_TOKEN}"
      }
    }
  }
}
JSON
export LAST9_MCP_TOKEN="..."
npx tare-mcp --timeout 10000

The hosted example config points at Last9's observability MCP endpoint:

https://mcp.last9.io/mcp

To use a different hosted MCP server, edit the url and headers in .mcp.json. Any Streamable HTTP MCP server works here.

If the token is missing or invalid, tare-mcp reports a 401 Unauthorized fallback instead of crashing.

Expected shape with valid credentials:

Inspecting last9 via streamable-http...

tare-mcp — MCP context weight

Config files found: 1
Servers analyzed: 1
Inspection mode: live default
Tools exposed: ...

Scenario Examples

Scenario files live in examples/scenarios:

For a no-credentials local Streamable HTTP smoke test, use examples/live-streamable-http:

pnpm install
pnpm build
cd examples/live-streamable-http
node server.mjs

Then in another terminal:

cd examples/live-streamable-http
mkdir -p .home
HOME="$PWD/.home" node ../../dist/cli.js

The temporary HOME keeps local smoke tests focused on the example .mcp.json instead of mixing in your real Claude or editor MCP configs.

Expected local smoke-test shape:

Inspecting tare-live-http-example via streamable-http...

tare-mcp — MCP context weight

Config files found: 1
Servers analyzed: 1
Inspection mode: live default
Tools exposed: 2

Worst servers:
1. tare-live-http-example ...

Worst tools:
1. tare-live-http-example.search_docs ...
2. tare-live-http-example.read_doc ...

Example output

tare-mcp — MCP context weight

MCP made tools easy to connect. It did not make them cheap to carry.

Config files found: 2
Servers analyzed: 3
Inspection mode: live default
Tools exposed: 418

Estimated context weight:
- Claude estimate:        ~143,200 tokens
- OpenAI cl100k estimate: ~138,400 tokens

Context window usage:
- 200k window: 72%
- 128k window: 112%
- 64k window: 224%

Worst servers:
1. github       ~67,410 Claude tokens   188 tools
2. notion       ~41,800 Claude tokens    96 tools
3. linear       ~34,010 Claude tokens   134 tools

Worst tools:
1. github.create_pull_request      ~3,912 Claude tokens
2. notion.query_database           ~3,110 Claude tokens
3. linear.create_issue             ~2,440 Claude tokens

Overlap warnings: 3 clusters

1. search intent
   github.search_code
   filesystem.grep
   linear.search_issues
   → Prefer one search surface per workflow.

2. file write
   filesystem.write_file
   github.create_or_update_file
   → Disable duplicate write paths unless explicitly needed.

3. issue creation
   github.create_issue
   linear.create_issue
   jira.create_issue
   → Create task-specific profiles.

Recommendations:
- Split large MCP servers into task-specific profiles.
- Prefer read-only profiles for common workflows.
- Avoid exposing multiple tools for the same intent unless needed.
- Disable rarely used write/admin tools.
- Use `tare-mcp --budget 40000` to enforce a context budget.
- Use `tare-mcp --json` to track this in CI.

Supported transports

v0.3 supports:

  • stdio MCP servers
  • Streamable HTTP MCP servers
  • programmatic tool definitions through measureTools()

SSE may be supported best-effort later.

If a server cannot be inspected because credentials are missing, the endpoint is wrong, or the transport is unsupported, tare-mcp falls back to static-insufficient mode and says so clearly.

Static vs live inspection

Live inspection is the default because it asks MCP servers for the tool definitions they actually expose through tools/list.

npx tare-mcp

Static-only mode does not spawn stdio MCP servers and does not call hosted MCP URLs:

npx tare-mcp --no-exec

Static-only mode is insufficient for packaged or hosted MCP servers because config files usually contain only commands, args, URLs, and headers. They do not contain the tool schemas the model receives.

Accuracy

tare-mcp reports estimates, not exact truth.

Live inspection shows the actual tool definitions exposed by your MCP servers at inspection time.

Token counts are still model-dependent. tare-mcp shows both Claude and OpenAI cl100k estimates where possible.

By default, Claude token counts are local approximations. API-backed Claude token counting is optional and must be explicitly enabled:

npx tare-mcp --claude-tokenizer api

That mode requires ANTHROPIC_API_KEY and uses Anthropic's POST /v1/messages/count_tokens endpoint.

Environment variables that control tokenization:

| Variable | Values | Default | Description | | ---------------------------------- | -------------- | ------------------- | ----------------------------------------------- | | ANTHROPIC_API_KEY | string | — | Required for --claude-tokenizer api | | TARE_CLAUDE_TOKENIZER | local, api | local | Override --claude-tokenizer via env | | TARE_ANTHROPIC_MODEL | model ID | claude-sonnet-4-6 | Model used for API-backed token counting | | TARE_DISABLE_ANTHROPIC_TOKEN_API | 1 | unset | Disable API-backed counting even when requested |

Security model

tare-mcp is local-first.

By default, it does not call cloud tokenization APIs.

Live inspection does execute configured stdio MCP server commands and calls configured hosted MCP URLs so it can ask them for their actual tool definitions.

Use --no-exec for static-only mode, but note that static-only mode is insufficient for packaged or hosted MCP servers because it cannot see exposed tool schemas.

tare-mcp redacts environment variable values and header values in logs, warnings, JSON, and errors.

Config discovery

tare-mcp discovers MCP configs from common locations:

./.mcp.json
./mcp.json
./.cursor/mcp.json
./.vscode/mcp.json
~/.claude/mcp.json
~/Library/Application Support/Claude/claude_desktop_config.json
~/.config/Claude/claude_desktop_config.json
~/.config/claude/claude_desktop_config.json
~/.config/tare/mcp.json

Supported server maps:

{
  "mcpServers": {}
}
{
  "servers": {}
}
{
  "mcp": {
    "servers": {}
  }
}

See examples/stdio.mcp.json and examples/streamable-http.mcp.json.

JSON usage

npx tare-mcp --json > tare-report.json

The JSON report includes:

  • version and generation time
  • summary counts
  • per-server inspection mode and confidence
  • both Claude and OpenAI cl100k estimates
  • per-tool estimates
  • overlap clusters
  • recommendations
  • warnings

Secrets from env vars and headers are redacted.

PR regression checks

tare-mcp diff compares two tare-mcp --json reports. It is built for pull requests: generate a fresh report in CI, compare it to a committed baseline, and fail when the MCP surface grows beyond a threshold.

Diff mode only reads JSON files. It does not spawn stdio servers, call hosted MCP URLs, or re-run live inspection.

Create an auditable baseline and commit it:

mkdir -p .tare
npx tare-mcp --json > .tare/baseline.json
git add .tare/baseline.json

Compare the current branch against that baseline:

npx tare-mcp --json > tare-report.json
npx tare-mcp diff --base .tare/baseline.json --head tare-report.json

Example output:

tare-mcp diff - MCP context regression

Base: .tare/baseline.json (0.2.0)
Head: tare-report.json (0.2.0)

Summary:
- Servers: 3 -> 4 (+1)
- Tools: 418 -> 443 (+25)
- Claude tokens: ~143,200 -> ~151,620 (~+8,420)
- OpenAI cl100k tokens: ~138,400 -> ~146,310 (~+7,910)
- Overlap clusters: 2 -> 3 (+1)

New servers:
- notion: 96 tools, ~41,800 Claude tokens

Largest changes to existing servers:
- github: 188 -> 200 (+12) tools, ~+8,420 Claude tokens

Fail a PR when context weight or tool surface grows too much:

npx tare-mcp diff \
  --base .tare/baseline.json \
  --head tare-report.json \
  --max-token-increase 5000 \
  --max-tool-increase 20 \
  --max-server-increase 1 \
  --max-overlap-increase 0

Token thresholds use the Claude estimate by default. Use OpenAI cl100k estimates when that is the budget you care about:

npx tare-mcp diff \
  --base .tare/baseline.json \
  --head tare-report.json \
  --max-token-increase 5000 \
  --tokenizer openai

The selected tokenizer applies to threshold math and to the server/tool detail sections in human output. Token values are always rendered as estimates with ~.

Human output shows new servers, removed servers, largest changes to existing servers, new tools, removed tools, changed tools, and overlap-cluster changes. JSON output is available for automation:

npx tare-mcp diff --base .tare/baseline.json --head tare-report.json --json

When a growth is intentional, regenerate .tare/baseline.json on the accepted setup and commit that change in the same PR.

Exit codes:

| Code | Meaning | | ---: | ------------------------------------------------------------------------------------------------ | | 0 | Diff completed and thresholds passed, or no thresholds were set. | | 1 | A configured regression threshold was exceeded. | | 2 | Invalid usage or invalid input, including missing files, invalid JSON, or missing report fields. |

Estimates are still estimates. The value of the baseline workflow is consistency: the same tool estimates are compared over time, so accidental MCP bloat becomes visible during review.

CI usage

name: MCP context budget

on:
  pull_request:

jobs:
  tare:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npx tare-mcp --budget 40000

For PR regression checks, commit .tare/baseline.json and compare the generated report in CI:

name: MCP context regression

on:
  pull_request:

jobs:
  tare-mcp:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - run: npx tare-mcp --json > tare-report.json

      - run: |
          npx tare-mcp diff \
            --base .tare/baseline.json \
            --head tare-report.json \
            --max-token-increase 5000 \
            --max-tool-increase 20 \
            --max-overlap-increase 0

For CI systems that should not execute local MCP server commands, use static-only mode and treat the result as insufficient:

npx tare-mcp --no-exec --json

Publishing to npm

This repository includes .github/workflows/publish-npm.yml. Maintainers should use the release checklist.

To publish from GitHub Actions:

  1. Create an npm automation token.
  2. Add it to the repository as NPM_TOKEN.
  3. Publish a GitHub release or run the workflow manually.

The workflow runs:

pnpm install --frozen-lockfile
pnpm test
pnpm run lint
pnpm build
npm pack --dry-run
npm publish --access public --provenance

The npm package is named tare-mcp because the unscoped tare package name is already occupied on npm.

Users can install it with:

npm install --save-dev tare-mcp
npx tare-mcp

For one-off usage:

npx tare-mcp

The installed binary is named tare-mcp, so global installs work as tare-mcp:

npm install --global tare-mcp
tare-mcp

CLI

Usage: tare-mcp [options]

Analyze MCP context weight and tool ambiguity.

MCP made tools easy to connect. It did not make them cheap to carry.

Options:
  --no-exec                    Static-only mode. Does not spawn MCP servers or call hosted MCP URLs.
  --timeout <ms>               Live inspection timeout per server. Default: 5000.
  --budget <tokens>            Fail if estimated context weight exceeds budget.
  --tokenizer <name>           Budget tokenizer: claude or openai. Default: claude.
  --json                       Output JSON report.
  --claude-tokenizer <mode>    Claude tokenizer mode: local or api. Default: local.
  -h, --help                   Display help.
Usage: tare-mcp diff [options] [base-report] [head-report]

Compare two tare-mcp JSON reports without inspecting MCP servers.

Options:
  --base <path>                      Baseline JSON report from tare-mcp --json.
  --head <path>                      Head JSON report from tare-mcp --json.
  --json                             Output JSON diff report.
  --max-token-increase <tokens>      Fail if token increase exceeds this value.
  --max-tool-increase <tools>        Fail if tool count increase exceeds this value.
  --max-server-increase <servers>    Fail if server count increase exceeds this value.
  --max-overlap-increase <clusters>  Fail if new overlap cluster count exceeds this value.
  --tokenizer <name>                 Tokenizer for --max-token-increase: claude or openai. Default: claude.

Roadmap

v0.3:

  • [x] Programmatic API for running agents through measureTools()
  • [x] Programmatic JSON reports compatible with tare-mcp diff

v0.2:

  • [x] PR diff/regression mode for JSON reports
  • [x] Threshold flags for token, tool, server, and overlap growth

Next:

  • [ ] Per-tool schema breakdown
  • [ ] Context budget config file (tare.config.json)

Later:

  • [ ] Better SSE fallback
  • [ ] Improved Claude local token estimator
  • [ ] Opt-in API-backed token counting improvements
  • [ ] Dedicated GitHub Action wrapper
  • [ ] HTML reports
  • [ ] MCP profile generator
  • [ ] tare-mcp --fix to generate lean MCP profiles

Dashboards, profile generation, and auto-fix are intentionally not part of v0.3.

License

MIT