Add SSE streaming to the HTTP transport GET endpoint - #300
Draft
sarthak-19 wants to merge 1 commit into
Draft
Conversation
The HTTP transport's GET endpoint returned 405 unconditionally, so the only documented way to reach a WordPress MCP server was some form of STDIO on the client side (wp mcp-adapter serve locally, or the mcp-wordpress-remote proxy forwarding to HTTP). Clients that run in a hosted sandbox and can't launch local processes had no way to connect. GET now opens a real Server-Sent Events stream per the MCP Streamable HTTP transport, after the same session and protocol-version validation POST already performs. The stream is held open for a bounded, filterable duration (30s default) with periodic keep-alive pings, then closes; compliant clients reconnect automatically, so a slow or idle connection never ties up a PHP-FPM worker indefinitely. Streaming happens outside the normal WP_REST_Server JSON envelope via a scoped rest_pre_serve_request filter, so calling the handler directly (as tests do) never blocks. Clients that support remote/custom MCP connectors can now point straight at the site's existing REST endpoint over HTTPS with an Application Password, with no local proxy required.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## trunk #300 +/- ##
============================================
- Coverage 88.17% 87.97% -0.21%
- Complexity 1259 1277 +18
============================================
Files 54 55 +1
Lines 4120 4182 +62
============================================
+ Hits 3633 3679 +46
- Misses 487 503 +16
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #280.
The HTTP transport's
GETendpoint has always returned405 Method Not Allowed, so the only documented way to reach a WordPress MCP server was some form of STDIO on the client side:wp mcp-adapter serverunning locally, or the@automattic/mcp-wordpress-remoteproxy, which is also a locally-spawned process that just forwards to HTTP behind the scenes. Either way, the client needs to be able to launch a local process — which doesn't work for Claude in Chat/Cowork mode, since that runs in a hosted sandbox.This PR completes the existing
HttpTransport's Streamable HTTP support by implementing theGET(SSE) endpoint, so clients that support remote/custom MCP connectors can point straight at the site's REST endpoint over HTTPS (with an Application Password), without any local proxy.GETnow validates the session and protocol version exactly likePOSTdoes, then opens a realtext/event-streamresponse with periodic keep-alive comments.GET/SSE support entirely and stay compliant).mcp_adapter_enable_http_sse_stream(opt back out to the old405behavior),mcp_adapter_sse_stream_duration,mcp_adapter_sse_ping_interval.rest_pre_serve_requestfilter scoped to the specific request, so it only fires during a realWP_REST_Serverdispatch — calling the transport/handler directly (as the existing unit tests do) never blocks.curlexample; updated the stale "SSE not yet implemented" notes elsewhere.Out of scope: OAuth-based authorization for browser-driven connector setups. That's a much larger, security-sensitive feature (essentially an OAuth provider for WordPress) and deserves its own design discussion rather than being bundled into this fix. This PR only completes the transport-level piece; sites can already authenticate remote HTTP access today via Application Passwords.
Test plan
composer test(full PHPUnit suite viawp-env) — all passing.composer lint/composer phpstan— no new warnings or errors.wp-env: initialized a session overPOST, opened theGETSSE stream withcurl -N, confirmedContent-Type: text/event-stream, the initialstream-opencomment, apingkeep-alive at the configured interval, and correct400/404responses for missing/invalid sessions.mcp_adapter_enable_http_sse_streamto restore the previous405behavior.