Pre-flight risk linting for agent tools

Lint tool-call risk before the tools run.

An agent's power is the union of its tools' permissions. CallLint reads your MCP config statically and tells you what each tool can read, write, execute, and send — with evidence — before your agent ever loads the server.

Deterministic · offline by default · never executes the server it judges

One config line can hand your agent the keys

MCP servers are usually described only by attacker-controllable metadata. A single entry can add filesystem write, shell execution, network egress, or model-directed instructions to an autonomous agent. You approve it before you can see what it really grants.

A verdict you can act on, with the evidence attached

Every finding cites the exact config field it came from. UNKNOWN never auto-upgrades to SAFE.

SAFE

Read-only, workspace-scoped, no risky surface.

REVIEW

Sensitive surface a human should weigh before approving.

BLOCK

Dangerous capability — broad FS, shell, prompt poisoning, observed money movement.

UNKNOWN

Can't be verified statically. Said plainly, never hidden as SAFE.

Eight static detectors over every server entry

Findings roll up into a risk class (S0 metadata-only → S5 financial/irreversible).

🔐

Secrets

Env keys whose names imply credentials — tokens, keys, passwords.

📁

Files

Filesystem roots granting broad read/write (/, ~, drive roots).

🌐

Network

Remote/HTTP transports to unrecognized or unpinned hosts.

🧠

Prompt

Model-directed instructions hidden in tool names, descriptions, schemas.

⚙️

Exec

Shell-out / interpreter / package-runner commands (bash -c, npx).

✉️

Action

Tools that send or mutate external state — email, messages, posts.

💸

Money

Payment / transfer / irreversible financial actions.

🧩

Supply

Unpinned package specs (@latest) — rug-pull surface.

Plus drift detection: baseline / verify records an approved surface and flags 🔁 rug-pulls when a server changes after you approve it.

A security tool with explicit, auditable boundaries

CallLint's own trust boundaries are stated, not implied.

No host execution

It parses and reasons about configuration only. It never runs, installs, or connects to the server it judges.

Config is attacker-controlled

Tool names, descriptions, and schemas are treated as untrusted input; report rendering escapes them.

Offline by default

--online adds advisory registry lookups only — it can never make a verdict more permissive.

Deterministic

No model, clock, or network in the decision path. The JSON report schema is stable (calllint.report.v0).

Built for CI and code review

JSON, SARIF (GitHub Code Scanning), compact terminal, and self-contained HTML reports. Documented exit codes gate your pipeline.

  • 0 SAFE
  • 10 REVIEW
  • 20 UNKNOWN
  • 30 BLOCK
  • 40 DRIFT
# fail the job on a blocking verdict
calllint scan .cursor/mcp.json --ci --no-emoji

# upload SARIF to GitHub Code Scanning
calllint scan .cursor/mcp.json --sarif > calllint.sarif

Install & scan

Point CallLint at your MCP config before your agent loads it. Requires Node.js ≥ 20; the published package is a single self-contained bundle with zero runtime dependencies.

npx calllint scan .cursor/mcp.json
npx calllint scan .cursor/mcp.json --ci --no-emoji
npx calllint scan .cursor/mcp.json --html > report.html

Currently a public preview — npx calllint@preview for the newest build.

Calibrated against a verdict corpus

Verdicts are held to a contract, not vibes.

A versioned corpus pins each case to an expected verdict, required evidence, and a "dangerous input never resolves to SAFE" policy, enforced as a release gate. The current seed corpus is deliberately small and synthetic — it proves the contract holds, not that CallLint has seen every server in the wild. Expanding it with redacted and real-public snapshots is active work. See CORPUS.md.

What CallLint does not do

This list matters more than the feature list. A clean run is necessary, not sufficient.

  • It does not execute, install, or connect to servers, so it cannot observe real runtime behaviour.
  • It does not read secret values — it inspects config shape (key names), never your .env.
  • It does not analyze server source code — only configuration and the tool metadata you provide.
  • It does not certify third-party tools or replace human security review.
  • It is heuristic: expect both false positives and false negatives. Treat REVIEW/BLOCK as the start of a review.

Full trust boundaries: LIMITATIONS.md · security model: SECURITY.md.