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

token-filter-mcp

v1.3.0

Published

MCP server that intercepts and compresses tool outputs before they reach the LLM context. Reduces 60-90% token consumption without losing actionable information.

Readme

🧹 token-filter-mcp

Your LLM is wasting 80% of its context window on noise. This fixes that.

npm version license node MCP

An MCP server that sits between your AI coding assistant and its tools, intelligently compressing outputs before they consume your precious context. Longer sessions. Better reasoning. Lower costs.


💸 The Problem Nobody Talks About

Every time your AI assistant runs a command, it dumps the entire raw output into its context window:

+ ✓ src/auth.test.ts (14 tests)          ← you don't need this
+ ✓ src/utils.test.ts (8 tests)          ← or this
+ ✓ src/payments.test.ts (12 tests)      ← or this
+ ✓ src/users.test.ts (10 tests)         ← or this
- ✗ src/orders.test.ts (3 tests)         ← THIS is what matters
-   ● should validate quantity > 0
-     Expected: error
-     Received: success

The vast majority of tool output is noise: tests that pass, git headers, resolution trees, progress bars, whitespace. ~80% of what goes into the context window is information the LLM will never act on.

That noise eats your context window, degrades reasoning quality, and costs you money.

⚡ The Solution

❌ Without token-filter-mcp

  • Context fills up fast
  • LLM loses track of conversation
  • Paying for tokens it ignores
  • Sessions hit context limit early
  • Reads 14 lines to find 1 failure

✅ With token-filter-mcp

  • Context stays lean
  • LLM maintains coherence longer
  • Only paying for useful tokens
  • Sessions last significantly longer
  • Reads exactly the failure, acts immediately

token-filter-mcp intercepts every tool output and applies intelligent, context-aware filtering — returning only what the LLM actually needs to make decisions.

No configuration needed. No changes to your workflow. Just plug it in.

🎯 Real Results

Average savings across real-world tool outputs: 60-90% fewer tokens consumed

🧠 How It Works

flowchart LR
    A[🤖 LLM Agent] -->|tool call| B[🧹 token-filter-mcp]
    B -->|execute| C[💻 System]
    C -->|raw output| B
    B -->|filtered output| A

    style B fill:#7c3aed,stroke:#5b21b6,color:#fff
    style A fill:#2563eb,stroke:#1d4ed8,color:#fff
    style C fill:#059669,stroke:#047857,color:#fff

1️⃣ Detect — Identifies what command was run (test runner? git? linter?)

2️⃣ Execute — Runs the command and captures full output

3️⃣ Filter — Applies the optimal strategy for that command type

4️⃣ Verify — Ensures no errors or actionable info was removed

5️⃣ Return — Sends compressed output to the LLM

🎨 Contextual Detection

The server doesn't blindly truncate. It understands what you ran and applies the right strategy:

| It detects... | And does this... | |:---|:---| | 🧪 Test runners (jest, vitest, pytest, cargo test, go test) | Strips passing tests. Shows only failures with location + expected/received | | 📊 git status | Converts to M 3 \| A 1 \| D 0 \| ? 2 + file list | | 📝 git diff | Removes repeated headers, keeps only hunks with ±3 context | | 📜 git log | One-liner: abc1234 feat: add auth (2h ago) × 15 max | | 🔍 Linters (tsc, eslint, biome, ruff) | Groups errors by rule/file, omits clean files | | 📦 Package installs | Returns ok + 847 packages instead of the resolution tree | | ❓ Unknown commands | Conservative: deduplicate + truncate to 100 lines |

🛡️ Zero Information Loss

The #1 design principle: never hide an error.

✅ Lines matching error patterns (FAIL, Error:, TypeError, panic...) → NEVER removed
✅ Non-zero exit codes → full error output preserved
✅ Parser can't understand format → returns raw output
✅ passthrough mode available for when you need everything

🚀 Installation

Add this to your MCP client config — that's it:

{
  "mcpServers": {
    "token-filter": {
      "command": "npx",
      "args": ["-y", "token-filter-mcp"]
    }
  }
}
npm install -g token-filter-mcp
{
  "mcpServers": {
    "token-filter": {
      "command": "token-filter-mcp"
    }
  }
}

📍 Where does the config go?

| Client | Config file | |:---|:---| | Kiro | .kiro/settings/mcp.json or ~/.kiro/settings/mcp.json | | Claude Desktop | claude_desktop_config.json | | Cursor | .cursor/mcp.json | | Any MCP client | Wherever it reads mcpServers config |

🔧 7 Tools, One Purpose

{ "command": "npm test", "filter_level": "normal" }

