Comparison
FastMCP vs xmcp vs the official MCP SDK
Last verified: 10 August 2026 · spec 2026-07-28 · ruleset 1.4.2
2025-11-25, and both FastMCP and xmcp depend on it — so all three produce servers that cannot serve a 2026-07-28 client.The short answer
@modelcontextprotocol/sdk@1.30.0 declares LATEST_PROTOCOL_VERSION = "2025-11-25", and 2026-07-28 is not in its SUPPORTED_PROTOCOL_VERSIONS. Every framework that depends on the SDK inherits that ceiling — a framework cannot speak a revision its transport layer has never heard of.- Need 2026-07-28 today? Your options are a framework that implements the transport itself, or a plain HTTP handler.
- Targeting 2025-11-25 deliberately? All three of the mainstream options work, and the choice is about ergonomics rather than conformance.
- Unsure? Check what your clients actually send before choosing. This decision is downstream of that, not upstream.
One thing this page will not do is rank these projects on code quality, ergonomics or community. Those are opinions, and we have no standing to publish them. Spec conformance is the axis this site is qualified to judge, so it is the only one here.
Verified comparison
| Package | Version | SDK dependency | Protocol ceiling | 2026-07-28 |
|---|---|---|---|---|
| @modelcontextprotocol/sdkOfficial SDK | 1.30.0 | — | 2025-11-25 | no |
| fastmcpFramework | 4.14.1 | ^1.24.3 | 2025-11-25 | no |
| xmcpFramework | 0.6.13 | ^1.26.0 | 2025-11-25 | no |
| @vitemcp/serverFramework | 1.3.1 | none | 2026-07-28 | yes |
Derived from published npm metadata and compiled package sources on 10 August 2026. Re-run node scripts/check-framework-spec-support.mjs to re-verify.
2026-07-28. It is also very new and very small — a handful of GitHub stars at the time of writing. We are reporting what we verified, not recommending it: a young project with few users is a real risk that a conformance table does not capture. Evaluate it on its own terms.Why the SDK's ceiling bounds the frameworks
FastMCP and xmcp are ergonomics layers. They give you a nicer way to declare tools, handle schemas and wire up a server — and then hand the actual protocol work to @modelcontextprotocol/sdk. The transport, the version negotiation and the message types are the SDK's.
curl -sL https://cdn.jsdelivr.net/npm/@modelcontextprotocol/sdk@latest/dist/esm/types.js \
| grep -E "LATEST_PROTOCOL_VERSION|SUPPORTED_PROTOCOL_VERSIONS"
# export const LATEST_PROTOCOL_VERSION = '2025-11-25';
# export const SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION,
# '2025-06-18', '2025-03-26', '2024-11-05', '2024-10-07'];FastMCP is unusually straightforward about this. Its own README states that it implements the legacy, handshake-based revisions and does not support 2026-07-28 — which is more than most projects say, and worth crediting.
What a modern client needs, and what none of the SDK-bound options can currently produce: no initialize handshake, no Mcp-Session-Id, required Mcp-Method and Mcp-Name headers validated against the body, resultType on every result, and ttlMs/cacheScope on the five cacheable methods. See the full change list.
The “stateless” naming trap
This one costs people real time, so it is worth stating plainly. Several frameworks have offered a “stateless mode” for a while. It is not the same thing as protocol statelessness.
| Framework stateless mode | 2026-07-28 statelessness | |
|---|---|---|
| What it is | A deployment option | A wire protocol change |
initialize | Still performed | Does not exist |
Mcp-Session-Id | Still on the wire | Removed |
| Solves | Serverless deployment | Protocol-level scaling |
A server running in a framework's stateless mode still fails every MCP-STL-* rule, because it still performs a handshake and still speaks a session-based protocol. The mode is genuinely useful for what it does — it just is not this. What protocol statelessness actually means.
How to choose
- Start from your clients. Which revision do the clients you need to serve actually speak? Everything else follows. A 2025-11-25 server is not wrong if that is what connects to it.
- If you need 2026-07-28, consider no framework. Sessions and handshake negotiation were most of what the transport layer did, and both are gone. A plain handler is around 150 lines — we wrote it out.
- Weigh maturity against conformance. “Supports the current revision” and “safe to depend on” are different questions. A young project can be right on the first and risky on the second.
- Verify rather than trust. Including this page — it is a dated snapshot of a fast-moving ecosystem. Build a minimal server and check its actual wire behaviour.
How we verified this, and how you can re-verify it
Everything above was derived from primary sources on 10 August 2026 — published npm metadata and compiled package sources, not project marketing:
- Protocol support — read from the SDK's own compiled
types.json a CDN. - Dependency ranges — read from each framework's published
package.jsonon the npm registry. - FastMCP's position — quoted from its own README.
git clone https://github.com/nocodeweb-llp/createmcp
node scripts/check-framework-spec-support.mjs2026-07-28, which would make FastMCP and xmcp's ceilings move with it and invalidate the central claim here. The script above says so explicitly when that happens. If you are reading this long after 10 August 2026, run it before relying on anything above.Settle it empirically
Framework claims are a proxy. Build a minimal server, deploy it, and run the endpoint through the validator — it reports what your server actually does on the wire against all 79 rules, which is the only answer that matters.
Validate a server →Frequently asked
What's the best framework for building an MCP server?
It depends which protocol revision you need. As of 10 August 2026, the official TypeScript SDK's SUPPORTED_PROTOCOL_VERSIONS stops at 2025-11-25, and FastMCP and xmcp both depend on it, so all three produce servers that cannot serve a 2026-07-28 client. If you need the current revision, that means either a framework that implements the transport itself or a plain HTTP handler.
Does FastMCP support MCP 2026-07-28?
Not as of version 4.14.1. FastMCP's own README states that it implements the legacy, handshake-based revisions (2025-11-25 and earlier) and does not support 2026-07-28. It depends on @modelcontextprotocol/sdk ^1.24.3, whose supported-version list also stops at 2025-11-25.
Does the official MCP TypeScript SDK support 2026-07-28?
Not as of 1.30.0, verified 10 August 2026. The published package declares LATEST_PROTOCOL_VERSION as 2025-11-25, and 2026-07-28 does not appear in SUPPORTED_PROTOCOL_VERSIONS. You can confirm this in one command by grepping the package's compiled types.js on a CDN.
What is FastMCP's stateless mode? Is that the same as 2026-07-28 statelessness?
No, and the naming collision causes real confusion. FastMCP's stateless mode is a deployment option that avoids persistent sessions for serverless environments, while still speaking the handshake-based protocol. Protocol statelessness in 2026-07-28 is a different thing: no initialize handshake and no Mcp-Session-Id at the wire level. A server can be in FastMCP's stateless mode and still fail every 2026-07-28 statelessness rule.
Should I use a framework at all?
Under 2026-07-28 there is a real case for not doing so. The framework work that mattered most was session management and handshake negotiation, and the revision removed both. What is left is JSON-RPC dispatch and header validation, which is roughly 150 lines. Frameworks still earn their place for schema handling, auth plumbing and developer experience.
How do I check whether a framework is spec compliant?
Do not take a README's word for it, in either direction. Build a minimal server with the framework, deploy it, and run the endpoint through a validator that checks the actual wire behaviour against the specification. A framework can claim support and still miss required fields like ttlMs and cacheScope.