What we fixed in the 1.4.1 standards release

A governed MCP server is only as trustworthy as its edges, the small responses a client relies on to know what just happened. Version 1.4.1 is a standards-conformance release: seven fixes that bring OAuth errors, discovery, and tool responses in line with what MCP and OAuth clients actually expect, starting with a bug an external user found before we did.

Why standards conformance is a governance issue

It is tempting to treat protocol conformance as a formality separate from security, but the two are the same thing here. If an OAuth client cannot parse an error response, it cannot tell a user why a connection failed. If a tool call returns the wrong status code, a client may reconnect when it should have just retried, or retry when it should have stopped. None of that changes what the plugin allows an agent to do, but all of it changes whether the systems around the plugin, and the people reading their output, can trust what they are being told. Our security model is about staying inside the lines that matter. This release is about making sure the lines themselves are drawn where the spec says they should be.

Fixing the OAuth error shape, reported by a real user

The most visible fix started outside our own testing. OAuth errors were coming back in WordPress’s own {code, message, data} shape instead of the {error, error_description} shape RFC 6749 requires, which meant no standard OAuth client could actually read what had gone wrong. It reported a failure, just not one any client library knew how to parse. This has been wrong since the plugin’s first release, and it took an external user filing issue #68 to catch it. That is exactly the kind of report we want: something we can reproduce, name, and fix in the open, in the same spirit as the 1.3.0 security release. OAuth errors now carry the shape the spec defines, so a client can surface a real reason instead of a shape it does not recognize.

Malformed requests no longer slip past unlabeled

The error-shape bug had a companion. A malformed JSON body sent to an OAuth route was being rejected by WordPress before the plugin ever saw the request, which meant it escaped with the same wrong error shape and no cache headers at all. Fixing the shape at the plugin level did nothing for a request that never reached the plugin. Malformed OAuth requests are now handled directly, so a bad body gets the same correctly shaped error and the same cache headers as everything else, instead of falling through a gap between WordPress and the plugin.

Calling a disabled or unknown tool returns the right error

Calling a tool that does not exist, or one you switched off, was returning HTTP 404. That sounds like a small detail, but the MCP spec reserves 404 for one specific meaning: the session itself is dead, start over. Telling a client to reconnect over an ordinary mistake, like a typo in a tool name or a tool that is simply turned off, is the wrong signal, and a client that takes it seriously ends up tearing down a perfectly good connection. Calling a disabled or unknown tool now returns a proper JSON-RPC error instead, describing the actual problem. A session that has genuinely expired still returns 404, that meaning is untouched.

Discovery stopped advertising an endpoint that does not work

The OAuth discovery document was advertising a client-registration endpoint even when dynamic client registration was off, which is the default on every fresh install. A brand-new site was pointing connecting clients at a URL that does not answer. Discovery now only advertises the registration endpoint when it is actually enabled, so what a client is told about the server matches what the server will actually do. If you are setting up a connection for the first time, connecting a client walks through what discovery should look like end to end, and the client list covers what is supported today.

Every tool now declares openWorldHint: false

The MCP schema has a field called openWorldHint that tells a client whether a tool can reach the open internet. None of this plugin’s tools declared it, and an absent value reads as “yes, it might.” That was never true. The plugin makes no outbound requests to any AI provider or external service, your client connects in, the plugin never reaches out, and that has been the design since day one. Every tool now explicitly declares openWorldHint: false, so the schema states in writing what the plugin has always actually done, instead of leaving a client to assume the more permissive default.

Two smaller header fixes

Two more fixes round out the release, both about the headers around credentials rather than the credentials themselves. Responses that carry a credential, including the response that hands out an OAuth token, were missing Pragma: no-cache next to Cache-Control: no-store. Some older caches still look at Pragma before Cache-Control, so a credentialed response is now marked not to be cached by either signal. And rate-limited OAuth responses now send a Retry-After header, so a client that gets throttled knows how long to wait instead of guessing or hammering the endpoint again immediately.

None of these seven fixes change what the plugin lets an agent do. What they change is whether the clients and libraries talking to it can trust the shape of what comes back. That is correctness too, just a quieter kind. If you run the plugin, 1.4.1 is worth taking.