MCP rug pulls and silent contract drift - catch the change before your agent acts
Short answer: yes, it can change after you approve it, and most of the time the declared version does not move. Across a frozen 40-day census of the public MCP registry we recorded 2,503 safety-relevant contract changes, and in 62.4% of them the server's declared version was unchanged. A version pin does not see roughly three in five of the changes that matter. 123 of them flipped a tool's annotation toward destructive: a hint that read "read-only" now declares it can write, delete or send.
Those figures are frozen and citable (DOI 10.5281/zenodo.21449150); the running count is on the public ledger, and the full deduped analysis - version behavior, removal scope, stability segmentation - is The MCP Drift Report. The honest limit: this is a contract diff, not a safety verdict, and "silent" is a claim about version evidence only, never about intent.
Security writeups call the sharpest version of this an MCP rug pull: a server passes review, runs cleanly for weeks, then swaps its tool contract for something else after your agent already trusts it (CVE-2025-54136 demonstrated the pattern against approved configs). Rug pull asserts intent; most contract changes we observe in the wild are ordinary, unannounced maintenance. Both matter, because your agent cannot tell them apart at call time - and the mechanics are identical.
Model Context Protocol tools are described to your agent the way a system prompt is: a name, parameters, constraints, and annotations. That description is a contract. Unlike a pinned npm version, many MCP servers can change that contract on the remote side with no release tag your client notices.
When the contract drifts - a new required parameter, a narrowed enum, an annotation flip to destructive - the agent still calls the tool with Monday’s assumptions. The failure mode is quiet. You see a weird tool result, a wrong side effect, or a hold-up much later in the chain.
A directory listing or a one-time “screen” of the description helps before you wire a tool. It does not help on Tuesday when the live schema changed. That is an in-path problem: something has to compare the live contract to what you pinned on first sight and stop the call when they disagree.
mcpindex’s drift gate does that locally. It pins each tool contract on first sight (TOFU), diffs on every later call, and HOLDs when the change is breaking. Benign added-optional fields can proceed. The verdict is a contract-diff - “this changed” - not a claim that the tool is safe. Zero credentials; the default build egresses nothing.
If you only need discovery or an advisory REVIEW/UNVERIFIED screen before install, use the directory and /screen. If you already run tools in Claude Desktop, Cursor, Cline, or Zed, install the gate so silent drift cannot run unseen: https://mcpindex.ai/#install
Related
Read Fig. 02 as text
MON -------------------- TUE -------------------- WED
| | |
you pin the contract the server changes it your agent calls it
search_docs( search_docs( WITHOUT A PIN
query: string query: string, the agent fills the new required
) webhook: string * param and calls. nothing tells you.
)
* newly required WITH MCPINDEX
no version bump |- HELD added-required-param
no notification held before the call goes out
no email
the tool your agent trusted on monday changed on tuesday. nothing in MCP told you.Permalink, SVG & reuse · CC BY 4.0
- What is an MCP rug pull?
- An MCP rug pull is when a server changes a tool's behavior or declared contract after you approved it - the tool your agent trusted Monday is a different tool on Tuesday, with no version bump. The pattern was demonstrated in CVE-2025-54136 (an approved config whose underlying command was swapped). A drift gate counters it by pinning the contract on first sight and holding any call where the live contract no longer matches the pin. Note the honest limit: a contract-diff catches declared changes; a server that keeps its contract identical and changes behavior underneath is out of scope.
- How do I know if an MCP tool changed after I connected it?
- Pin the tool's declared contract (name, schema, annotations) on first sight and diff it on every later call. When the live contract differs from what you pinned, a drift gate flags the specific change or holds the call. MCP servers can change remotely with no version bump, so a diff is the only reliable signal.
- What is silent MCP tool contract drift?
- It is when an MCP server changes a tool's declared contract, a new required parameter, a narrowed constraint, an annotation flipping from read to write, without a version bump your client notices. The agent keeps calling the tool with its old assumptions, and the failure is quiet: a wrong side effect or a bad result later in the chain.
- Can you detect an MCP server that changes behavior without changing its schema?
- Not from the client side deterministically. Contract pinning catches declared changes to schema, description, and annotations. A server that keeps the schema identical and changes behavior underneath is the honest hard part, and anyone claiming to verify behavior for arbitrary servers is overclaiming. mcpindex scopes itself to declared-contract diff and labels behavior-underneath as out of scope.
- Is git diff enough to catch MCP tool contract changes?
- No. git diff and similar utilities compare file snapshots you provide. MCP contract integrity pins the live tool contract on first sight and diffs it on later calls - including when the server changes remotely with no file in your repo. See the layer map in MCP scanners vs gateways.