next.js/packages/next/src/server/mcp/get-mcp-middleware.ts
get-mcp-middleware.ts45 lines1.4 KB
import type { ServerResponse, IncomingMessage } from 'http'
import {
  getOrCreateMcpServer,
  type McpServerOptions,
} from './get-or-create-mcp-server'
import { parseBody } from '../api-utils/node/parse-body'
import { StreamableHTTPServerTransport } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/streamableHttp'

export function getMcpMiddleware(options: McpServerOptions) {
  return async function (
    req: IncomingMessage,
    res: ServerResponse,
    next: () => void
  ): Promise<void> {
    const { pathname } = new URL(req.url || '', 'http://n')
    if (!pathname.startsWith('/_next/mcp')) {
      return next()
    }
    const mcpServer = getOrCreateMcpServer(options)
    const transport = new StreamableHTTPServerTransport({
      sessionIdGenerator: undefined,
    })
    try {
      res.on('close', () => {
        transport.close()
      })
      await mcpServer.connect(transport)
      const parsedBody = await parseBody(req, 1024 * 1024) // 1MB limit
      await transport.handleRequest(req, res, parsedBody)
    } catch (error) {
      if (!res.headersSent) {
        res.statusCode = 500
        res.setHeader('Content-Type', 'application/json; charset=utf-8')
        res.end(
          JSON.stringify({
            jsonrpc: '2.0',
            error: { code: -32000, message: 'Internal server error' },
            id: null,
          })
        )
      }
    }
  }
}
Quest for Codev2.0.0
/
SIGN IN