h3-mcp logoh3-mcp

SSE Streaming

The standalone GET stream, legacy only.

Note

The standalone GET stream was removed in 2026-07-28 — use subscriptions/listen instead.

Legacy clients open a GET connection to the MCP endpoint to receive server→client messages. Streaming is explicitly opt-in: without an onStream callback, GET answers 405, telling the client that this endpoint does not stream.

defineMcpHandler({
  name: "my-server",
  version: "1.0.0",
  onStream(stream, event) {
    // Push a JSON-RPC notification to the client
    stream.push({
      data: JSON.stringify({
        jsonrpc: "2.0",
        method: "custom/update",
        params: { status: "ready" },
      }),
    });
  },
  tools: [/* ... */],
});

stream is an h3 event stream. Anything you push must be a complete JSON-RPC message — this is the channel for notifications/resources/updated, notifications/tools/list_changed, and notifications/message.

#Resumption

The handler sends a priming event on connection so proxies flush the stream immediately, and honors resumption per SEP-1699: a reconnecting client sends Last-Event-ID (or a lastEventId query parameter), and the value is available as event.context.mcp.lastEventId.

Replaying what the client missed is up to you — keep a bounded ring buffer of recent events keyed by id, and push from the last acknowledged one:

onStream(stream, event) {
  const from = event.context.mcp?.lastEventId;
  for (const missed of recentEvents(from)) {
    stream.push({ id: missed.id, data: JSON.stringify(missed.message) });
  }
  const off = subscribe((message) => stream.push({ id: nextId(), data: JSON.stringify(message) }));
  // clean up when the client disconnects
  event.req.signal?.addEventListener("abort", off, { once: true });
}

Important

A stream is a server-lifetime resource held open by the client. Always unregister your source when the connection ends, and bound how many streams and how much replay history you are willing to keep — an open connection that nobody cleans up is the easiest resource leak to ship.

#Sessions and Auth

GET goes through the same checks as POST: auth, origin validation, and the session header when sessions are enabled. Body limits do not apply — a GET carries no body.

h3-mcp logo

h3-mcp  MCP servers, built on H3.