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

@tomfletcher2929/mcplint

v0.1.2

Published

Lint and score Model Context Protocol (MCP) server tool definitions before you publish — name/schema validity, description quality, token weight, and safety annotations for destructive tools. CLI + library.

Downloads

520

Readme

mcplint

Lint and score your MCP server's tool definitions before you publish — so the model can actually choose them, and they don't quietly bloat every request's context window.

mcplint checks name/schema validity, description quality, token weight, and safety on destructive tools, then gives you a 0–100 score and a CI gate.

Quick start

# install once, then use the short `mcplint` command shown below
npm install -g @tomfletcher2929/mcplint
mcplint tools.json

# or run it without installing:
npx @tomfletcher2929/mcplint tools.json

Lint a static file — a tools array, or an MCP tools/list result ({ "tools": [...] }):

mcplint tools.json                 # lint + score (free)
mcplint tools.json --ci --min 90   # exit 1 below 90 — drop into CI (free)
mcplint tools.json --json          # machine-readable
mcplint tools.json --report                 # shareable Markdown report (Pro)
mcplint tools.json --report --format html    # standalone HTML report (Pro)
mcplint tools.json --watch                   # re-lint on every save (Pro)

Watch mode (Pro) lints once, then re-lints and re-prints on every change until you quit — pair it with --report to keep a report fresh, or --json to pipe scores into a dashboard. A static file is watched for saves; a live server has no file, so it's re-linted on a timer (--interval <seconds>, default 3):

mcplint tools.json --watch                          # re-lint the file on save
mcplint --cmd node --watch -- dist/server.js        # re-lint a live server every 3s
mcplint --cmd node --watch --interval 10 -- dist/server.js   # …every 10s

Or lint a live server — mcplint spawns it, runs initialize + tools/list over stdio, and lints exactly what it advertises to a model. Put the server's own command and args after a literal --:

mcplint --cmd node --ci -- dist/server.js          # lint your built server in CI
mcplint --cmd npx -- -y @scope/your-mcp-server     # lint a published server
mcplint --cmd python --json -- -m your_server      # any stdio MCP server

Everything after -- is passed to the server untouched, so its flags can never clash with mcplint's (and can't silently disarm --ci). The live path runs the same rules and scoring as the file path — so a passing file is a passing server.

Lint several sources at once (Pro)

Pass more than one source — files and/or one live --cmd server — to lint them all in a single pass with a combined summary:

mcplint a.json b.json                              # several files
mcplint a.json b.json --cmd node --ci -- dist/server.js   # files + a live server, gated in CI
mcplint a.json b.json --json                       # one JSON object per source

Each source is scored independently and listed on its own row; --ci then fails if any source breaches --min or has errors (a source that can't even be linted counts as a failure — never a silent pass). --report and --watch act on a single source, so run those one source at a time.

What it checks

  • valid, unique tool names ([A-Za-z0-9_-], ≤ 128 chars — snake_case and kebab-case both pass, per the MCP spec)
  • present, useful, non-placeholder descriptions — not too short, not token-bloated
  • object input schemas; required params actually defined in properties
  • destructive tools (delete/drop/exec…) flag their risk in the description

Destructive detection is deliberately conservative: names like reset_password or execute_query draw a destructive-safety warning (not an error) — document the risk in the description to clear it.

Free vs Pro

  • Free (no key, always works): lint, score, --json, and the --ci gate — for a single file or a single live --cmd server.
  • Pro (one-off): --report export (Markdown or --format html), watch mode, and the multi-source view (several sources in one pass).

→ Get mcplint Pro — you'll be emailed a licence key. Activate it with an environment variable:

export MCPLINT_LICENSE_KEY="mcpl_…"      # macOS / Linux
setx MCPLINT_LICENSE_KEY "mcpl_…"         # Windows (takes effect in new shells)

The key is verified offline — no account, no sign-in, no phone-home. One licence works on all your machines.

Use as a library

import { lint, parseTools } from "@tomfletcher2929/mcplint";

const result = lint(parseTools(JSON.parse(rawJson)));
console.log(result.score, result.findings);

MIT-licensed engine. Automated linting catches structure and hygiene, not intent — review findings in context.