Offline · no network · CI-ready

Audit MCP servers before an agent ever connects.

mcplint reads a saved tools/list payload, an mcp.json config, or a live server command, then tells you which tools a client will reject or silently drop, what the definitions cost in context tokens, and which inputs are risky. No call leaves your machine.

bunx github:srivtx/mcplint#main --tools tools.json

Not on npm; it runs from GitHub with Bun. Docs: Rules, Usage, CI, FAQ.

mcplint tools.json
$ mcplint --tools tools.json --client claudetools.json  errors:3  warnings:6  info:1  tools:3  tokens:~147ERROR  MCP-001  read file:name  Tool name "read file" is not valid for claude (use letters, digits, "_" and "-", 1-64 characters).ERROR  MCP-004  read file:inputSchema  The root "inputSchema" must have "type": "object" for claude; without it, requests fail on every call.ERROR  MCP-008  search_docs:inputSchema.required  "required" lists "page", which is not declared in "properties"; strict clients reject the tool.WARNING  MCP-009  read file:inputSchema.properties.encoding  Property "encoding" declares no "type", so its type is ambiguous to the model.WARNING  MCP-010  read file:inputSchema.properties.encoding  Uses the OpenAPI keyword "nullable", which is not valid JSON Schema; use a union type such as ["string", "null"] instead.INFO  MCP-011  read file:inputSchema  "$schema" declares draft-07, but claude prefers 2020-12.WARNING  MCP-020  read file:description  Tool text matches a prompt-injection pattern; describe capabilities plainly so the server is not treated as hostile.WARNING  MCP-022  read file:inputSchema.properties.path  Property "path" looks like a path sink but is an unconstrained string; validate it in the server (pattern, enum, or maxLength).

What it catches

An agent can only call the tools its client let it see. These are the failures that make a tool disappear, break a call, or cost more context than it should.

A tool the client silently drops
A root inputSchema that is not type: object, or that leans on a root $ref or combinator a client will not resolve, is rejected or dropped with no error.
A name that does not survive validation
Names with spaces or punctuation, names past the length limit, and duplicate names all break the client's tool list in different ways. mcplint reports each.
A required entry that points at nothing
When required lists a property that properties never declares, strict clients reject the whole tool.
A schema the model cannot read
Properties with no type, the OpenAPI nullable keyword, and a JSON Schema draft the client does not prefer all make a schema ambiguous.
Risky sinks in tool inputs
Properties named like a shell, file, SQL, or URL sink that are unconstrained strings are flagged before they reach an agent.
Tool text that looks hostile
Descriptions that read like a prompt injection, and invisible or bidirectional Unicode characters, are caught as tool-poisoning patterns.
Context cost nobody measured
Every definition is re-sent on every request. mcplint counts the tokens, warns over your budget, and flags a single oversized tool.
Descriptions that help or hurt
A missing description leaves the model unable to judge when to call the tool; an extremely long one is re-sent every time. Both are reported.
context cost
$ mcplint --config mcp.json --costlenses  errors:0  warnings:5  info:0  tools:8  tokens:~901lenses: ~901 tokens across 8 tool(s) — 0.5% of a 200,000-token window       111  booklens_audit       121  booklens_fix       105  officelens_audit       108  odflens_audit       117  iconlens_audit       143  waxseal_seal       130  waxseal_verify        66  waxseal_inspect

Quick start

Three inputs, one binary. Point it at a saved payload, a client config, or the server command itself, and let the exit code gate the pipeline.

quick start
# run once, without installing$ bunx github:srivtx/mcplint#main --tools tools.json# lint against a client profile and fail CI on warnings$ mcplint --tools tools.json --client claude --fail-on warning# read the client's own config, or start the server and ask for tools/list$ mcplint --config mcp.json$ mcplint bunx -y @modelcontextprotocol/server-filesystem /srv/data

Every flag, the exit codes, and the TypeScript API are in Usage.

Playground

Paste a tools/list payload and audit it against a client profile. Everything runs in your browser; nothing is uploaded.

Runs entirely in your browser. Nothing is uploaded.

No payload audited yet.

mcplint
Audit output appears here.

Documentation

The landing page is the pitch. The details live on four short pages.

Rules
Every rule code, the client profiles it checks against, and the static pipeline behind a run.
Usage
The three input modes, every CLI flag, the exit-code scheme, stable JSON output, and the library API.
CI
SARIF 2.1.0 and GitHub code scanning, with a workflow you can paste.
FAQ
Scope, limitations, and how mcplint compares to the MCP Inspector and other tooling.