mcpdrift
Pin your MCP servers' tool surface — tool names, descriptions, input schemas, resources and prompts — in a reviewable lockfile, and fail CI when an update silently changes what a server exposes.
MCP servers get upgraded by version ranges, transitive deps and config edits. A tool your agent relied on can lose an argument, change type, or disappear entirely, and nothing tells you until a run misbehaves. mcpdrift turns that surface into a contract.
Install
pip install mcpdrift
Usage
# record what the server exposes today (writes a reviewable lockfile)
mcpdrift snapshot --config .mcp.json --server myserver --out mcp.lock.json
# fail CI when the live surface no longer matches the lock
mcpdrift check --config .mcp.json --lock mcp.lock.json
The config file is a Claude-Desktop-style .mcp.json:
{
"mcpServers": {
"myserver": { "command": "uvx", "args": ["some-mcp-server"] }
}
}
check exits 1 when drift is found and prints every added, removed or changed path:
removed tools.read: {'description': 'read a doc', ...}
changed tools.search.inputSchema.properties.q.type: 'string' -> 'integer'
Ignoring intentional changes
mcpdrift check --config .mcp.json --lock mcp.lock.json \
--ignore 'server.version' --ignore 'tools.search.description'
Patterns are globs matched against the dotted path (server.*, tools.*, prompts.*). Ignoring a node hides every finding beneath it.
CI
- run: pip install mcpdrift
- run: mcpdrift snapshot --config .mcp.json --server myserver --out mcp.lock.json.new
- run: diff <(mcpdrift check --config .mcp.json --lock mcp.lock.json --json) /dev/null
Or simply run mcpdrift check as a required status check; a non-zero exit blocks the merge that bumped the server.
How it works
mcpdrift launches the configured server, speaks newline-delimited JSON-RPC over stdio (the MCP stdio transport): initialize → notifications/initialized → tools/list + resources/list + prompts/list. Servers that don't implement a listing method simply yield an empty section. The result is canonicalized (keys sorted recursively) so comparisons are stable, then diffed structurally against the lockfile.
Notes
- Snapshots are local and offline-friendly; nothing phones home.
- The lockfile records
server.version, so an honest version bump shows as a one-line drift you can--ignoreif you only care about the schema.
License
MIT-style: use it, ship it, no warranty.
Metadata
Release files for 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 | Provenance | |
|---|---|---|---|---|
| mcpdrift-0.1.0.tar.gz | 11.5 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcpdrift-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 20.5 kB
Release files / mcpdrift-0.1.0.tar.gz
| Download URL | mcpdrift-0.1.0.tar.gz |
|---|---|
| Size | 11.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
84718b06438b8161ca49611efc62d2ef9c7b3a9cc4c8a92a5df11b9de3c509af
|
|
BLAKE2b-256 checksum How to use checksums |
13ccf2a84807e97cc80c6576623d6cfab81ac7d33203f8b58782bfb14ba8a9a4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Release files / mcpdrift-0.1.0-py3-none-any.whl
| Download URL | mcpdrift-0.1.0-py3-none-any.whl |
|---|---|
| Size | 9.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
45af855f38d23ca9900c27060187801b7b163e1e33674ca89e80cd354de21099
|
|
BLAKE2b-256 checksum How to use checksums |
a1ea883458c7589d5e28c8a485c83ae1b71a6fffc8f077b9a7af165225011104
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.15
|
Security for mcpdrift 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.