#TanStack Start does not expose Node’s raw req/res

11 messages · Page 1 of 1 (latest)

vernal shard
#

After upgrading from @tanstack/react-start 1.131.x to 1.132.10, getEvent() is no longer exported from @tanstack/react-start/server.
Previously there was getEvent() function to access Node req/res via event.node.req and event.node.res

import { getEvent } from '@tanstack/react-start/server'

const event = getEvent()
const req = event.node.req
const res = event.node.res
noble leaf
#

you have access to (almost?) the entire API that getEvent had, but in dedicated functions

vernal shard
#

Is there a way to get the raw Node req/res . I want the request of type http.IncomingMessage .

noble leaf
vernal shard
#

Because I’m integrating the MCP SDK’s Streamable HTTP transport, which requires Node’s IncomingMessage/ServerResponse. Its handleRequest signature explicitly takes Node types:

handleRequest(req: IncomingMessage & {
    auth?: AuthInfo;
}, res: ServerResponse, parsedBody?: unknown): Promise<void>;
noble leaf
#

hmm

#

maybe you could get away with mocking the conversion

#
import { IncomingMessage } from 'http'
import { Socket } from 'net'

export async function requestToIncomingMessage(webRequest: Request) {
  const { method, headers, url, body } = webRequest
  const socket = new Socket() // dummy socket

  const incoming = new IncomingMessage(socket)
  incoming.method = method
  incoming.url = new URL(url).pathname + new URL(url).search
  incoming.headers = Object.fromEntries(headers.entries())

  if (body) {
    const reader = body.getReader()
    ;(async () => {
      try {
        while (true) {
          const { done, value } = await reader.read()
          if (done) break
          incoming.push(value)
        }
      } catch (err) {
        incoming.destroy(err as Error)
        return
      }
      incoming.push(null) // end of stream
    })()
  } else {
    incoming.push(null) // no body
  }

  return incoming
}

export async function responseToServerResponse(
  response: Response,
) {
  const serverResponse = new ServerResponse({} as IncomingMessage)
  serverResponse.statusCode = response.status
  serverResponse.statusMessage = response.statusText
  response.headers.forEach((value, key) => {
    serverResponse.setHeader(key, value)
  })
  const body = await response.arrayBuffer()
  serverResponse.end(body)
  return serverResponse
}
#

i dont think this works

vernal shard
#

Hey @noble leaf ,No problem. Implementing another way to make the MCP work. Thanks for helping.