Last updated: August 31, 2026
Migrating an MCP server to the 2026-07-28 spec
The 2026-07-28 revision removes sessions, the initialize handshake, and blocking tasks/result. It adds a mandatory server/discover call, required Mcp-Method and Mcp-Name headers, and ttlMs plus cacheScope on list results. Your tool code survives. Your transport layer does not.
We run a production hosted MCP server at mcp.opentweet.io, so this is the checklist we work from, not a paraphrase of the changelog. Read it as an operator would: what breaks, what it costs, and what you can defer.
Three removals, and what each one costs
This is the largest revision since MCP launched, and the reason is that all three removals target the same thing: the assumption that a client and a server hold a conversation. They now exchange requests instead.
SEP-2567
Sessions and Mcp-Session-Id removed
The server no longer mints a session id, and the client no longer echoes one. Every request stands on its own. If your server kept per-session state in memory, that state has to move into the request, into your auth token, or into a store you look up by user.
Migration cost: High if you were stateful. Zero if you already ran the transport with no session id generator.
SEP-2575
The initialize handshake removed
The initialize request and the notifications/initialized reply are gone. There is no negotiation round trip before the first real call. Capability discovery moves to server/discover, which a client may call once and cache.
Migration cost: Low code cost, real behaviour change. Any logic you hung off "client has initialized" has nowhere to live now.
SEP-2663
Blocking tasks/result removed
A client can no longer block on tasks/result waiting for a long job to finish. Long-running work reports through the async task flow instead. If you had a tool that quietly held a connection open for 90 seconds, that pattern is over.
Migration cost: High for servers doing slow work inline. Low for servers whose tools return in a second or two.
Three additions you have to implement
server/discover is mandatory
Every server must answer server/discover. This is the replacement for what initialize used to tell a client, and because it is a plain request it can be cached, proxied, and prefetched.
Mcp-Method and Mcp-Name headers are required
The JSON-RPC method name and the server name now ride on the HTTP request as headers. Infrastructure in front of your server can finally see what a request does without parsing the body.
ttlMs and cacheScope on list results
tools/list and resources/list responses can declare how long they stay fresh and whether the answer is per user or global. Static tool catalogues stop being re-fetched on every connect.
The header change is the one your ops team will care about
Mcp-Method and Mcp-Name put the JSON-RPC method on the HTTP request line. That means nginx, your API gateway, and your CDN can rate limit tools/call separately from tools/list without reading a body. If you have ever tried to protect an MCP endpoint from a runaway agent, you know why this matters.What the wire looks like now
The old flow spent three requests getting permission to do the first useful thing. The new flow spends one, and that one is cacheable.
# Before: three requests before a single tool ran
POST /mcp {"method":"initialize", ...}
-> 200, Mcp-Session-Id: 6f1e...c92
POST /mcp Mcp-Session-Id: 6f1e...c92
{"method":"notifications/initialized"}
POST /mcp Mcp-Session-Id: 6f1e...c92
{"method":"tools/call","params":{"name":"opentweet_create_tweet", ...}}# After: discovery is one cacheable call, then straight to work
curl -X POST https://mcp.opentweet.io/mcp \
-H "Authorization: Bearer ot_your_key" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Method: server/discover" \
-H "Mcp-Name: opentweet" \
-d '{"jsonrpc":"2.0","id":1,"method":"server/discover"}'
# No session id comes back, and none goes out on the next request.
curl -X POST https://mcp.opentweet.io/mcp \
-H "Authorization: Bearer ot_your_key" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: opentweet" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"opentweet_create_tweet",
"arguments":{"text":"Shipped the migration.","publish_now":true}}}'Exact field names in the server/discover response are defined by the spec text. Read it before you hard-code a parser. The headers and the absence of a session id are the parts that will break a client first.
Deprecations, and how long you actually have
Sampling is the deprecation that bites hardest
Roots and Logging have obvious replacements. Sampling does not. If a tool of yours calls back into the client model to summarize or classify, you have 12 months to move that call to a model you own. Start with an inventory of every server that uses it, because the answer is usually more servers than the team remembers.The order we work in
- 1
Delete session state first
Find every read of Mcp-Session-Id and every in-memory map keyed by it. If your transport already runs stateless, this step is a grep that returns nothing, which is the best possible outcome. If it returns hits, this is the bulk of your migration.
- 2
Answer server/discover
Implement it before you remove initialize, so both work for one deploy. Clients on the old revision keep running while you cut over.
- 3
Read the new headers, then require them
Log Mcp-Method and Mcp-Name for a week before you enforce them. You will find at least one client you forgot about.
- 4
Set ttlMs and cacheScope on your list results
If your tool catalogue is identical for every user, say so with cacheScope. You get a latency win for free and shed a request per connect.
- 5
Audit Sampling, Roots, and Logging usage
Twelve months sounds long until it is a quarter away. Inventory now, migrate on your own schedule.
- 6
Stop advertising the HTTP+SSE endpoint
Leave it running for the deprecation window, but remove it from your docs and your install instructions today so no new client picks it up.
Where mcp.opentweet.io stands
Our hosted endpoint speaks Streamable HTTP and runs the transport with no session id generator, so it has never issued an Mcp-Session-Id. The SEP-2567 removal is a non-event for us, which is the single best argument for building stateless in the first place. Auth is a static ot_ bearer key, so the DCR to CIMD move does not touch it either.
If you are wiring a client to us today, use the config below. As of 31 August 2026 our endpoint answers an initialize at revision 2025-11-25, including when the client asks for 2026-07-28, so a newer client negotiates down instead of failing. Revisions move, so verify what your client actually negotiates rather than trusting a date in an article. That is good practice against any hosted MCP server during a spec transition, ours included.
{
"mcpServers": {
"opentweet": {
"type": "streamable-http",
"url": "https://mcp.opentweet.io/mcp",
"headers": { "Authorization": "Bearer ot_your_key" }
}
}
}And the fallback that no spec revision can break, because it is a plain HTTP POST with no protocol on top of it:
curl -X POST https://opentweet.io/api/v1/posts \
-H "Authorization: Bearer ot_your_key" \
-H "Content-Type: application/json" \
-d '{"text":"Migration done. No MCP client involved.","publish_now":true}'The REST endpoint is /api/v1/posts. Full reference in the API docs, and the tool list is in the MCP docs.
Why we keep a REST path documented next to the MCP path
A protocol revision this large is exactly when you want a second way in. Anything you can do with the 36 MCP tools, you can do with the REST API and a bearer key. When a client library lags a spec revision, that is the door that stays open.If you consume MCP servers rather than run one
You mostly wait for your client to update. Claude Code, Cursor, OpenCode, goose, and Zed all ship their own MCP implementations and will move on their own timelines. What you can do is stop pinning to an old revision in any config you control, and prefer hosted Streamable HTTP endpoints over the deprecated SSE transport when a server offers both.
Watch for one specific failure during the transition: a client on the old revision talking to a server that has already dropped initialize will look like a hang, not an error. If a previously working MCP server goes quiet after an update, check the revision before you check your key.
Frequently asked questions
What changed in the 2026-07-28 MCP spec?
Five removals and three additions. Sessions and the Mcp-Session-Id header are gone (SEP-2567). The initialize request and notifications/initialized handshake are gone (SEP-2575). Blocking tasks/result is gone (SEP-2663). A server/discover RPC is now mandatory, Mcp-Method and Mcp-Name request headers are now required, and list results carry ttlMs and cacheScope. Roots, Sampling, and Logging are deprecated on a 12-month window, and the older HTTP+SSE transport is deprecated on a 1-year window.
Do I have to rewrite my MCP server?
No, but you do have to change the transport layer. Tool definitions, argument schemas, and handler bodies are untouched. What changes is everything around them: the handshake you no longer perform, the session id you no longer issue or read, the discovery method you now have to answer, and the two headers you now have to read and, as a client, send.
What replaces the initialize handshake?
server/discover. Instead of a round trip that negotiates capabilities before any real work, a client calls server/discover and gets the server description back in one response. The practical effect is that the first useful call is now the first call, which matters for stateless HTTP servers behind a load balancer.
What are the Mcp-Method and Mcp-Name headers for?
They surface the JSON-RPC method and the server name at the HTTP layer, where a proxy, gateway, or CDN can see them without parsing the body. If you run an MCP server behind nginx or an API gateway, this is the change that lets you route, rate limit, and log per method instead of treating every POST to /mcp as one opaque endpoint.
What do ttlMs and cacheScope do on list results?
They let a server tell a client how long a tools/list or resources/list result stays valid and how widely it may be shared. ttlMs is a lifetime in milliseconds. cacheScope says whether the answer is per user or common to everyone. For a server whose tool list is identical for every account, this removes a listing round trip on every session start, which is a real latency win.
Is the HTTP+SSE transport dead?
Deprecated, not dead. The window is one year from the 2026-07-28 revision. If you still publish an SSE endpoint, keep it up for now, but do not build anything new on it. Streamable HTTP is the transport to target, and it is what the OpenTweet hosted server at mcp.opentweet.io/mcp already speaks.
What is happening to Dynamic Client Registration?
DCR is moving to CIMD. If your server implements OAuth with dynamic registration, this is the piece of your auth stack that needs the most attention, because it is the one change in this revision that touches identity rather than transport. Servers that authenticate with a static bearer key, which is how OpenTweet API keys work, are unaffected.
Does the OpenTweet MCP server work with the new spec?
As of 31 August 2026 the hosted endpoint at mcp.opentweet.io/mcp negotiates protocol revision 2025-11-25. A client that requests 2026-07-28 is answered at 2025-11-25 rather than refused, so newer clients still connect. The endpoint runs Streamable HTTP with no session id generator, so it never issued Mcp-Session-Id and the SEP-2567 removal costs it nothing. Revisions move, so verify what your client negotiates rather than trusting a date in an article.
Keep exploring
Posting and scheduling on X from any MCP client, on either transport.
OpenTweet vs the X API
Post, schedule, and automate X without a developer account or the $200/mo minimum.
X DM outreach, human-approved
Find and qualify leads, AI-draft DMs, approve each one, and drip-send from your own account via API or MCP.
Post to X without an API
The clean, account-safe way to post to X from your code or an AI agent.
Twitter MCP Server
Give Claude, Cursor, and OpenClaw the ability to post to X. 36 tools included.
Developer docs
Quickstart, API keys, MCP setup, and the REST reference for posting to X from code or an agent.
XMCP vs OpenTweet
X's official MCP server bills per API call and cannot schedule. Compare it with the flat-fee hosted MCP.
MCP for AI agents
Connect your AI client to X in under two minutes, no X developer account.
Developer API and keys
REST endpoints, one bearer key, and usage tracking. Build on OpenTweet.
OpenTweet for AI agents
The posting layer for autonomous agents and automations that live on X.
Build an AI Twitter persona
Give your AI agent its own X account. Setup, cadence, and the rules that keep it safe.
Best MCP servers for social media
The 2026 ranked list. How the hosted OpenTweet MCP compares with the official X MCP and others.
Cheapest way to post to X via code
Flat fee vs pay-per-use. Why the $0.20 per-link fee flips the math past ~60 posts a month.
One endpoint, 36 tools, no session to lose
Point your MCP client at mcp.opentweet.io/mcp and post, schedule, and thread on X. No X developer account.
$11.99/month. Cancel anytime.