VOOZH about

URL: https://deepwiki.com/WordPress/mcp-adapter/3.2-request-processing-pipeline

⇱ Request Processing Pipeline | WordPress/mcp-adapter | DeepWiki


Loading...
Menu

Request Processing Pipeline

Purpose and Scope

This page documents the complete request processing pipeline for MCP (Model Context Protocol) requests in the WordPress MCP Adapter. It covers the flow from HTTP transport entry through JSON-RPC processing, session validation, method routing, handler execution, and response building.

For information about specific handler implementations (tools, resources, prompts), see Tools, Resources, and Prompts. For transport-level permission checking, see Transport Permissions. For session storage and lifecycle details, see Session Management.

Overview

The request processing pipeline transforms incoming HTTP requests into MCP method executions and returns JSON-RPC 2.0 formatted responses. The pipeline implements the MCP 2025-06-18 specification for HTTP-based communication with support for:

  • JSON-RPC 2.0 request/response format
  • Session-based request validation
  • Batch request processing
  • Notification handling (requests without IDs)
  • Error standardization with HTTP status code mapping
  • Observability metadata extraction

The pipeline consists of several layers that progressively refine and route the request:

  1. HTTP Layer: REST API endpoint handling and transport permissions
  2. Request Context Layer: HTTP request parsing and session extraction
  3. JSON-RPC Layer: Message validation and format compliance
  4. Session Layer: Session validation and lifecycle management
  5. Routing Layer: MCP method to handler mapping
  6. Execution Layer: Handler invocation and result processing
  7. Response Layer: JSON-RPC response building and HTTP status mapping

Sources: includes/Transport/HttpTransport.php includes/Transport/Infrastructure/HttpRequestHandler.php1-277 includes/Transport/Infrastructure/RequestRouter.php1-245

Complete Request Flow

The following diagram shows the complete request flow through all pipeline layers:


Sources: includes/Transport/HttpTransport.php includes/Transport/Infrastructure/HttpRequestHandler.php46-277 includes/Transport/Infrastructure/RequestRouter.php51-130 tests/Integration/HttpTransportTest.php78-118

HTTP Request Entry Point

HttpTransport Class

The HttpTransport class is the entry point for all HTTP-based MCP communication. It registers a REST API endpoint at /wp-json/{namespace}/{route} and implements the McpTransportInterface.

Key responsibilities:

  • REST API endpoint registration via register_routes()
  • Permission checking via check_permission()
  • Request delegation to HttpRequestHandler

The transport is configured during server creation and receives an McpTransportContext containing all necessary dependencies.


Sources: includes/Transport/HttpTransport.php includes/Core/McpServer.php tests/Integration/HttpTransportTest.php97-118

Transport Permission Checking

Before any request processing begins, check_permission() validates that the requester has authorization to access the MCP server. This is a server-wide gatekeeper that blocks all requests if permission is denied.

Permission evaluation order:

  1. Execute transport_permission_callback if configured
  2. On exception or WP_Error, fall back to default check
  3. Default: is_user_logged_in() with capability check via current_user_can('read')
  4. Capability is filterable via mcp_adapter_default_transport_permission_user_capability

Sources: includes/Transport/HttpTransport.php docs/guides/transport-permissions.md tests/Integration/HttpTransportTest.php528-803

Request Context Extraction

HttpRequestContext

The HttpRequestContext class extracts and stores essential request information for the processing pipeline:

PropertyTypeDescription
$methodstringHTTP method (POST, GET, DELETE)
$bodyarray|nullDecoded JSON request body
$headersarrayHTTP request headers
$session_idstring|nullExtracted from Mcp-Session-Id header
$requestWP_REST_RequestOriginal WordPress REST request

The context is created once at the start of request handling and passed through the pipeline, avoiding repeated parsing of the same request data.

Sources: includes/Transport/Infrastructure/HttpRequestContext.php includes/Transport/Infrastructure/HttpRequestHandler.php46-67

HTTP Method Routing

The HttpRequestHandler class routes HTTP methods to appropriate processing strategies based on the MCP specification:


Sources: includes/Transport/Infrastructure/HttpRequestHandler.php46-67 tests/Unit/Transport/Infrastructure/HttpRequestHandlerTest.php63-75 tests/Integration/HttpTransportTest.php325-335

POST Request Processing

POST requests contain JSON-RPC 2.0 messages to be executed on the server. The handler:

  1. Validates JSON syntax in request body
  2. Normalizes single messages or batch arrays
  3. Processes each message individually
  4. Returns single response or batch array

Sources: includes/Transport/Infrastructure/HttpRequestHandler.php77-131 tests/Integration/HttpTransportTest.php78-214

DELETE Request Processing

DELETE requests terminate active sessions:

  1. Extract Mcp-Session-Id header
  2. Validate header presence
  3. Call HttpSessionValidator::terminate_session()
  4. Return 200 with null body on success

