Skip to content

HTTP transport returns 200 instead of 202 Accepted for JSON-RPC notifications #125

@galatanovidiu

Description

@galatanovidiu

Summary

The HTTP transport returns HTTP 200 with a null body for JSON-RPC notifications, but the MCP specification (2025-06-18) requires HTTP 202 Accepted with no body.

Current Behavior

When a client sends a notification (JSON-RPC message without an id field, e.g., notifications/initialized):

  • Server returns: HTTP 200 with null body

Expected Behavior

Per MCP Streamable HTTP Transport specification (2025-06-18):

If the input is a JSON-RPC response or notification: If the server accepts the input, the server MUST return HTTP status code 202 Accepted with no body.

Impact

Strict MCP clients like OpenAI Codex CLI (using the rmcp Rust crate) interpret HTTP 200 for notifications as a protocol error, causing the transport channel to close during the handshake:

MCP client for `WordPress` failed to start: MCP startup failed: handshaking with MCP server failed:
Send message error Transport [...] error: Transport channel closed, when send initialized notification

Files to Fix

  1. includes/Transport/Infrastructure/HttpRequestHandler.php (line ~131)

    • Add check for null === $response_body before returning
    • Return new \WP_REST_Response( null, 202 ) for notifications
  2. tests/Unit/Transport/Infrastructure/HttpRequestHandlerTest.php (line 287)

    • Update test_handle_request_post_notification() to expect HTTP 202 instead of 200

Proposed Fix

// Per MCP spec 2025-06-18: Notifications return HTTP 202 Accepted with no body.
// A null response_body indicates only notifications were processed (no requests with IDs).
if ( null === $response_body ) {
    return new \WP_REST_Response( null, 202 );
}

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions