mcpdrift
Catch silent MCP server contract drift in CI. Snapshot your server's tools/list,
commit the baseline, and fail the build when a change breaks the contract — a tool
removed or renamed, a parameter newly required or retyped.
MCP servers are young, fast-moving, and mostly have no tests (one audit found 52% of servers broken, the median with zero CI tests). A refactor quietly renames a tool or makes a param required, and every agent depending on it breaks — with no version bump and no warning. mcpdrift is the missing contract test.
pipx install mujin-mcpdrift
mcpdrift snapshot # record current tools/list as the baseline (commit it)
mcpdrift check # exit 1 if the contract broke
myserver: 3 change(s):
BREAKING tool 'echo' was removed
info tool 'ping' was added
info param 'limit' added to 'search'
-> breaking changes. If intentional, re-run `mcpdrift snapshot myserver` and bump your version.
How it works
mcpdrift launches your server over stdio, completes the MCP handshake, reads tools/list,
and reduces it to the part that's actually a contract: which tools exist, and each
tool's parameter names, types, and required-ness. It diffs that against the committed
baseline (.mcpdrift/<server>.json) and classifies every change:
| Breaking (fails CI) | Informational (passes) |
|---|---|
| tool removed | tool added |
| parameter removed | optional parameter added |
| parameter now required | parameter now optional |
| parameter type changed | description changed |
When a change is intentional, re-run snapshot to bless it (and bump your server's
version) — the baseline diff makes the contract change explicit in code review.
Configure servers — .mcpdrift.json
{
"servers": {
"myserver": { "command": ["python", "server.py"] },
"everything": { "command": ["npx", "-y", "@modelcontextprotocol/server-everything"] }
}
}
Or run ad-hoc without a config:
mcpdrift snapshot myserver --command "python server.py" --env API_KEY=xxx
mcpdrift check myserver --command "python server.py" --env API_KEY=xxx
CI gate
# .github/workflows/mcp-contract.yml
jobs:
mcpdrift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.11" }
- run: pipx install mujin-mcpdrift
- run: mcpdrift check # fails if a PR breaks the tool contract
Zero dependencies, stdio transport. --json for machine output.
Part of a set
- agentaudit — audit MCP servers / skills / plugins for security & quality.
- agentsync — keep agent config files in sync.
- skillbudget — budget your always-loaded context tokens.
agentaudit checks your MCP server is safe; mcpdrift checks it didn't silently change its contract.
Built by Mujin Labs — tooling for the autonomous-agent era. MIT.
Release files for mujin-mcpdrift 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mujin_mcpdrift-0.1.0.tar.gz | 10.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mujin_mcpdrift-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.8 kB
Release files / mujin_mcpdrift-0.1.0.tar.gz
| Download URL | mujin_mcpdrift-0.1.0.tar.gz |
|---|---|
| Size | 10.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1028819fea5f6578d9ddc65369d0deccd74a3c83b32557e959e40d88dddd6278
|
|
BLAKE2b-256 checksum How to use checksums |
dfb0e193c9caf5bde8782befad0a2036eaf37bd9a9a7fd221db6756eaf2a49b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.3
|
Release files / mujin_mcpdrift-0.1.0-py3-none-any.whl
| Download URL | mujin_mcpdrift-0.1.0-py3-none-any.whl |
|---|---|
| Size | 11.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9e2f49b97279f99888bbcf0c028b41ec1db92d8ecdac464b27e55f1c7f2cc3a6
|
|
BLAKE2b-256 checksum How to use checksums |
f54cd86b2f1e5c55e3ad9d0f503e5bdaea35023f315161d2a38cdd2a58c087dd
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.3
|