Sources: includes/Transport/Infrastructure/HttpRequestHandler.php225-234 tests/Integration/HttpTransportTest.php340-385

JSON-RPC Message Processing

Message Validation and Normalization

The JsonRpcResponseBuilder class provides utilities for processing JSON-RPC 2.0 messages:

Key methods:

  • is_batch_request(array $body) - Detects array of messages vs single message
  • normalize_messages(array $body) - Converts single message to array for uniform processing
  • validate_jsonrpc_message(array $message) - Validates required fields and version
  • process_messages(array $messages, bool $is_batch, callable $processor) - Processes messages and handles batch/single response logic

Validation rules:

  • jsonrpc field must equal "2.0"
  • Requests must have method field (string)
  • Requests with id field expect responses
  • Notifications (no id field) do not receive responses
  • id can be string, number, or null

Sources: includes/Transport/Infrastructure/JsonRpcResponseBuilder.php includes/Transport/Infrastructure/HttpRequestHandler.php112-159

Request vs Notification Handling

The pipeline distinguishes between two message types:

TypeCharacteristicsResponse
RequestHas id fieldJSON-RPC response with matching id
NotificationNo id fieldNo response (returns null)

This distinction is critical for batch processing, where some messages may be notifications:


Sources: includes/Transport/Infrastructure/HttpRequestHandler.php141-159 tests/Integration/HttpTransportTest.php120-157

Batch Request Processing

Batch requests are arrays of multiple JSON-RPC messages. The pipeline processes each message independently and returns an array of responses:

Processing rules:

  1. Validate each message independently
  2. Process valid messages in order
  3. Skip notifications (contribute no response)
  4. Return array of responses in same order
  5. If all messages are notifications, return null body with 200 status

Sources: includes/Transport/Infrastructure/JsonRpcResponseBuilder.php includes/Transport/Infrastructure/HttpRequestHandler.php112-131 tests/Integration/HttpTransportTest.php159-214

Session Management Integration

Session Validation Flow

All MCP requests except initialize must include a valid session ID in the Mcp-Session-Id header. The validation flow is:


Sources: includes/Transport/Infrastructure/HttpRequestHandler.php169-203 includes/Transport/Infrastructure/HttpSessionValidator.php tests/Integration/HttpTransportTest.php405-504

Session Creation on Initialize

When processing an initialize request with HttpRequestContext, the pipeline:

  1. Processes initialize request through InitializeHandler
  2. If successful and no existing session, calls HttpSessionValidator::create_session()
  3. Stores returned session ID in result as _session_id
  4. HttpRequestHandler extracts _session_id and adds as response header
  5. Removes _session_id from response body before returning to client

This ensures the session is created only after successful initialization and the session ID is communicated to the client via the standard Mcp-Session-Id header.

Sources: includes/Transport/Infrastructure/RequestRouter.php147-172 includes/Transport/Infrastructure/HttpRequestHandler.php192-203 includes/Transport/Infrastructure/HttpSessionValidator.php

MCP Method Routing

RequestRouter Class

The RequestRouter class is the central dispatcher for MCP protocol methods. It maps method names to handler functions and manages observability integration.

Method-to-handler mapping:

MCP MethodHandlerReturns
initializeInitializeHandler::handle()Server capabilities
pingSystemHandler::ping()Empty object
tools/listToolsHandler::list_tools()Array of tools
tools/list/allToolsHandler::list_all_tools()All tools (internal)
tools/callToolsHandler::call_tool()Tool execution result
resources/listResourcesHandler::list_resources()Array of resources
resources/readResourcesHandler::read_resource()Resource contents
prompts/listPromptsHandler::list_prompts()Array of prompts
prompts/getPromptsHandler::get_prompt()Prompt with messages
logging/setLevelSystemHandler::set_logging_level()Empty object
completion/completeSystemHandler::complete()Completion result
roots/listSystemHandler::list_roots()Array of roots

Unknown methods return METHOD_NOT_FOUND error.

Sources: includes/Transport/Infrastructure/RequestRouter.php65-82 tests/Unit/Transport/Infrastructure/RequestRouterTest.php74-204

Route Request Processing

The route_request() method orchestrates the complete handler execution lifecycle:


Sources: includes/Transport/Infrastructure/RequestRouter.php51-130 tests/Unit/Transport/Infrastructure/RequestRouterTest.php260-291

Initialize with Session Creation

The initialize method receives special handling when an HttpRequestContext is provided:

  1. Calls InitializeHandler::handle()
  2. If successful and no existing session, creates new session
  3. Stores session ID in result as _session_id (extracted by RequestRouter)
  4. Session ID flows back to HttpRequestHandler for header injection

This coordination happens in RequestRouter::handle_initialize_with_session().

