Install
$ agentstack add mcp-samlader-mcpdiff ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
mcpdiff
[](https://github.com/samlader/mcpdiff/actions) [](https://www.npmjs.com/package/mcpdiff) [](./LICENSE)
Command-line tool to compare and detect breaking changes in MCP servers.
Detects both hard contract breaks (e.g. removed tools, a new required argument, a narrowed enum) and semantic drift (e.g. a reworded description that changes how the model calls a tool, with no schema change at all).
Run it locally, in CI to gate pull requests on breaking changes, or embed the library in your own tooling.
Installation
Install with npm
npm install -g mcpdiff
Run with npx (no install)
npx mcpdiff
Build from source
git clone https://github.com/samlader/mcpdiff
cd mcpdiff && npm install && npm run build
Documentation
Commands
The top-level subcommands. ` and ` are each a [source](#inputs).
captureintrospect a live server into a canonical snapshot you can commit and diff laterdifffull diff of the server's surface, including documentation-only edits (output text, json, markdown, or github)summaryhigh-level count of changes between two serversbreakingonly the changes that break existing MCP clients; exits non-zero when any are foundchangelogchanges that can affect MCP clients, breaking or not, in human-readable formvalidatecheck that a server or snapshot is reachable and well-formedcheckslist the rules mcpdiff uses to classify changes ([customize them](#configuration))
Inputs
Where a server's surface comes from. Every command accepts these forms for both base and revision:
- Live server over stdio
- Live server over HTTP
- Snapshot file
- Git revision
Comparison
- Identity matching: tools by
name, resources byuri, resource templates byuriTemplate, prompts byname; unmatched-in-base is an addition, unmatched-in-revision a removal - Request/response variance: narrowing an accepted input breaks callers, while it's broadening an output that breaks readers; mcpdiff applies the correct variance per field role
- Safety annotations: weakening
readOnlyHint,destructiveHint, oridempotentHintis treated as breaking - Semantic drift: a changed
descriptionorinstructionswith no schema change is reported as a first-class change class, so meaning changes don't slip through silently
Output
Shape the report for humans or automation. diff and breaking accept --format:
text(default): colorized terminal reportjsonmachine-readable, one object per change withseverity,ruleId, andpathmarkdowna table for pull-request commentsgithubGitHub Actions::error/::warningannotations for inline PR feedback
Every finding carries a stable rule ID (T-REQ-ADD, T-ENUM-REMOVE, P-ARG-REQ-ADD, …) so you can suppress or re-classify individual rules.
How to run
- [Continuous integration](#ci) gate pull requests on breaking changes
- [Configuration file](#configuration)
.mcpdiff.yamlfor per-rule overrides and ignore globs - [Use as a library](#library) everything the CLI does is exported from the npm package
CI
Gate pull requests on breaking changes. Commit mcp.snapshot.json, then diff the PR's server against the base branch's snapshot:
name: mcp-contract
on: pull_request
jobs:
mcpdiff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: |
npx mcpdiff breaking \
git:origin/${{ github.base_ref }}:mcp.snapshot.json \
'stdio:node dist/server.js' \
--format github
breaking exits non-zero when a breaking change is found, failing the check.
Configuration
Drop a .mcpdiff.yaml at your repo root (discovered upward from the working directory). See [.mcpdiff.example.yaml](./.mcpdiff.example.yaml).
# Re-classify individual rules by their stable ID (see `mcpdiff checks`).
rules:
T-DESC-DRIFT: info # off | info | warn | breaking
T-ADDED: info
# Drop changes whose path matches a glob.
ignore:
- tools/debug_*
# Fail the `breaking` gate on high semantic drift too.
failOnDrift: false
Library
Everything the CLI does is exported from the package:
import { loadSnapshot, diffSnapshots, render, shouldFail } from "mcpdiff";
const base = await loadSnapshot("mcp.snapshot.json");
const revision = await loadSnapshot("stdio:node dist/server.js");
const changeset = diffSnapshots(base, revision);
console.log(render(changeset, "markdown"));
if (shouldFail(changeset.changes)) process.exit(1);
Contributions
Contributions and bug reports are welcome! Feel free to open issues, submit pull requests or contact me if you need any support.
License
This project is licensed under the [MIT License](LICENSE).
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: samlader
- Source: samlader/mcpdiff
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.