Versioning an MCP Server: Changing a Tool's Input Schema Without Breaking Existing Agents
Quick answer
Changing an MCP tool's input schema is a breaking change for the agents that already call it, even though there is no compiled client to fail loudly. Add a required field, tighten a type, or remove a parameter, and existing prompts and automated workflows that send the old shape start erroring at runtime. The safe path is to version the tool deliberately: evolve the schema additively under the same name when you can, introduce a new tool version when you cannot, and keep old and new available during a migration window. Treat the input schema as a published contract with consumers you cannot see, not as internal configuration you can reshape freely.
What an unversioned breaking change looks like
An existing tool accepts a simple query and agents have built prompts around it.
{
"name": "search_orders",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" }
},
"required": ["query"]
}
}
A later edit makes a new field required and narrows an existing one. Every caller that still sends only the original shape now fails validation.
{
"name": "search_orders",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "minLength": 3 },
"scope": { "type": "string", "enum": ["all", "team"] }
},
"required": ["query", "scope"]
}
}
Because the change is in a schema rather than a typed function signature, nothing at build time warns the owners of those callers. The failures surface as invalid-parameter tool errors when the agents next run.
Why MCP makes this easy to miss
There is no lockstep client release. Agents discover tools dynamically and may have baked the old calling pattern into saved prompts, rules, or other agents' workflows distributed across teams. The schema is the only documentation of the contract, and a quiet edit gives existing consumers no signal. The fact that a tool is "just" JSON configuration makes the change feel low-risk, but its consumers are real and numerous, and they cannot adapt until they see the new schema and update their calls.
| Schema change | Compatibility | Safe handling |
|---|---|---|
| Add optional field | Non-breaking | Ship under the same tool |
| Add required field | Breaking | New tool version or default applied server-side |
| Remove or rename field | Breaking | Keep old field, deprecate, then version |
| Widen a type or enum | Usually non-breaking | Same tool, document new values |
| Tighten constraints | Breaking | New version with migration window |
Evolving additively first
Prefer changes that old callers survive. Add new parameters as optional and apply sensible defaults server-side so a request that omits them still works. Widen rather than narrow, and introduce new enum values without removing old ones. When the desired behavior genuinely requires new input, see whether the server can derive it from context instead of forcing the caller to send it. Additive evolution lets existing agents keep running while new ones take advantage of the richer schema.
Introducing explicit tool versions
When a breaking change is unavoidable, publish it as a distinct tool rather than mutating the old one, and keep both available during migration.
search_orders // v1, original shape, marked deprecated
search_orders_v2 // new required scope and tightened query
Mark the old tool's description as deprecated and point callers to the new one, but do not remove it until you have evidence that no agent still invokes it. A deprecation window gives downstream teams time to discover the new schema through their normal tool listing and update saved prompts. Versioning the tool name is the clearest signal because an agent that references the old name keeps working while one that adopts the new name gets the new contract.
Communicating and verifying the rollout
Log which tool version each call uses so you can measure adoption and decide when the old one is truly dead. Add tests that submit both the old and new shapes and assert the validation behavior, including a negative test that sends the old shape to the new version and confirms the error is clear. Document the change in terms of the contract: what was added, what is now required, and how to migrate. Relying on the schema alone to communicate the change is not enough, because callers only read it when they happen to list the tool.
FAQ
Can I just make the new field optional and default it?
Often yes, and that is the preferred non-breaking route. If a meaningful default exists, apply it server-side so old callers stay valid. Only when the caller must provide information that cannot be derived do you need a versioned tool.
How long should the old tool stay available?
Until usage logs show no agent still calls it, and at least long enough for downstream teams to complete a normal update cycle. Removing it earlier reintroduces the same runtime breakage the versioning was meant to avoid.
Is renaming a field a breaking change?
Yes. Callers sending the old name will fail. Keep the old name accepted as an alias during deprecation, document the new one, and only drop the alias under a new version after migration.
Do I need to version the whole server or just the tool?
Versioning the individual tool is usually sufficient and more precise, because agents call tools by name. Server-level versioning is useful for broad protocol changes, but per-tool versions keep the migration granular and avoid forcing unrelated callers to move.
This is part of the Powerduck vs Smithery: Generating and Hosting MCP Servers — start there for the full picture of owning and evolving MCP servers over time.