skip to content

Revisions and Era Compatibility

Versions are dates like 2026-07-28, declared on every request; a server that will not serve one returns -32022 with the list it supports. Interviewers ask how a client detects a legacy server.

part ofAPI stylesoverview, primer and where to startread it →
on this pageshow

questions

6

In MCP, what does a protocol version like 2026-07-28 mean, and when is it bumped?

level: juniorimportance: must knowfreq 70%

answer

  1. dates, not semantic versioning
  2. the date marks a breaking change
  3. additive edits leave the date alone
  4. Draft, Current, Final statuses
  5. 2026-07-28 is the current revision

basics

~10 s

MCP protocol versions are dates in YYYY-MM-DD form naming the day of the last backwards-incompatible change to the specification. The current revision is 2026-07-28. Backwards-compatible additions do not bump the version.

solid answer

~40 s

MCP does not use semantic versioning. Each revision of the specification is identified by a date string such as `2026-07-28`, and that date names the last **backwards-incompatible** change — not the date of the newest edit. If a revision gains a new optional field or another purely additive change, the version string stays where it is, so the published spec can be newer than the date it advertises. The released revisions in order are `2024-11-05`, `2025-03-26`, `2025-06-18`, `2025-11-25` and `2026-07-28`, which is current. A revision also carries a status: Draft (in progress, not for implementation), Current (ready to implement, may still take backwards-compatible edits) and Final (frozen). Since revision 2026-07-28 there is no handshake, so the version is declared per request rather than agreed once per connection.

code

json · 9 lines
json
{
  "supportedVersions": [
    "2024-11-05",
    "2025-03-26",
    "2025-06-18",
    "2025-11-25",
    "2026-07-28"
  ]
}

go deeper

for a junior

Memorise the shape and the meaning: an MCP version is a date like 2026-07-28, and that date is when the last breaking change landed. Say that the current revision is 2026-07-28 and that it is not semantic versioning.

for a middle

Explain why an additive change leaves the version alone, and that a version is therefore a compatibility marker rather than a build stamp. Be ready to walk the revision list and name the statuses Draft, Current and Final.

for a senior

Show the operational consequence: because the date only moves on breaking changes, a version match is a compatibility guarantee but not a feature guarantee, so a server still has to tolerate peers built against different snapshots of the same revision.

for a principal

Argue the tradeoff of date-based revisions for a protocol — unambiguous snapshots and no false compatibility inference from a shared major, at the cost of not being able to compute compatibility from the strings alone. Tie it to how you would stage adoption across a fleet.

