{"version":3,"sources":["../../../../src/server/mcp/tools/get-errors.ts"],"sourcesContent":["/**\n * MCP tool for retrieving error state from Next.js dev server.\n *\n * This tool provides comprehensive error reporting including:\n * - Next.js global errors (e.g., next.config validation errors)\n * - Browser runtime errors with source-mapped stack traces\n * - Build errors from webpack/turbopack compilation\n *\n * For browser errors, it leverages the HMR infrastructure for server-to-browser communication.\n *\n * Flow:\n * MCP client → server generates request ID → HMR message to browser →\n * browser queries error overlay state → HMR response back → server performs source mapping →\n * combined with global errors → formatted output.\n */\nimport type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp'\nimport type { OverlayState } from '../../../next-devtools/dev-overlay/shared'\nimport {\n HMR_MESSAGE_SENT_TO_BROWSER,\n type HmrMessageSentToBrowser,\n} from '../../dev/hot-reloader-types'\nimport { formatErrors } from './utils/format-errors'\nimport {\n createBrowserRequest,\n handleBrowserPageResponse,\n DEFAULT_BROWSER_REQUEST_TIMEOUT_MS,\n} from './utils/browser-communication'\nimport { NextInstanceErrorState } from './next-instance-error-state'\nimport { mcpTelemetryTracker } from '../mcp-telemetry-tracker'\n\nexport function registerGetErrorsTool(\n server: McpServer,\n sendHmrMessage: (message: HmrMessageSentToBrowser) => void,\n getActiveConnectionCount: () => number\n) {\n server.registerTool(\n 'get_errors',\n {\n description:\n 'Get the current error state from the Next.js dev server, including Next.js global errors (e.g., next.config validation), browser runtime errors, and build errors with source-mapped stack traces',\n inputSchema: {},\n },\n async (_request) => {\n // Track telemetry\n mcpTelemetryTracker.recordToolCall('mcp/get_errors')\n\n try {\n const connectionCount = getActiveConnectionCount()\n if (connectionCount === 0) {\n return {\n content: [\n {\n type: 'text',\n text: 'No browser sessions connected. Please open your application in a browser to retrieve error state.',\n },\n ],\n }\n }\n\n const responses = await createBrowserRequest(\n HMR_MESSAGE_SENT_TO_BROWSER.REQUEST_CURRENT_ERROR_STATE,\n sendHmrMessage,\n getActiveConnectionCount,\n DEFAULT_BROWSER_REQUEST_TIMEOUT_MS\n )\n\n // The error state for each route\n // key is the route path, value is the error state\n const routesErrorState = new Map()\n for (const response of responses) {\n if (response.data) {\n routesErrorState.set(response.url, response.data)\n }\n }\n\n const hasRouteErrors = Array.from(routesErrorState.values()).some(\n (state) => state.errors.length > 0 || !!state.buildError\n )\n const hasInstanceErrors = NextInstanceErrorState.nextConfig.length > 0\n\n if (!hasRouteErrors && !hasInstanceErrors) {\n return {\n content: [\n {\n type: 'text',\n text:\n responses.length === 0\n ? 'No browser sessions responded.'\n : `No errors detected in ${responses.length} browser session(s).`,\n },\n ],\n }\n }\n\n const output = await formatErrors(\n routesErrorState,\n NextInstanceErrorState\n )\n\n return {\n content: [\n {\n type: 'text',\n text: output,\n },\n ],\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n }\n }\n }\n )\n}\n\n// Browser will first receive an HMR message from server to send back its error state.\n// The actual state is sent back in a subsequent HMR message, which is handled by this function\n// on the server.\nexport function handleErrorStateResponse(\n requestId: string,\n errorState: OverlayState | null,\n url: string | undefined\n) {\n handleBrowserPageResponse(\n requestId,\n errorState,\n url || ''\n )\n}\n"],"names":["handleErrorStateResponse","registerGetErrorsTool","server","sendHmrMessage","getActiveConnectionCount","registerTool","description","inputSchema","_request","mcpTelemetryTracker","recordToolCall","connectionCount","content","type","text","responses","createBrowserRequest","HMR_MESSAGE_SENT_TO_BROWSER","REQUEST_CURRENT_ERROR_STATE","DEFAULT_BROWSER_REQUEST_TIMEOUT_MS","routesErrorState","Map","response","data","set","url","hasRouteErrors","Array","from","values","some","state","errors","length","buildError","hasInstanceErrors","NextInstanceErrorState","nextConfig","output","formatErrors","error","Error","message","String","requestId","errorState","handleBrowserPageResponse"],"mappings":"AAAA;;;;;;;;;;;;;;CAcC;;;;;;;;;;;;;;;IA8GeA,wBAAwB;eAAxBA;;IA9FAC,qBAAqB;eAArBA;;;kCAVT;8BACsB;sCAKtB;wCACgC;qCACH;AAE7B,SAASA,sBACdC,MAAiB,EACjBC,cAA0D,EAC1DC,wBAAsC;IAEtCF,OAAOG,YAAY,CACjB,cACA;QACEC,aACE;QACFC,aAAa,CAAC;IAChB,GACA,OAAOC;QACL,kBAAkB;QAClBC,wCAAmB,CAACC,cAAc,CAAC;QAEnC,IAAI;YACF,MAAMC,kBAAkBP;YACxB,IAAIO,oBAAoB,GAAG;gBACzB,OAAO;oBACLC,SAAS;wBACP;4BACEC,MAAM;4BACNC,MAAM;wBACR;qBACD;gBACH;YACF;YAEA,MAAMC,YAAY,MAAMC,IAAAA,0CAAoB,EAC1CC,6CAA2B,CAACC,2BAA2B,EACvDf,gBACAC,0BACAe,wDAAkC;YAGpC,iCAAiC;YACjC,kDAAkD;YAClD,MAAMC,mBAAmB,IAAIC;YAC7B,KAAK,MAAMC,YAAYP,UAAW;gBAChC,IAAIO,SAASC,IAAI,EAAE;oBACjBH,iBAAiBI,GAAG,CAACF,SAASG,GAAG,EAAEH,SAASC,IAAI;gBAClD;YACF;YAEA,MAAMG,iBAAiBC,MAAMC,IAAI,CAACR,iBAAiBS,MAAM,IAAIC,IAAI,CAC/D,CAACC,QAAUA,MAAMC,MAAM,CAACC,MAAM,GAAG,KAAK,CAAC,CAACF,MAAMG,UAAU;YAE1D,MAAMC,oBAAoBC,8CAAsB,CAACC,UAAU,CAACJ,MAAM,GAAG;YAErE,IAAI,CAACP,kBAAkB,CAACS,mBAAmB;gBACzC,OAAO;oBACLvB,SAAS;wBACP;4BACEC,MAAM;4BACNC,MACEC,UAAUkB,MAAM,KAAK,IACjB,mCACA,CAAC,sBAAsB,EAAElB,UAAUkB,MAAM,CAAC,oBAAoB,CAAC;wBACvE;qBACD;gBACH;YACF;YAEA,MAAMK,SAAS,MAAMC,IAAAA,0BAAY,EAC/BnB,kBACAgB,8CAAsB;YAGxB,OAAO;gBACLxB,SAAS;oBACP;wBACEC,MAAM;wBACNC,MAAMwB;oBACR;iBACD;YACH;QACF,EAAE,OAAOE,OAAO;YACd,OAAO;gBACL5B,SAAS;oBACP;wBACEC,MAAM;wBACNC,MAAM,CAAC,OAAO,EAAE0B,iBAAiBC,QAAQD,MAAME,OAAO,GAAGC,OAAOH,QAAQ;oBAC1E;iBACD;YACH;QACF;IACF;AAEJ;AAKO,SAASxC,yBACd4C,SAAiB,EACjBC,UAA+B,EAC/BpB,GAAuB;IAEvBqB,IAAAA,+CAAyB,EACvBF,WACAC,YACApB,OAAO;AAEX","ignoreList":[0]}