Schema Evolution
Versioning & Migration Strategy
Schema Evolution in MCP: Versioning, Deprecations, and Migrations
Why MCP Schema Versioning Matters
MCP sits between agents and the real world. When tool contracts change, clients can fail silently, hallucinate parameters, or spam retries. A clear mcp schema versioning approach lets you ship improvements without surprise outages.
Backward-Compatible First: What Counts as a Breaking Change?
Breaking Changes (avoid or gate)
- • Removing a field or tool
- • Changing a field's type/format (e.g.,
int → string) - • Tightening validation (making optional → required)
- • Renaming tools or fields without an alias
- • Changing default behaviors with user-visible effects
Compatible Changes (safe to add)
- • Adding optional fields with defaults
- • Adding new enum values (if clients ignore unknown values)
- • Adding new tools/capabilities under new names
- • Expanding length/size limits
Rule of thumb:
If an old client can send yesterday's payload and still succeed tomorrow, it's backward compatible.
Versioning Strategy (SemVer + Capability Flags)
Semantic Versioning
- MAJOR: breaking changes (rare; coordinate)
- MINOR: additive features/fields
- PATCH: bug fixes, doc clarifications
Discovery Endpoint
Expose version & features in /tools (or discovery):
{
"contract_version":"1.7.0",
"features":["streaming","rich-errors","next_cursor"]
}Best Practices
- • Prefer capability flags over version gates for behavior toggles
- • Audience scoping: allow clients to request
?version=1.xor headerX-Contract-Version: 1 - • Error messages: include
contract_versionanderror.pathfor fast triage
Deprecations: Policy, Timelines, and UX Copy
Deprecation Process
- Mark: add
deprecated: truemetadata in discovery plus a short reason and removal date - Warn: log server-side on use; optionally add a soft warning field in the response (non-blocking)
- Document: show old/new field mapping and examples
- Window: typical 90–180 days before removal; longer for popular tools
- Notify: change log + RSS/email/Slack for integrators; pin in your SDK README
- Remove: major version or maintenance window; keep a temporary compat adapter if critical
UX Copy Template
field "path" is deprecated; use "paths[]" (array). Removal on 2026-09-01. See migration guide.Migration Strategy (Adapters, Shims, and Rollouts)
Adapter Strategy
- • Adapters at the edge: translate old requests to new shape
- • Dual-write/dual-read: store outputs in both formats
- • Feature flags: ship the new path dark
Rollout Strategy
- • Canary matrix: internal → power user → 10% → 100%
- • Observability: tag logs with client_id, contract_version
- • Hard back-out: retain previous container image
Contract Tests for MCP (Goldens & CI)
Test Strategy
- • Golden fixtures: versioned JSON requests/responses for each tool
- • Schema snapshots: commit generated JSON Schemas; fail CI on breaking diffs
- • Compatibility suite: run the full golden set in compat profiles
- • Property tests: fuzz unknown fields; server must ignore or error clearly
- • Latency budget tests: ensure adapters don't push p95 beyond target
Example Golden (old client)
tools/execute request (v1)
{"tool":"files.read","args":{"path":"README.md"}}Mapped by adapter to v2
{"tool":"files.read","args":{"paths":["README.md"],"max_bytes":32768}}Release & Rollback Playbook
Release Process
- Pre-release: update discovery docs; publish migration notes; ship adapters dark
- Canary: enable feature flag for internal client; watch error rate & adapter usage
- Ramp: 1% → 10% → 25% → 100%; hold if p95, error rate, or warning counts climb
- Remove deprecated paths: after the window closes, bump MAJOR; keep a maintenance branch for LTS users
- Rollback: flip feature flag off; revert image; announce post-mortem and next attempt plan
Copy/Paste Checklists
Design (before coding)
contract_version + featuresDeprecation
Migration & Testing
contract_versionRelease
FAQs
What's the safest way to handle breaking changes in MCP?
Avoid them. Add new optional fields or new tools; keep old ones with adapters during a deprecation window. Reserve MAJOR bumps for removals.
How long should I keep deprecated fields?
90–180 days is common. For widely used tools, keep longer and provide automated code-mod or adapter support.
How do I signal capabilities vs versions?
Expose both: contract_version for schema and features for behavior toggles. Clients can pin to a version and selectively enable features.
How do contract tests prevent regressions?
Golden request/response fixtures and schema snapshots fail CI if you remove or tighten fields unintentionally—catching breaking changes before deploy.
Key Takeaways
- Backward compatibility first: Prefer additive changes over breaking modifications
- Semantic versioning: Use MAJOR.MINOR.PATCH with clear deprecation windows
- Migration strategy: Use adapters, feature flags, and canary rollouts
- Contract testing: Golden fixtures and schema snapshots prevent regressions
- Clear communication: Document deprecations with timelines and migration guides
- Rollback planning: Always have a tested rollback strategy