T
TanStack2mo ago
extended-salmon

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

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
import { getEvent } from '@tanstack/react-start/server'

const event = getEvent()
const req = event.node.req
const res = event.node.res
7 Replies
sensitive-blue
sensitive-blue2mo ago
use getRequest and getResponse instead you have access to (almost?) the entire API that getEvent had, but in dedicated functions
extended-salmon
extended-salmonOP2mo ago
Is there a way to get the raw Node req/res . I want the request of type http.IncomingMessage .
sensitive-blue
sensitive-blue2mo ago
may i ask why you specifically need IncomingMessage ? This may be a case of an XY problem (you want something that can be solved in a better and simpler way)
extended-salmon
extended-salmonOP2mo ago
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>;
handleRequest(req: IncomingMessage & {
auth?: AuthInfo;
}, res: ServerResponse, parsedBody?: unknown): Promise<void>;
sensitive-blue
sensitive-blue2mo ago
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
}
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
extended-salmon
extended-salmonOP2mo ago
Hey @notKamui ,No problem. Implementing another way to make the MCP work. Thanks for helping.
conscious-sapphire
conscious-sapphire2mo ago
https://github.com/TanStack/create-tsrouter-app/blob/main/frameworks/react-cra/add-ons/mcp/assets/src/utils/mcp-handler.ts This will get you further down the road. But be warned that it's not good with asynchronous tools. You'll need to add more code in there to block after clientTransport.send.
GitHub
create-tsrouter-app/frameworks/react-cra/add-ons/mcp/assets/src/uti...
Create-tsrouter-app is drop-in replacement for create-react-app that builds TanStack Router based SPA applications - TanStack/create-tsrouter-app

Did you find this page helpful?