next
Version:
The React Framework
88 lines (87 loc) • 4.16 kB
JavaScript
/**
* MCP tool for retrieving error state from Next.js dev server.
*
* This tool provides comprehensive error reporting including:
* - Next.js global errors (e.g., next.config validation errors)
* - Browser runtime errors with source-mapped stack traces
* - Build errors from webpack/turbopack compilation
*
* For browser errors, it leverages the HMR infrastructure for server-to-browser communication.
*
* Flow:
* MCP client → server generates request ID → HMR message to browser →
* browser queries error overlay state → HMR response back → server performs source mapping →
* combined with global errors → formatted output.
*/ import { HMR_MESSAGE_SENT_TO_BROWSER } from '../../dev/hot-reloader-types';
import { formatErrors } from './utils/format-errors';
import { createBrowserRequest, handleBrowserPageResponse, DEFAULT_BROWSER_REQUEST_TIMEOUT_MS } from './utils/browser-communication';
import { NextInstanceErrorState } from './next-instance-error-state';
import { mcpTelemetryTracker } from '../mcp-telemetry-tracker';
export function registerGetErrorsTool(server, sendHmrMessage, getActiveConnectionCount) {
server.registerTool('get_errors', {
description: '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',
inputSchema: {}
}, async (_request)=>{
// Track telemetry
mcpTelemetryTracker.recordToolCall('mcp/get_errors');
try {
const connectionCount = getActiveConnectionCount();
if (connectionCount === 0) {
return {
content: [
{
type: 'text',
text: 'No browser sessions connected. Please open your application in a browser to retrieve error state.'
}
]
};
}
const responses = await createBrowserRequest(HMR_MESSAGE_SENT_TO_BROWSER.REQUEST_CURRENT_ERROR_STATE, sendHmrMessage, getActiveConnectionCount, DEFAULT_BROWSER_REQUEST_TIMEOUT_MS);
// The error state for each route
// key is the route path, value is the error state
const routesErrorState = new Map();
for (const response of responses){
if (response.data) {
routesErrorState.set(response.url, response.data);
}
}
const hasRouteErrors = Array.from(routesErrorState.values()).some((state)=>state.errors.length > 0 || !!state.buildError);
const hasInstanceErrors = NextInstanceErrorState.nextConfig.length > 0;
if (!hasRouteErrors && !hasInstanceErrors) {
return {
content: [
{
type: 'text',
text: responses.length === 0 ? 'No browser sessions responded.' : `No errors detected in ${responses.length} browser session(s).`
}
]
};
}
const output = await formatErrors(routesErrorState, NextInstanceErrorState);
return {
content: [
{
type: 'text',
text: output
}
]
};
} catch (error) {
return {
content: [
{
type: 'text',
text: `Error: ${error instanceof Error ? error.message : String(error)}`
}
]
};
}
});
}
// Browser will first receive an HMR message from server to send back its error state.
// The actual state is sent back in a subsequent HMR message, which is handled by this function
// on the server.
export function handleErrorStateResponse(requestId, errorState, url) {
handleBrowserPageResponse(requestId, errorState, url || '');
}
//# sourceMappingURL=get-errors.js.map