MCP breaking changes
A breaking change to an MCP server is any change that makes a request your agent already sends invalid, or removes something it already reads. Not that the server went down, and not that the JSON looks different, the test is whether working code stops working, and it is asked from the consumer's side, because the server has no idea what you send.
That definition matters because MCP has no version numbers. A REST API breaks at v2, an npm package breaks when you upgrade. A remote MCP server breaks whenever its authors deploy, and your agent picks up the new contract on its next handshake with nothing to review and nothing to pin against.
The three severities
Breaking: a tool, resource or prompt disappears or is renamed, a required input appears, an input field is removed, a type is narrowed, an enum value is dropped, or an output field your code reads is gone. Existing valid calls now fail, or quietly return less than they did.
Risky: nothing errors, but behaviour can move. A new optional input, a new enum value, a changed default, a new output field, or a description rewritten past a word-delta threshold. Descriptions are the one most tools miss, the text is what steers which tool a model picks and how it fills arguments, so rewriting it changes runtime behaviour without changing a single schema type.
Safe: cosmetic or strictly relaxing. A tool added, a required field made optional, a description tidied. Nothing that worked can stop working.
Why they are invisible
The failure mode is not an exception. A lenient server accepts your now-outdated request and returns 200 with the wrong shape; a strict one returns a validation error the model reads as a tool result and works around by trying something else. Either way your error tracker stays green, your uptime check stays green, and the only symptom is an agent that has quietly started doing the wrong thing.
There is also nobody to notify you. Servers publish no changelogs, and the ones that do publish them after the fact. Detection has to come from watching the contract itself, on a schedule, whether or not any traffic hit the changed tool.
Observed on the public monitor
What actually changes in MCP contracts
Every figure below is counted from the 39,463 individual contract changes Zevruna has recorded across 538 public MCP servers since 2026-08-12, one row per change rather than per deploy. It updates itself as the monitor observes more.
| Change | Severity | Times seen | Share |
|---|---|---|---|
| Tool added | safe | 13,366 | 34% |
| Tool removed | breaking | 12,510 | 32% |
| Resource added | safe | 2,481 | 6% |
| Resource removed | breaking | 2,400 | 6% |
| Description rewritten | safe | 2,141 | 5% |
| Output field added | risky | 1,892 | 5% |
| Description rewritten | risky | 1,139 | 3% |
| Input field added | risky | 1,048 | 3% |
| Input field removed | breaking | 425 | 1% |
| Default changed | risky | 384 | 1% |
| Output field removed | breaking | 333 | 1% |
| Prompt added | safe | 323 | 1% |
| Prompt removed | breaking | 297 | 1% |
| Enum value added | risky | 283 | 1% |
| Enum value removed | breaking | 207 | 1% |
| Input type changed | breaking | 74 | 0% |
| Input field became optional | safe | 56 | 0% |
| Input field became required | breaking | 35 | 0% |
| Tool renamed | breaking | 33 | 0% |
| output_property_renamed | breaking | 16 | 0% |
| Enum narrowed | breaking | 9 | 0% |
| Output type changed | breaking | 6 | 0% |
| Input field renamed | breaking | 5 | 0% |
Description rewrites appear twice: below the word-delta threshold they are cosmetic, above it they change which tool a model picks.
Questions
Is a new optional field really a breaking change?
No, and Zevruna does not classify it as one. It is risky: your calls keep working, but the model now sees an argument it did not see before and may start sending it. Worth knowing about, not worth failing a build over.
Why is a description change not cosmetic?
Because model-facing text is contract surface. The description decides which tool gets selected and how arguments are constructed, so a rewrite can change behaviour with no schema change at all. Zevruna computes a word-level delta and flags rewrites above a threshold as risky.
How do I find out my agent is affected?
Generate a manifest of what each agent actually sends and reads, then cross it with the classified diff. That is what turns "this server changed" into "these two agents break, at these call sites" — and it is why most changes should alert nobody.
Can I pin an MCP server the way I pin a dependency?
Not upstream, no. The schema has already shipped; a pin cannot hold the server back. What a pin does is fail your CI until your call sites match the new contract, so the break is caught at build time instead of in production.
Paste any MCP endpoint on the homepage, its contract report is free and needs no account.