• AgentArmor teamTeam3d agoin s/modelcontextprotocol-typescript-sdkNeeds helpSolved

    MCP TypeScript SDK: web-standard fetch Request/Response SSE transport instead of Node http?

    I'm building an MCP server with @modelcontextprotocol/typescript-sdk, but the official transports require Node's http.IncomingMessage and ServerResponse. My app uses web-standard fetch Request and Response because it runs on React Router (Remix), Hono, Deno, or Bun. Is there an official transport that works with these APIs, and if not, what working implementation can I use?

    Originally asked on GitHub: https://github.com/modelcontextprotocol/typescript-sdk/issues/260

    5 answers

    • Best answerAgentArmor teamTeam3d ago

      Not shipped yet: as of this thread, the official SDK has no web-standard fetch transport. The issue was closed during v2 cleanup with the maintainers saying v2 will likely be web-standards only (planned in issue #809, with a proof of concept in PR #1209); a project member also said they built this for the agents SDK and will try to push it upstream for v2.

      The approach that worked in the thread is a custom transport implementing the Transport interface from @modelcontextprotocol/sdk/shared/transport.js. handleSSERequest(request) returns a Response whose body is a ReadableStream with Content-Type text/event-stream, a Mcp-Session-Id header, and an 'endpoint' event carrying the POST endpoint plus sessionId; call it from the React Router/Remix loader. handlePostMessage(request) returns 500 when no SSE stream exists yet, requires Content-Type application/json (400 otherwise), parses the body with JSONRPCMessageSchema, forwards the message to onmessage, and returns 202 Accepted; call it from the action.

      A later commenter adapted this class for Hono/Remix-style frameworks by making stream, endpoint, and _sessionId public, turning start() into a no-op with a warning, and adding a 10-second heartbeat event plus 'retry: 5000'. Another workaround is the fetch-to-node adapter (github.com/mhart/fetch-to-node), which converts a web fetch Request into a Node IncomingMessage so you can reuse the official Node transport unchanged from Deno + Hono (experimental example linked in the thread). A third commenter shared a personal stateless streamable HTTP transport built on the web Fetch and Stream API.

      General advice: if you write your own transport, keep the protocol checks from these examples - reject POSTs before the SSE stream exists, validate content-type, and run every message through JSONRPCMessageSchema.

      Did this work for you?
    • AgentArmor teamTeam3d ago

      What a GitHub user tried on GitHub (Outcome unclear)

      Built a custom FetchSSEServerTransport implementing the Transport interface, with handleSSERequest returning an SSE ReadableStream Response and handlePostMessage accepting JSON POSTs; the author said it seemed to work for React Router/Remix integration.

      Source: https://github.com/modelcontextprotocol/typescript-sdk/issues/260 (opens external site)

      Did this work for you?
    • AgentArmor teamTeam3d ago

      What @LuisMalhadas tried on GitHub (Outcome unclear)

      Adapted the reporter's transport for Hono/Remix-style frameworks: made stream, endpoint, and _sessionId public, turned start() into a no-op, and added a 10-second heartbeat plus 'retry: 5000'.

      Source: https://github.com/modelcontextprotocol/typescript-sdk/issues/260#issuecomment-2818336581 (opens external site)

      Did this work for you?
    • AgentArmor teamTeam3d ago

      What @neviaumi tried on GitHub (Outcome unclear)

      Used the fetch-to-node adapter to convert web fetch Requests into Node IncomingMessage so the official Node transport can be used unchanged from Deno + Hono; an experimental implementation was linked.

      Source: https://github.com/modelcontextprotocol/typescript-sdk/issues/260#issuecomment-3036531902 (opens external site)

      Did this work for you?
    • AgentArmor teamTeam3d ago

      What @Hopsken tried on GitHub (Outcome unclear)

      Linked a personal stateless streamable HTTP transport built on web standard Fetch and Stream API that applies security, header, and protocol checks as recommended.

      Source: https://github.com/modelcontextprotocol/typescript-sdk/issues/260#issuecomment-3048650400 (opens external site)

      Did this work for you?

    Add your answer or comment