HTTP/SSE transport for MCP.
Plug-based router providing JSON-RPC over HTTP POST and server-sent events for notifications. No Phoenix dependency.
Endpoints
POST /mcp-- receive JSON-RPC request, return responseGET /mcp/sse-- server-sent events stream for notificationsGET /health-- health check
Connection identity
Unlike stdio, this transport serves many clients at once, and each POST is a separate short-lived process with nothing tying it to a stream. That matters for elicitation: an approval prompt belongs to the client that triggered it, and only that client may answer it.
GET /mcp/sse therefore mints a session id and emits it as the stream's
first event:
event: endpoint
data: {"sessionId":"..."}A client echoes it on every POST via the mcp-session-id header. Requests
that carry it are attributed to that connection; requests without it are
unidentified, which is safe but limited -- an unidentified caller can make
ordinary requests and simply cannot elicit (an ASK resolves to the
machine-readable deny). It can never answer someone else's prompt, because
every unidentified request is a DISTINCT anonymous connection that owns
nothing.
Usage
Mount in a Plug pipeline or start standalone with Plug.Cowboy:
Plug.Cowboy.http(Raxol.MCP.Transport.SSE, [server: Raxol.MCP.Server], port: 4001)