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.

41%Breaking
12%Risky
47%Safe
2,216Contract revisions
ChangeSeverityTimes seenShare
Tool addedsafe13,36634%
Tool removedbreaking12,51032%
Resource addedsafe2,4816%
Resource removedbreaking2,4006%
Description rewrittensafe2,1415%
Output field addedrisky1,8925%
Description rewrittenrisky1,1393%
Input field addedrisky1,0483%
Input field removedbreaking4251%
Default changedrisky3841%
Output field removedbreaking3331%
Prompt addedsafe3231%
Prompt removedbreaking2971%
Enum value addedrisky2831%
Enum value removedbreaking2071%
Input type changedbreaking740%
Input field became optionalsafe560%
Input field became requiredbreaking350%
Tool renamedbreaking330%
output_property_renamedbreaking160%
Enum narrowedbreaking90%
Output type changedbreaking60%
Input field renamedbreaking50%

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.

Next step

Paste any MCP endpoint on the homepage, its contract report is free and needs no account.

Check a server freeRead the docs