## What the string is A Model Context Protocol version is a date, written `YYYY-MM-DD` — for example `2026-07-28`. It is an opaque identifier that both sides compare for equality against a list; it is not a semantic version, so there is no major/minor/patch split and no arithmetic like "anything 2.x is compatible". Ordering by date is meaningful for humans reading a changelog, but a client does not get to assume that a later date is a superset of an earlier one. ## What the date actually marks The date names the day of the **last backwards-incompatible change** to the specification. This is the detail interviewers probe. A revision can keep receiving backwards-compatible work — clarifications, a new optional field, a new optional error detail — without the version string moving at all. So two implementations both claiming `2026-07-28` may have been written against slightly different snapshots of the same revision, and the only guarantee is that nothing incompatible separates them. The converse is the useful rule for implementers: **if the date changed, something breaking changed**, and you must read the migration notes rather than assume a drop-in upgrade. ## The revision history The released revisions, in order, are: - `2024-11-05` — the first published revision. - `2025-03-26` — introduced Streamable HTTP and deprecated the older HTTP+SSE transport. - `2025-06-18` - `2025-11-25` — the last revision of the handshake era. - `2026-07-28` — **current**. This is the revision that removed the `initialize` handshake and protocol-level sessions and made MCP a stateless protocol in which every request is self-contained. That last jump is why the version string matters so much in practice in 2026: the deployed fleet straddles the two eras, and the version a request declares is what tells a server which set of rules the caller is playing by. ## Draft, Current, Final Each revision also carries a lifecycle status: - **Draft** — still being written. Not ready for implementation; anything in it may change. - **Current** — the latest revision that is ready to implement. It may still take backwards-compatible changes without a new date. - **Final** — no longer receiving changes of any kind. Superseded revisions end up here, which is what makes them safe to implement against for compatibility purposes. At the time of writing, `2026-07-28` is Current and the earlier dates are Final. ## Where the version travels Before revision 2026-07-28, the two sides agreed a version once, during the `initialize` handshake, and the connection then ran under it. That handshake was removed in 2026-07-28. In the current revision every single request declares its own protocol version in its metadata, and over Streamable HTTP the same value is also carried as a request header. There is no negotiation step and no agreed state: the server simply looks at each request, decides whether it will serve that revision, and answers or rejects it independently. A consequence worth stating out loud in an interview: a server does not "become" a version for the duration of a connection. It has a set of revisions it is willing to serve, and each request is judged against that set on its own. ## What happens on a mismatch If the declared revision is one the server will not serve, it answers that request with the JSON-RPC error `-32022`, `UnsupportedProtocolVersionError`, whose `data` carries `supported` (the revisions the server will serve) and `requested` (what the caller asked for). Because there is no session to invalidate, this is a rejection of one request, not of the connection — the correct client behaviour is to re-issue with a version from `supported`, not to tear the transport down. ## Why date-based versioning at all Date versions suit a specification that evolves as a series of dated snapshots rather than a library with a release cadence. They read unambiguously in a changelog, they sort naturally, they never invite a false compatibility inference from a shared major number, and they make "which snapshot were you written against" a question with one obvious answer. The cost is that you cannot look at two versions and mechanically decide whether one contains the other — you have to consult the revision's own compatibility notes. ## Interview framing Say plainly: dates, not semver; the date is the last breaking change; additive work does not move it; statuses are Draft, Current, Final; `2026-07-28` is current and is the revision that made MCP stateless. Getting the "last backwards-incompatible change" phrasing right is the part that separates a memorised answer from an understood one.

  • If a revision gains a new optional field, what protocol version does a server report?
    The same one. The version string names the last backwards-incompatible change, so a purely additive edit leaves it untouched. A server implementing the amended text still reports the existing date — which is why two implementations claiming the same revision may differ in optional detail, while remaining compatible on everything the revision guarantees.
  • Do a client and server negotiate a version when the connection opens?
    Not in revision 2026-07-28. The `initialize` handshake that did that was removed; there is no negotiation step at all. Every request declares its own protocol version and the server accepts or rejects that request independently. Handshake-time negotiation belongs to revision 2025-11-25 and earlier.
  • What do the Draft, Current and Final statuses mean for someone about to implement?
    Implement against Current — it is ready for use and only takes backwards-compatible changes. Final revisions are frozen, so they are safe targets for compatibility with older peers but are not where new work goes. Draft is unfinished and may change under you; do not ship against it.

saying these in an interview costs you the question

  • Says MCP uses semantic versioning with major and minor bumps
  • Thinks every specification edit produces a new date
  • Claims the version is negotiated once when the connection opens
  • Assumes a later date is automatically backwards compatible with an earlier one

context

open as a page

What do modern, legacy and dual-era mean in MCP, and which combinations interoperate?

level: middleimportance: must knowfreq 58%

basics

~20 s

Modern means the per-request metadata model of MCP 2026-07-28 and later; legacy means the initialize handshake of 2025-11-25 and earlier; dual-era supports both. Era is a property of the server, and only a dual-era server serves clients of both eras.

open as a page

In MCP, what is the -32022 UnsupportedProtocolVersionError and how should a client react?

level: middleimportance: must knowfreq 62%

basics

~20 s

UnsupportedProtocolVersionError, JSON-RPC code -32022, is how an MCP server rejects one request whose declared protocol version it will not serve. Its data carries supported and requested, so the client retries with a listed version rather than disconnecting.

open as a page

In MCP, what does the Deprecated status guarantee about a feature's removal?

level: middleimportance: should knowfreq 42%

basics

~20 s

A feature marked Deprecated in MCP stays in the specification for at least twelve months, and new implementations SHOULD NOT adopt it. Features deprecated in revision 2026-07-28 cannot be removed before the first revision released on or after 2027-07-28.

open as a page

How does an MCP client tell a legacy initialize-era server from a modern one?

level: seniorimportance: should knowfreq 50%

basics

~20 s

The client probes. Over stdio it calls server/discover, which every modern server must implement, and reads a method-not-found error as the signal to fall back to the legacy initialize handshake. Over HTTP the JSON-RPC error body of a failed attempt identifies the era.

open as a page

Your MCP server faces a mixed client fleet — do you ship dual-era support, and for how long?

level: principalimportance: should knowfreq 34%

basics

~20 s

Decide from measured client traffic, not from a wish to be safe. Dual-era support means maintaining two lifecycle implementations, so carry it only while real handshake-era clients exist, keep the stateless modern path canonical, and publish a retirement date up front.

open as a page