| Level | Behavior | |:---|:---| | normal | Smart filtering with sensible defaults | | aggressive | 50% additional reduction for tight context budgets | | passthrough | Raw output when you need everything (capped at 200KB) |

{ "path": "src/app.ts", "mode": "signatures" }

| Mode | What it returns | |:---|:---| | full | Content minus blank blocks, license headers, grouped imports | | signatures | Only declarations — no implementation bodies | | relevant | Only sections matching focus pattern with ±10 lines context |

Supports: TypeScript, JavaScript, Python, Rust, Go

{ "pattern": "useState", "path": "src", "group_by": "file", "max_results": 20 }

Results grouped by file, deduplicated, with context lines. Uses ripgrep when available.

{ "command": "npm test" }

All pass:

[PASS] 47/47 tests passed (3.2s)

Failures:

[PASS] 44/47 tests passed
[FAIL] 3 failures:

1. src/auth.test.ts:42 — "should refresh token"
   Expected: 200
   Received: 401

2. src/payments.test.ts:89 — "should validate 3DS"
   TypeError: Cannot read property 'status' of undefined
   at processPayment (src/payments.ts:156)

Auto-detects: Jest, Vitest, pytest, cargo test, go test

{ "operation": "status" }

| Operation | What you get | |:---|:---| | status | M 3 \| A 1 \| D 0 \| ? 2 + file list | | diff | Only hunks with changes, no header spam | | log | abc1234 feat: add auth (2h ago) × 15 | | commit | ok abc1234 | | push | ok main → origin/main | | pull | ok +3 files, 47 insertions |

{ "operation": "dump", "device": "emulator-5554" }

| Operation | What it does | |:---|:---| | dump | Compact accessibility tree: resource-id, text, clickable, tap-center | | tap | Resolve resource_id/text/content_desc to its bounds center and tap it | | tap_xy | Tap raw coordinates (last resort, e.g. a map/canvas view) | | key | Symbolic KEYCODE_* keyevent only — raw numeric codes are rejected | | type | Send text to the focused field | | swipe | Swipe from (start_x,start_y) to (end_x,end_y) | | long_press | Long-press a locator (resource_id/text/content_desc) or raw x/y | | install / uninstall | Install an APK from a local path / remove by package name | | logcat | Recent logcat output pre-filtered to error/warning lines only |

Replaces the "screenshot → vision → guess coordinates → tap → screenshot again" loop with cheap structured text.

{ "tool": "smart_git", "limit": 100 }

Aggregates ~/.config/token-filter-mcp/metrics.jsonl (plus rotated history) into invocation count, raw vs filtered chars, overall savings %, and a per-tool breakdown sorted by chars saved — without reading the JSONL file by hand.

⚙️ Configuration (Optional)

Works great out of the box. Customize only if you want to.

{
  "defaults": {
    "max_output_lines": 100,
    "test_show_passes": false,
    "git_log_max": 15,
    "diff_context_lines": 3,
    "dedup_threshold": 3
  },
  "commands": {
    "my-custom-script.sh": { "filter_level": "passthrough" }
  },
  "metrics": { "enabled": true }
}

Same schema. Project config overrides global. Global overrides built-in defaults.

📊 Built-in Observability

When enabled, every invocation is logged to ~/.config/token-filter-mcp/metrics.jsonl:

{
  "tool": "smart_test",
  "command": "npm test",
  "rawChars": 5200,
  "filteredChars": 480,
  "savingsPercent": 90.7,
  "strategy": "test_result_filter",
  "filterDurationMs": 3,
  "timestamp": "2026-06-30T15:30:00Z"
}

Auto-rotated at 5MB, max 5 history files.

What it tracks:

  • Real savings per tool and command type
  • Which filters are most effective
  • Passthrough re-invocations (signal that a filter might be too aggressive)

Query it anytime with the metrics_summary tool instead of reading the JSONL by hand.

🛡️ Guarantees

| Guarantee | Detail | |:---|:---| | 🔒 Zero loss | Errors, test failures, and changes are never filtered out | | ⚡ < 50ms overhead | Filtering adds negligible latency vs raw execution | | 🪂 Safe fallback | Unknown commands get conservative treatment, not silence | | 🔌 No lock-in | Standard MCP protocol — works with any compliant client | | 🏠 No network | Everything runs locally over stdio. Your code never leaves your machine |

🛠️ Development

git clone https://github.com/VMexicano/token-filter-mcp
cd token-filter-mcp
npm install
npm run build
npm test        # 57 tests, all passing

The best token is the one you never spend.

Made with 💖 by Victor Mexicano