Sources: includes/Transport/Infrastructure/RequestRouter.php147-172 tests/Unit/Transport/Infrastructure/RequestRouterTest.php111-135

Handler Execution and Metadata

Handler Invocation

Handlers receive request parameters and return results with optional metadata:

Input:

  • array $params - Request parameters from JSON-RPC message
  • mixed $request_id - Request ID for response correlation (string, number, or null)

Output format:


The _metadata key is a convention used throughout the system. Handlers can add arbitrary tags that will be merged with common request tags before observability recording.

Sources: includes/Handlers/Tools/ToolsHandler.php includes/Handlers/Resources/ResourcesHandler.php includes/Transport/Infrastructure/RequestRouter.php86-96

Metadata Extraction and Observability

The RequestRouter extracts metadata from handler responses and integrates it with observability:

Metadata flow:

  1. Handler returns result with _metadata key
  2. RequestRouter extracts _metadata array (line 87-88 in RequestRouter.php)
  3. Merges with common tags (method, transport, server_id, params, request_id, session_id)
  4. Adds status tag ('success' or 'error')
  5. Calls observability_handler->record_event('mcp.request', tags, duration)
  6. Strips _metadata from result before returning (line 88)

This pattern ensures observability data never leaks to clients while providing rich context for monitoring.

Sources: includes/Transport/Infrastructure/RequestRouter.php86-111 includes/Infrastructure/Observability/ tests/Unit/Transport/Infrastructure/RequestRouterTest.php260-291

Error Handling in Routing

When handler execution fails, the RequestRouter provides consistent error handling:

Exception handling:

  1. Catch any \Throwable from handler
  2. Calculate duration up to exception point
  3. Add exception metadata (error_type, error_category)
  4. Record observability event with error status
  5. Return INTERNAL_ERROR JSON-RPC error

Error categorization:

Exception ClassCategory
ArgumentCountErrorarguments
Errorsystem
InvalidArgumentExceptionvalidation
LogicExceptionlogic
RuntimeExceptionexecution
TypeErrortype
Otherunknown

Sources: includes/Transport/Infrastructure/RequestRouter.php112-129 includes/Transport/Infrastructure/RequestRouter.php186-204 tests/Unit/Transport/Infrastructure/RequestRouterTest.php206-230

Response Building

JsonRpcResponseBuilder

The JsonRpcResponseBuilder class provides static methods for constructing JSON-RPC 2.0 compliant responses:

Success response format:


Error response format:


The builder ensures the id field preserves its original type (string, number, or null) as required by JSON-RPC 2.0.

Sources: includes/Transport/Infrastructure/JsonRpcResponseBuilder.php includes/Transport/Infrastructure/HttpRequestHandler.php199-202

HTTP Status Code Mapping

The McpErrorFactory::get_http_status_for_error() method maps JSON-RPC error codes to HTTP status codes:

JSON-RPC Error CodeHTTP StatusDescription
-32700 (PARSE_ERROR)400Invalid JSON
-32600 (INVALID_REQUEST)400Invalid JSON-RPC
-32601 (METHOD_NOT_FOUND)404Method not found
-32602 (INVALID_PARAMS)400Invalid parameters
-32603 (INTERNAL_ERROR)500Internal error
-32000 (UNAUTHORIZED)401Authentication required
-32001 (FORBIDDEN)403Permission denied
Other500Default to internal error

This mapping only applies to single (non-batch) requests. Batch requests always return 200 status with individual errors in the response array.

Sources: includes/Infrastructure/ErrorHandling/McpErrorFactory.php includes/Transport/Infrastructure/HttpRequestHandler.php125-128 tests/Integration/HttpTransportTest.php216-229

Request Sanitization for Observability

Parameter Sanitization

To prevent sensitive data from appearing in observability logs, the RequestRouter sanitizes request parameters:

Sanitization strategy:

  • Extract only safe, scalar fields: name, protocolVersion, uri
  • Include client name from clientInfo.name if available
  • For tool calls, log argument count and keys (not values)
  • Discard all other parameter data

Example sanitized params:


This provides useful debugging information without exposing user data or sensitive arguments.

Sources: includes/Transport/Infrastructure/RequestRouter.php206-244 includes/Transport/Infrastructure/RequestRouter.php56-63

Complete Component Map

The following diagram maps natural language concepts to concrete code entities:


Sources: includes/Transport/HttpTransport.php includes/Transport/Infrastructure/HttpRequestHandler.php1-277 includes/Transport/Infrastructure/HttpRequestContext.php includes/Transport/Infrastructure/JsonRpcResponseBuilder.php includes/Transport/Infrastructure/HttpSessionValidator.php includes/Transport/Infrastructure/RequestRouter.php1-245 includes/Handlers/

Refresh this wiki

On this page