Building a WordPress MCP Server When the Spec Changed
July 29, 2026 0 comments
MCP 2026-07-28 is the fifth revision of the Model Context Protocol, and it retires sessions and the initialize handshake in favor of plain request and response. That change suits WordPress unusually well. PHP already treats every request as an independent, shared-nothing process, so a WordPress MCP server no longer has to fake a persistent connection it was never going to hold open anyway.
What’s on this page
- The spec changed the night before we submitted
- Why WordPress was already the right shape
- What broke was the handshake, and only the handshake
- We’re supporting both generations, not switching
- The timing call was harder than the code
- The small win: tool lists are cacheable now
- The rest of the changelog, for WordPress builders
- Simple survives revisions. Clever gets rewritten.
The spec changed the night before we submitted
On July 28, 2026 the Model Context Protocol shipped its fifth revision. We were hours away from uploading our WordPress MCP plugin to the plugin directory.
The headline change was a stateless core. MCP went from a bidirectional, stateful protocol to plain request and response. Sessions gone. The initialize and initialized handshake, retired outright. You can read the maintainers’ release notes for the full list, and Anthropic published its own summary of what’s rolling out across Claude the same day.
So the first question was not “should we adopt this.” It was “are we broken.”
Mostly, no. And for a deeply unglamorous reason.
Why WordPress was already the right shape
In the first week of the build we had a choice about how the server replies. The old spec allowed a persistent event stream, or a single JSON response per request. We took the single response. Not because we saw anything coming, but because server-sent events inside PHP, under a shared host’s process model, is a bad afternoon that turns into a bad week.
The simpler option was permitted. We took it and moved on.
Eight months later the protocol moved to exactly that shape. Every server that had built the sophisticated version now has a migration to do. We had already accidentally arrived.
There is a general point buried in that, and it’s the reason this release matters beyond one plugin. WordPress has always been shared-nothing. A PHP request boots, does its work, and dies with no memory of the request before it. The previous MCP spec fought that model by asking for a connection WordPress does not naturally hold. The new spec asks for exactly what WordPress already does.
What broke was the handshake, and only the handshake
initialize and initialized were the first code written on this project, the thing that proved a WordPress site could act as an MCP server at all. Both are now retired in favor of an optional server/discover call. The most protocol-shaped part of the build was the part that aged worst.
Everything downstream, reading site data and returning JSON, did not care at all.
The parts of our build that broke were the parts doing protocol ceremony. The parts doing the actual job carried on untouched, because they had never known what a session was.
Here is what a call looks like now. Note that there is nothing to establish first, and nothing stored between requests.
|
1 2 3 4 5 6 7 8 |
POST /mcp HTTP/1.1 MCP-Protocol-Version: 2026-07-28 Mcp-Method: tools/call Mcp-Name: search {"jsonrpc":"2.0","id":1,"method":"tools/call", "params":{"name":"search","arguments":{"q":"otters"}, "_meta":{"io.modelcontextprotocol/clientInfo":{"name":"my-app","version":"1.0"}}}} |
Protocol version, client identity and client capabilities all travel in the request itself. Any request can land on any instance behind an ordinary load balancer. For a plugin running on shared hosting, that is not an abstract scalability win. It removes the one requirement PHP was worst equipped to meet.
We’re supporting both generations, not switching
The new spec carries a formal deprecation policy with a twelve-month minimum window. That changes the calculation. A plugin installed on somebody else’s site has to work with whatever client that person happens to have. You do not get to pick.
So version negotiation decides per request, and nothing is stored between them. Two code paths, one endpoint, no session table.
Agencies will recognize the shape of this problem. If you maintain WordPress sites for other people, you already live with the gap between the version you’d like everyone to run and the version they actually run. Protocol support is the same discipline applied one layer down, and it accumulates the same way technical debt accumulates in WordPress: quietly, until a release forces the accounting.
The timing call was harder than the code
Directory review takes weeks. Submitting on the previous spec would have meant being reviewed, approved and listed as already out of date, in a category where the audience reads specifications for a living.
A day of work against several weeks of looking dated is not a close call.
The engineering question was answered in an hour. The publishing question was the harder one, because the cost of shipping something correct-but-stale is paid entirely in credibility, and you cannot patch that in version 1.0.1.
The small win: tool lists are cacheable now
One change we are quietly pleased about. List responses now carry a time-to-live and a cache scope.
Through the entire build, every time we added a capability, we had to disconnect and reconnect the client, because it had cached a stale catalog with no way to learn it was stale. Minor, constant, mildly maddening. Now the protocol handles it.
Nobody will write a headline about that one. It is the change that will show up most often in daily use.
The rest of the changelog, for WordPress builders
If you are building or evaluating anything MCP-shaped on WordPress, these are the items worth reading properly in the 2026-07-28 specification rather than skimming.
| What changed | What it means for a WordPress MCP server |
|---|---|
Sessions and the initialize/initialized handshake retired |
Delete the handshake code. Each request carries its own protocol version and client info in _meta. PHP’s request model already worked this way. |
Mcp-Method and Mcp-Name required as HTTP headers |
Your endpoint reads them, and anything in front of you must not strip them. Security plugins and aggressive WAF rules are the thing to test here. |
List responses carry ttlMs and cacheScope |
Clients stop re-fetching your tool catalog on every connect. Adding a tool no longer means telling users to reconnect. |
| Sampling, elicitation and roots replaced by Multi Round-Trip Requests | A tool needing user confirmation returns input_required, and the client retries with the answers attached. No held-open stream, which PHP was never going to hold. |
| Dynamic Client Registration deprecated in favor of Client ID Metadata Documents | The long-term path away from Application Passwords toward standard OAuth. Real, but not a migration to rush. |
| Legacy HTTP+SSE transport deprecated, twelve-month minimum window | If you built on the event stream, you have a year. If you built on single JSON responses, you have nothing to do. |
Simple survives revisions. Clever gets rewritten.
Budget for the specification moving. Not as a line in a risk register, as a genuine expectation.
You cannot predict which way it moves, so insulation is not foresight. What actually protected us was choosing the simplest option the spec permitted, at a moment when the constraint was our own platform rather than any theory about the future. And keeping the protocol layer thin and separate from the work, which is the same discipline we apply to controlled AI coding and to keeping AI-generated code clean.
- Take the simplest option the spec permits, especially when your own platform is the constraint
- Keep protocol handling in its own layer, separate from the code doing the actual work
- Support two spec generations rather than switching, if your code runs on installs you don’t control
- Negotiate the version per request and store nothing between requests
- Test that nothing in front of your endpoint strips
Mcp-MethodorMcp-Name - Read the deprecation policy before planning a migration, not after
We got this one right by accident. That is not a method, and I would not want anyone reading this to treat it as one. A hands-on guide to connecting a live WordPress site to Claude is in progress and will follow this post.
Thinking about connecting your WordPress site to an AI assistant?
We build and maintain WordPress for agencies and site owners in the US, UK and Australia, including the plumbing that makes a site readable by AI tools rather than just by browsers.
Related Posts
-
January 24, 2024
Why You Should Use ChatGPT Rather Than Google Search – ChatGPT vs Google Search
ChatGPT vs Google Search? Comparing ChatGPT with Google Search might initially seem unusual, but this comprehensive guide will illuminate why and when switching to ChatGPT can be more advantageous than relying solely on Google Search. In today's era, Google has long been the go-to platform, for accessing information. However, with
ChatGPT, Google SEO, Search Engine Optimization, SEO, Welcome0 comments -
April 15, 2025
GEO vs. Traditional SEO: Key Differences and How to Adapt
The blog title says GEO vs SEO; But it would be more as GEO and SEO. The digital marketing trends - with Google, are constantly changing. Now with the rise of AI-powered search experiences, a new player has entered the field: Generative Engine Optimization (GEO). While traditional Search Engine Optimization


