Reference
Usage
The same rule set runs from the command line or from TypeScript. Both accept a list of tool definitions and return the same result object.
Install
# run once, without installing$ bunx github:srivtx/mcplint#main --tools tools.json# one-line install (installs the `mcplint` binary)$ curl -fsSL https://raw.githubusercontent.com/srivtx/mcplint/main/install.sh | sh# add as a project dev dependency$ bun add -d github:srivtx/mcplint
Inputs
mcplint takes exactly one of three inputs. A saved payload or config never starts a process; a server command is started over stdio, asked for tools/list, and then closed.
| Input | Description |
|---|---|
--tools <tools.json> | Audit a saved tools/list payload: an array, a {"tools":[...]} object, or a raw response. |
--config <mcp.json> | Audit every local stdio server in an MCP config with an mcpServers or servers object. |
<server-command...> | Start a server, request tools/list, then audit the tools it returns. |
Flags
| Flag | Description |
|---|---|
--tools <path> | Audit a saved tools/list payload. Does not start a server. |
--config <path> | Audit every local stdio server in an MCP config file. |
--client <name> | Client profile to lint against: claude (default), openai, gemini, foundry, copilot, generic. |
--cost | Print a per-tool context-cost table. |
--budget <tokens> | Warn when a server's tool definitions exceed this many tokens (default: 8000). |
--timeout <ms> | How long to wait for a server to answer tools/list (default: 10000). |
--json | Print machine-readable JSON: one object, or an array when more than one server is audited. |
--quiet, -q | Print a single summary line per target. |
--sarif <path> | Write a SARIF 2.1.0 report for GitHub code scanning. |
--fail-on <level> | error (default), warning, info, or none — the exit-code threshold. |
-h, --help / -v, --version | Print help or the version and exit. |
-- | End option parsing; treat the rest as the server command. |
Examples
# audit a saved payload$ mcplint --tools tools.json# lint against a client profile$ mcplint --tools tools.json --client claude# audit every server in a config, with a token budget$ mcplint --config mcp.json --cost --budget 20000# machine-readable output$ mcplint --tools tools.json --json# fail CI on warnings and write SARIF$ mcplint --tools tools.json --fail-on warning --sarif mcplint.sarif
Exit codes
| Code | Meaning |
|---|---|
0 | No findings at or above --fail-on. |
1 | At least one finding at or above --fail-on. |
2 | Invalid usage, or input that could not be parsed. |
3 | I/O error: a file could not be read, or a server could not be started or did not answer. |
--fail-on affects only the exit code. Every finding is still reported and included in JSON and SARIF output.
JSON output
With --json, a single target produces one object; more than one produces an array. Field order is stable, so a diff means a real change.
{
"file": "tools.json",
"tools": 3,
"counts": { "error": 3, "warning": 5, "info": 0 },
"cost": {
"tokens": 113,
"window": 200000,
"fraction": 0.000565,
"perTool": [
{ "name": "search_docs", "tokens": 34 }
]
},
"issues": [
{
"code": "MCP-001",
"severity": "error",
"location": "read file:name",
"message": "Tool name \"read file\" is not valid for claude (use letters, digits, \"_\" and \"-\", 1-64 characters)."
}
]
}
Library
The same rules power the CLI and the library. Import them directly when you are already in TypeScript.
import {
auditTools,
formatCost,
formatText,
parseToolsJson,
resolveProfile,
} from "mcplint";
const tools = parseToolsJson(source);
const result = auditTools(tools, "tools.json", {
profile: resolveProfile("claude"),
budget: 8000,
});
console.log(formatText(result));
console.log(formatCost(result));