
This lesson is part of Learn MCP, our free course on the Model Context Protocol, within The MCP Guide.
In this lesson you will set up a versioning and update routine for an MCP server. You will learn the difference between the MCP protocol version and your own server's version, how to keep older clients working, how to change tools without breaking people, and how to plan around features the spec has deprecated.
Once other people rely on your server, every change is a release. A renamed tool can break a team's workflow overnight. A changed tool description can even look like an attack. This lesson gives you a calm, repeatable process.
You should have finished Lesson 26: Logging and Monitoring, because logs tell you who still uses an old tool.
Key Takeaways
- There are three versions to track: the MCP protocol version (a date, currently 2026-07-28), your server's own version, and the SDK version you build with.
- Under the 2026-07-28 spec, every request declares its protocol version, and servers reject unsupported ones with an error that lists the versions they do support.
- Servers built for 2026-07-28 can also serve older "legacy" clients that still use the
initializehandshake; this is called dual-era support. - Deprecated spec features stay for at least twelve months under the feature lifecycle policy; Roots, Sampling, Logging, HTTP+SSE and Dynamic Client Registration are all deprecated as of October 2026.
- Treat tool renames, removed tools and changed required arguments as breaking changes, and announce description changes so they don't look like a rug pull.
Step 1: Know your three version numbers
Write these down in your README:
| Version | Example | Who sets it |
|---|---|---|
| MCP protocol version | 2026-07-28 | The MCP spec |
| Your server version | 1.4.0 | You |
| SDK version | mcp 2.3.0, @modelcontextprotocol/server 2.4.0 | The SDK maintainers |
The versioning page explains that protocol versions use a YYYY-MM-DD format marking "the last date backwards incompatible changes were made." Backward-compatible updates do not change the date. As of October 2026, the current version is 2026-07-28.
The SDK numbers above were the latest on PyPI and npm when we checked on 28 October 2026. Python SDK 2.0.0 was published on 28 July 2026. The TypeScript SDK README says v1 gets bug fixes and security updates "for at least six months after the v2 release (2026-07-27)." Pin exact SDK versions in your lockfile and upgrade on purpose.
Step 2: Understand how protocol versions are negotiated now
Before 2026-07-28, client and server agreed on a version once, in an initialize handshake. The current spec removed that handshake. The Versioning and Compatibility page says every request carries its protocol version in _meta, and on HTTP also in the MCP-Protocol-Version header.
If your server does not support the requested version, it must reply with an UnsupportedProtocolVersionError that lists what it does support:
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32022,
"message": "Unsupported protocol version",
"data": {
"supported": ["2026-07-28", "2025-11-25"],
"requested": "1900-01-01"
}
}
}
Servers must also implement server/discover, which returns supported versions, capabilities and identity in one call. Clients may call it first, but don't have to. See MCP server discovery and why MCP became stateless.
Step 3: Decide whether to support legacy clients
The spec calls versions with the initialize handshake (2025-11-25 and earlier) "legacy," and 2026-07-28 and later "modern." A server that handles both is "dual-era." Its compatibility matrix is blunt: a legacy client talking to a modern-only server fails, and legacy clients "have no fall-forward mechanism."
So for now, most public servers should be dual-era. The official build tutorial notes that the TypeScript SDK's serveStdio helper negotiates the version with each client, so one server can answer both eras. A modern-only server should at least name its supported versions in any error it returns to an initialize request, because that message may be the only clue a legacy user sees.
Test both. The MCP Inspector protocol eras guide explains the --protocol-era flag: legacy is the default, modern pins 2026-07-28 with no fallback, and auto probes first. Lesson 19 shows the Inspector basics.
Step 4: Plan for deprecated spec features
The spec now has a formal feature lifecycle policy with three states: Active, Deprecated and Removed. The versioning page says deprecated features stay in the spec for at least twelve months, or at least ninety days under an expedited-removal exception.
The 2026-07-28 changelog deprecated these, with suggested migrations:
| Deprecated feature | Suggested replacement |
|---|---|
| Roots | Pass directories via tool parameters, resource URIs or server config |
| Sampling | Integrate directly with LLM provider APIs |
| Logging | stderr on stdio, or OpenTelemetry |
| HTTP+SSE transport | Streamable HTTP |
| Dynamic Client Registration | Client ID Metadata Documents |
If your server uses any of these, add a migration item to your backlog now. Our versioning and deprecation explainer tracks the details.
Step 5: Version your own server with semantic versioning
Use semantic versioning (MAJOR.MINOR.PATCH) for your server and decide in advance what counts as breaking. A practical rule set:
- Major (breaking): removing or renaming a tool, adding a required argument, changing an argument's type, or changing the shape of structured output.
- Minor (additive): a new tool, a new optional argument, a new resource.
- Patch: bug fixes that do not change any tool's contract.
Two spec details help clients cope with change. Servers should return tools/list in a deterministic order, which the changelog says helps client caching. And clients can opt in to toolsListChanged notifications through subscriptions/listen, so they learn when your tool list changes.
Step 6: Retire tools gently
Don't delete a tool the day you replace it. Instead:
- Ship the new tool alongside the old one in a minor release.
- Add "Deprecated: use
get_invoice_v2" to the old tool's description. - Watch your audit logs from Lesson 26 for remaining calls.
- Announce a removal date, then remove it in the next major release.
Be careful with description changes in general. A trusted server that quietly changes its tools after users approved them is often called a "rug pull." Explain every change in your release notes so users can tell an honest update from an attack. See MCP rug pull attacks.
Step 7: Release, publish and keep a rollback
For each release: update the changelog, bump the version, run your tests in both protocol eras, and deploy. Keep the previous build ready so you can roll back fast.
If you list your server in the MCP Registry, its versioning guide says each published version string must be unique and cannot be changed once published. It recommends semantic versioning and aligning the registry version with your package version. Lesson 28 walks through publishing.
Try it
- Add a "Versions" section to your server's README with the three numbers from Step 1.
- Run your server through the Inspector twice, once with
--protocol-era legacyand once with--protocol-era modern. Note which one fails, if any. - Search your code for Roots, Sampling,
logging/setLevelor an SSE endpoint. Add a migration task for each hit. - Pick one tool and write the release note you would publish if you renamed it.
Recap
You separated protocol, server and SDK versions. You learned how per-request version negotiation and dual-era support work in the 2026-07-28 spec, which features are deprecated and what replaces them, and how to version and retire tools without surprising users. Next, you will publish a version to the MCP Registry.
Course navigation
Previous lesson: Lesson 26: Logging and Monitoring.
Next lesson: Lesson 28: Publish to the MCP Registry.
Back to the Learn MCP course outline.
Frequently asked questions
Does every spec update break my server?
No. The protocol date only changes when backwards-incompatible changes are made. Backward-compatible updates keep the same version. The 2026-07-28 revision was a big one because it removed the initialize handshake.
Should I drop support for legacy clients?
Not yet for most public servers. The spec's compatibility matrix shows legacy clients cannot talk to a modern-only server. Keep dual-era support until your logs show legacy traffic has faded.
What error code means "unsupported protocol version"?
In the 2026-07-28 spec it is -32022, UnsupportedProtocolVersionError. The error's data lists the supported versions so the client can retry.
How long will deprecated features keep working?
At least twelve months after the revision that deprecated them, under the feature lifecycle policy, unless the expedited-removal exception applies. Removal happens in a later spec revision, not overnight.
Where can I see every change in a spec release?
Read the official changelog for each version. We summarize it in the MCP specification changelog.











