feat(blog): add file-based blog with dynamic slugs, MDX content and layout shell
- Introduced blog routing using Next.js App Router - Implemented dynamic [slug] pages for blog posts - Added MDX-based content loading via lib/posts - Integrated shared TopBar layout with navigation - Established clear content, lib and component separation
This commit is contained in:
3
apps/public-web/node_modules/next/dist/server/mcp/get-mcp-middleware.d.ts
generated
vendored
Normal file
3
apps/public-web/node_modules/next/dist/server/mcp/get-mcp-middleware.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import type { ServerResponse, IncomingMessage } from 'http';
|
||||
import { type McpServerOptions } from './get-or-create-mcp-server';
|
||||
export declare function getMcpMiddleware(options: McpServerOptions): (req: IncomingMessage, res: ServerResponse, next: () => void) => Promise<void>;
|
||||
49
apps/public-web/node_modules/next/dist/server/mcp/get-mcp-middleware.js
generated
vendored
Normal file
49
apps/public-web/node_modules/next/dist/server/mcp/get-mcp-middleware.js
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "getMcpMiddleware", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return getMcpMiddleware;
|
||||
}
|
||||
});
|
||||
const _getorcreatemcpserver = require("./get-or-create-mcp-server");
|
||||
const _parsebody = require("../api-utils/node/parse-body");
|
||||
const _streamableHttp = require("next/dist/compiled/@modelcontextprotocol/sdk/server/streamableHttp");
|
||||
function getMcpMiddleware(options) {
|
||||
return async function(req, res, next) {
|
||||
const { pathname } = new URL(req.url || '', 'http://n');
|
||||
if (!pathname.startsWith('/_next/mcp')) {
|
||||
return next();
|
||||
}
|
||||
const mcpServer = (0, _getorcreatemcpserver.getOrCreateMcpServer)(options);
|
||||
const transport = new _streamableHttp.StreamableHTTPServerTransport({
|
||||
sessionIdGenerator: undefined
|
||||
});
|
||||
try {
|
||||
res.on('close', ()=>{
|
||||
transport.close();
|
||||
});
|
||||
await mcpServer.connect(transport);
|
||||
const parsedBody = await (0, _parsebody.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
|
||||
}));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
//# sourceMappingURL=get-mcp-middleware.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/get-mcp-middleware.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/get-mcp-middleware.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/server/mcp/get-mcp-middleware.ts"],"sourcesContent":["import type { ServerResponse, IncomingMessage } from 'http'\nimport {\n getOrCreateMcpServer,\n type McpServerOptions,\n} from './get-or-create-mcp-server'\nimport { parseBody } from '../api-utils/node/parse-body'\nimport { StreamableHTTPServerTransport } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/streamableHttp'\n\nexport function getMcpMiddleware(options: McpServerOptions) {\n return async function (\n req: IncomingMessage,\n res: ServerResponse,\n next: () => void\n ): Promise<void> {\n const { pathname } = new URL(req.url || '', 'http://n')\n if (!pathname.startsWith('/_next/mcp')) {\n return next()\n }\n const mcpServer = getOrCreateMcpServer(options)\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n })\n try {\n res.on('close', () => {\n transport.close()\n })\n await mcpServer.connect(transport)\n const parsedBody = await parseBody(req, 1024 * 1024) // 1MB limit\n await transport.handleRequest(req, res, parsedBody)\n } catch (error) {\n if (!res.headersSent) {\n res.statusCode = 500\n res.setHeader('Content-Type', 'application/json; charset=utf-8')\n res.end(\n JSON.stringify({\n jsonrpc: '2.0',\n error: { code: -32000, message: 'Internal server error' },\n id: null,\n })\n )\n }\n }\n }\n}\n"],"names":["getMcpMiddleware","options","req","res","next","pathname","URL","url","startsWith","mcpServer","getOrCreateMcpServer","transport","StreamableHTTPServerTransport","sessionIdGenerator","undefined","on","close","connect","parsedBody","parseBody","handleRequest","error","headersSent","statusCode","setHeader","end","JSON","stringify","jsonrpc","code","message","id"],"mappings":";;;;+BAQgBA;;;eAAAA;;;sCAJT;2BACmB;gCACoB;AAEvC,SAASA,iBAAiBC,OAAyB;IACxD,OAAO,eACLC,GAAoB,EACpBC,GAAmB,EACnBC,IAAgB;QAEhB,MAAM,EAAEC,QAAQ,EAAE,GAAG,IAAIC,IAAIJ,IAAIK,GAAG,IAAI,IAAI;QAC5C,IAAI,CAACF,SAASG,UAAU,CAAC,eAAe;YACtC,OAAOJ;QACT;QACA,MAAMK,YAAYC,IAAAA,0CAAoB,EAACT;QACvC,MAAMU,YAAY,IAAIC,6CAA6B,CAAC;YAClDC,oBAAoBC;QACtB;QACA,IAAI;YACFX,IAAIY,EAAE,CAAC,SAAS;gBACdJ,UAAUK,KAAK;YACjB;YACA,MAAMP,UAAUQ,OAAO,CAACN;YACxB,MAAMO,aAAa,MAAMC,IAAAA,oBAAS,EAACjB,KAAK,OAAO,MAAM,YAAY;;YACjE,MAAMS,UAAUS,aAAa,CAAClB,KAAKC,KAAKe;QAC1C,EAAE,OAAOG,OAAO;YACd,IAAI,CAAClB,IAAImB,WAAW,EAAE;gBACpBnB,IAAIoB,UAAU,GAAG;gBACjBpB,IAAIqB,SAAS,CAAC,gBAAgB;gBAC9BrB,IAAIsB,GAAG,CACLC,KAAKC,SAAS,CAAC;oBACbC,SAAS;oBACTP,OAAO;wBAAEQ,MAAM,CAAC;wBAAOC,SAAS;oBAAwB;oBACxDC,IAAI;gBACN;YAEJ;QACF;IACF;AACF","ignoreList":[0]}
|
||||
14
apps/public-web/node_modules/next/dist/server/mcp/get-or-create-mcp-server.d.ts
generated
vendored
Normal file
14
apps/public-web/node_modules/next/dist/server/mcp/get-or-create-mcp-server.d.ts
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp';
|
||||
import type { HmrMessageSentToBrowser } from '../dev/hot-reloader-types';
|
||||
import type { NextConfigComplete } from '../config-shared';
|
||||
export interface McpServerOptions {
|
||||
projectPath: string;
|
||||
distDir: string;
|
||||
nextConfig: NextConfigComplete;
|
||||
pagesDir: string | undefined;
|
||||
appDir: string | undefined;
|
||||
sendHmrMessage: (message: HmrMessageSentToBrowser) => void;
|
||||
getActiveConnectionCount: () => number;
|
||||
getDevServerUrl: () => string | undefined;
|
||||
}
|
||||
export declare const getOrCreateMcpServer: (options: McpServerOptions) => McpServer;
|
||||
41
apps/public-web/node_modules/next/dist/server/mcp/get-or-create-mcp-server.js
generated
vendored
Normal file
41
apps/public-web/node_modules/next/dist/server/mcp/get-or-create-mcp-server.js
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "getOrCreateMcpServer", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return getOrCreateMcpServer;
|
||||
}
|
||||
});
|
||||
const _mcp = require("next/dist/compiled/@modelcontextprotocol/sdk/server/mcp");
|
||||
const _getprojectmetadata = require("./tools/get-project-metadata");
|
||||
const _geterrors = require("./tools/get-errors");
|
||||
const _getpagemetadata = require("./tools/get-page-metadata");
|
||||
const _getlogs = require("./tools/get-logs");
|
||||
const _getserveractionbyid = require("./tools/get-server-action-by-id");
|
||||
const _getroutes = require("./tools/get-routes");
|
||||
let mcpServer;
|
||||
const getOrCreateMcpServer = (options)=>{
|
||||
if (mcpServer) {
|
||||
return mcpServer;
|
||||
}
|
||||
mcpServer = new _mcp.McpServer({
|
||||
name: 'Next.js MCP Server',
|
||||
version: '0.2.0'
|
||||
});
|
||||
(0, _getprojectmetadata.registerGetProjectMetadataTool)(mcpServer, options.projectPath, options.getDevServerUrl);
|
||||
(0, _geterrors.registerGetErrorsTool)(mcpServer, options.sendHmrMessage, options.getActiveConnectionCount);
|
||||
(0, _getpagemetadata.registerGetPageMetadataTool)(mcpServer, options.sendHmrMessage, options.getActiveConnectionCount);
|
||||
(0, _getlogs.registerGetLogsTool)(mcpServer, options.distDir);
|
||||
(0, _getserveractionbyid.registerGetActionByIdTool)(mcpServer, options.distDir);
|
||||
(0, _getroutes.registerGetRoutesTool)(mcpServer, {
|
||||
projectPath: options.projectPath,
|
||||
nextConfig: options.nextConfig,
|
||||
pagesDir: options.pagesDir,
|
||||
appDir: options.appDir
|
||||
});
|
||||
return mcpServer;
|
||||
};
|
||||
|
||||
//# sourceMappingURL=get-or-create-mcp-server.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/get-or-create-mcp-server.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/get-or-create-mcp-server.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/server/mcp/get-or-create-mcp-server.ts"],"sourcesContent":["import { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp'\nimport { registerGetProjectMetadataTool } from './tools/get-project-metadata'\nimport { registerGetErrorsTool } from './tools/get-errors'\nimport { registerGetPageMetadataTool } from './tools/get-page-metadata'\nimport { registerGetLogsTool } from './tools/get-logs'\nimport { registerGetActionByIdTool } from './tools/get-server-action-by-id'\nimport { registerGetRoutesTool } from './tools/get-routes'\nimport type { HmrMessageSentToBrowser } from '../dev/hot-reloader-types'\nimport type { NextConfigComplete } from '../config-shared'\n\nexport interface McpServerOptions {\n projectPath: string\n distDir: string\n nextConfig: NextConfigComplete\n pagesDir: string | undefined\n appDir: string | undefined\n sendHmrMessage: (message: HmrMessageSentToBrowser) => void\n getActiveConnectionCount: () => number\n getDevServerUrl: () => string | undefined\n}\n\nlet mcpServer: McpServer | undefined\n\nexport const getOrCreateMcpServer = (options: McpServerOptions) => {\n if (mcpServer) {\n return mcpServer\n }\n\n mcpServer = new McpServer({\n name: 'Next.js MCP Server',\n version: '0.2.0',\n })\n\n registerGetProjectMetadataTool(\n mcpServer,\n options.projectPath,\n options.getDevServerUrl\n )\n registerGetErrorsTool(\n mcpServer,\n options.sendHmrMessage,\n options.getActiveConnectionCount\n )\n registerGetPageMetadataTool(\n mcpServer,\n options.sendHmrMessage,\n options.getActiveConnectionCount\n )\n registerGetLogsTool(mcpServer, options.distDir)\n registerGetActionByIdTool(mcpServer, options.distDir)\n registerGetRoutesTool(mcpServer, {\n projectPath: options.projectPath,\n nextConfig: options.nextConfig,\n pagesDir: options.pagesDir,\n appDir: options.appDir,\n })\n\n return mcpServer\n}\n"],"names":["getOrCreateMcpServer","mcpServer","options","McpServer","name","version","registerGetProjectMetadataTool","projectPath","getDevServerUrl","registerGetErrorsTool","sendHmrMessage","getActiveConnectionCount","registerGetPageMetadataTool","registerGetLogsTool","distDir","registerGetActionByIdTool","registerGetRoutesTool","nextConfig","pagesDir","appDir"],"mappings":";;;;+BAuBaA;;;eAAAA;;;qBAvBa;oCACqB;2BACT;iCACM;yBACR;qCACM;2BACJ;AAetC,IAAIC;AAEG,MAAMD,uBAAuB,CAACE;IACnC,IAAID,WAAW;QACb,OAAOA;IACT;IAEAA,YAAY,IAAIE,cAAS,CAAC;QACxBC,MAAM;QACNC,SAAS;IACX;IAEAC,IAAAA,kDAA8B,EAC5BL,WACAC,QAAQK,WAAW,EACnBL,QAAQM,eAAe;IAEzBC,IAAAA,gCAAqB,EACnBR,WACAC,QAAQQ,cAAc,EACtBR,QAAQS,wBAAwB;IAElCC,IAAAA,4CAA2B,EACzBX,WACAC,QAAQQ,cAAc,EACtBR,QAAQS,wBAAwB;IAElCE,IAAAA,4BAAmB,EAACZ,WAAWC,QAAQY,OAAO;IAC9CC,IAAAA,8CAAyB,EAACd,WAAWC,QAAQY,OAAO;IACpDE,IAAAA,gCAAqB,EAACf,WAAW;QAC/BM,aAAaL,QAAQK,WAAW;QAChCU,YAAYf,QAAQe,UAAU;QAC9BC,UAAUhB,QAAQgB,QAAQ;QAC1BC,QAAQjB,QAAQiB,MAAM;IACxB;IAEA,OAAOlB;AACT","ignoreList":[0]}
|
||||
44
apps/public-web/node_modules/next/dist/server/mcp/mcp-telemetry-tracker.d.ts
generated
vendored
Normal file
44
apps/public-web/node_modules/next/dist/server/mcp/mcp-telemetry-tracker.d.ts
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Telemetry tracker for MCP tool call usage.
|
||||
* Tracks invocation counts for each MCP tool to be reported via telemetry.
|
||||
*/
|
||||
import type { McpToolName } from '../../telemetry/events/build';
|
||||
export interface McpToolUsage {
|
||||
featureName: McpToolName;
|
||||
invocationCount: number;
|
||||
}
|
||||
declare class McpTelemetryTracker {
|
||||
private usageMap;
|
||||
/**
|
||||
* Record a tool call invocation
|
||||
*/
|
||||
recordToolCall(toolName: McpToolName): void;
|
||||
/**
|
||||
* Get all tool usages as an array
|
||||
*/
|
||||
getUsages(): McpToolUsage[];
|
||||
/**
|
||||
* Reset all usage tracking
|
||||
*/
|
||||
reset(): void;
|
||||
/**
|
||||
* Check if any tools have been called
|
||||
*/
|
||||
hasUsage(): boolean;
|
||||
}
|
||||
export declare const mcpTelemetryTracker: McpTelemetryTracker;
|
||||
/**
|
||||
* Get MCP tool usage telemetry
|
||||
*/
|
||||
export declare function getMcpTelemetryUsage(): McpToolUsage[];
|
||||
/**
|
||||
* Reset MCP telemetry tracker
|
||||
*/
|
||||
export declare function resetMcpTelemetry(): void;
|
||||
/**
|
||||
* Record MCP telemetry usage to the telemetry instance
|
||||
*/
|
||||
export declare function recordMcpTelemetry(telemetry: {
|
||||
record: (event: any) => void;
|
||||
}): void;
|
||||
export {};
|
||||
82
apps/public-web/node_modules/next/dist/server/mcp/mcp-telemetry-tracker.js
generated
vendored
Normal file
82
apps/public-web/node_modules/next/dist/server/mcp/mcp-telemetry-tracker.js
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* Telemetry tracker for MCP tool call usage.
|
||||
* Tracks invocation counts for each MCP tool to be reported via telemetry.
|
||||
*/ "use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
getMcpTelemetryUsage: null,
|
||||
mcpTelemetryTracker: null,
|
||||
recordMcpTelemetry: null,
|
||||
resetMcpTelemetry: null
|
||||
});
|
||||
function _export(target, all) {
|
||||
for(var name in all)Object.defineProperty(target, name, {
|
||||
enumerable: true,
|
||||
get: all[name]
|
||||
});
|
||||
}
|
||||
_export(exports, {
|
||||
getMcpTelemetryUsage: function() {
|
||||
return getMcpTelemetryUsage;
|
||||
},
|
||||
mcpTelemetryTracker: function() {
|
||||
return mcpTelemetryTracker;
|
||||
},
|
||||
recordMcpTelemetry: function() {
|
||||
return recordMcpTelemetry;
|
||||
},
|
||||
resetMcpTelemetry: function() {
|
||||
return resetMcpTelemetry;
|
||||
}
|
||||
});
|
||||
class McpTelemetryTracker {
|
||||
/**
|
||||
* Record a tool call invocation
|
||||
*/ recordToolCall(toolName) {
|
||||
const current = this.usageMap.get(toolName) || 0;
|
||||
this.usageMap.set(toolName, current + 1);
|
||||
}
|
||||
/**
|
||||
* Get all tool usages as an array
|
||||
*/ getUsages() {
|
||||
return Array.from(this.usageMap.entries()).map(([featureName, count])=>({
|
||||
featureName,
|
||||
invocationCount: count
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* Reset all usage tracking
|
||||
*/ reset() {
|
||||
this.usageMap.clear();
|
||||
}
|
||||
/**
|
||||
* Check if any tools have been called
|
||||
*/ hasUsage() {
|
||||
return this.usageMap.size > 0;
|
||||
}
|
||||
constructor(){
|
||||
this.usageMap = new Map();
|
||||
}
|
||||
}
|
||||
const mcpTelemetryTracker = new McpTelemetryTracker();
|
||||
function getMcpTelemetryUsage() {
|
||||
return mcpTelemetryTracker.getUsages();
|
||||
}
|
||||
function resetMcpTelemetry() {
|
||||
mcpTelemetryTracker.reset();
|
||||
}
|
||||
function recordMcpTelemetry(telemetry) {
|
||||
const mcpUsages = getMcpTelemetryUsage();
|
||||
if (mcpUsages.length === 0) {
|
||||
return;
|
||||
}
|
||||
const { eventMcpToolUsage } = require('../../telemetry/events/build');
|
||||
const events = eventMcpToolUsage(mcpUsages);
|
||||
for (const event of events){
|
||||
telemetry.record(event);
|
||||
}
|
||||
}
|
||||
|
||||
//# sourceMappingURL=mcp-telemetry-tracker.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/mcp-telemetry-tracker.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/mcp-telemetry-tracker.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../src/server/mcp/mcp-telemetry-tracker.ts"],"sourcesContent":["/**\n * Telemetry tracker for MCP tool call usage.\n * Tracks invocation counts for each MCP tool to be reported via telemetry.\n */\n\nimport type { McpToolName } from '../../telemetry/events/build'\n\nexport interface McpToolUsage {\n featureName: McpToolName\n invocationCount: number\n}\n\nclass McpTelemetryTracker {\n private usageMap = new Map<McpToolName, number>()\n\n /**\n * Record a tool call invocation\n */\n recordToolCall(toolName: McpToolName): void {\n const current = this.usageMap.get(toolName) || 0\n this.usageMap.set(toolName, current + 1)\n }\n\n /**\n * Get all tool usages as an array\n */\n getUsages(): McpToolUsage[] {\n return Array.from(this.usageMap.entries()).map(([featureName, count]) => ({\n featureName,\n invocationCount: count,\n }))\n }\n\n /**\n * Reset all usage tracking\n */\n reset(): void {\n this.usageMap.clear()\n }\n\n /**\n * Check if any tools have been called\n */\n hasUsage(): boolean {\n return this.usageMap.size > 0\n }\n}\n\n// Singleton instance\nexport const mcpTelemetryTracker = new McpTelemetryTracker()\n\n/**\n * Get MCP tool usage telemetry\n */\nexport function getMcpTelemetryUsage(): McpToolUsage[] {\n return mcpTelemetryTracker.getUsages()\n}\n\n/**\n * Reset MCP telemetry tracker\n */\nexport function resetMcpTelemetry(): void {\n mcpTelemetryTracker.reset()\n}\n\n/**\n * Record MCP telemetry usage to the telemetry instance\n */\nexport function recordMcpTelemetry(telemetry: {\n record: (event: any) => void\n}): void {\n const mcpUsages = getMcpTelemetryUsage()\n if (mcpUsages.length === 0) {\n return\n }\n\n const { eventMcpToolUsage } =\n require('../../telemetry/events/build') as typeof import('../../telemetry/events/build')\n const events = eventMcpToolUsage(mcpUsages)\n for (const event of events) {\n telemetry.record(event)\n }\n}\n"],"names":["getMcpTelemetryUsage","mcpTelemetryTracker","recordMcpTelemetry","resetMcpTelemetry","McpTelemetryTracker","recordToolCall","toolName","current","usageMap","get","set","getUsages","Array","from","entries","map","featureName","count","invocationCount","reset","clear","hasUsage","size","Map","telemetry","mcpUsages","length","eventMcpToolUsage","require","events","event","record"],"mappings":"AAAA;;;CAGC;;;;;;;;;;;;;;;;;IAmDeA,oBAAoB;eAApBA;;IALHC,mBAAmB;eAAnBA;;IAmBGC,kBAAkB;eAAlBA;;IAPAC,iBAAiB;eAAjBA;;;AAjDhB,MAAMC;IAGJ;;GAEC,GACDC,eAAeC,QAAqB,EAAQ;QAC1C,MAAMC,UAAU,IAAI,CAACC,QAAQ,CAACC,GAAG,CAACH,aAAa;QAC/C,IAAI,CAACE,QAAQ,CAACE,GAAG,CAACJ,UAAUC,UAAU;IACxC;IAEA;;GAEC,GACDI,YAA4B;QAC1B,OAAOC,MAAMC,IAAI,CAAC,IAAI,CAACL,QAAQ,CAACM,OAAO,IAAIC,GAAG,CAAC,CAAC,CAACC,aAAaC,MAAM,GAAM,CAAA;gBACxED;gBACAE,iBAAiBD;YACnB,CAAA;IACF;IAEA;;GAEC,GACDE,QAAc;QACZ,IAAI,CAACX,QAAQ,CAACY,KAAK;IACrB;IAEA;;GAEC,GACDC,WAAoB;QAClB,OAAO,IAAI,CAACb,QAAQ,CAACc,IAAI,GAAG;IAC9B;;aAhCQd,WAAW,IAAIe;;AAiCzB;AAGO,MAAMtB,sBAAsB,IAAIG;AAKhC,SAASJ;IACd,OAAOC,oBAAoBU,SAAS;AACtC;AAKO,SAASR;IACdF,oBAAoBkB,KAAK;AAC3B;AAKO,SAASjB,mBAAmBsB,SAElC;IACC,MAAMC,YAAYzB;IAClB,IAAIyB,UAAUC,MAAM,KAAK,GAAG;QAC1B;IACF;IAEA,MAAM,EAAEC,iBAAiB,EAAE,GACzBC,QAAQ;IACV,MAAMC,SAASF,kBAAkBF;IACjC,KAAK,MAAMK,SAASD,OAAQ;QAC1BL,UAAUO,MAAM,CAACD;IACnB;AACF","ignoreList":[0]}
|
||||
20
apps/public-web/node_modules/next/dist/server/mcp/tools/get-errors.d.ts
generated
vendored
Normal file
20
apps/public-web/node_modules/next/dist/server/mcp/tools/get-errors.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* 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 type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp';
|
||||
import type { OverlayState } from '../../../next-devtools/dev-overlay/shared';
|
||||
import { type HmrMessageSentToBrowser } from '../../dev/hot-reloader-types';
|
||||
export declare function registerGetErrorsTool(server: McpServer, sendHmrMessage: (message: HmrMessageSentToBrowser) => void, getActiveConnectionCount: () => number): void;
|
||||
export declare function handleErrorStateResponse(requestId: string, errorState: OverlayState | null, url: string | undefined): void;
|
||||
107
apps/public-web/node_modules/next/dist/server/mcp/tools/get-errors.js
generated
vendored
Normal file
107
apps/public-web/node_modules/next/dist/server/mcp/tools/get-errors.js
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* 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.
|
||||
*/ "use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
handleErrorStateResponse: null,
|
||||
registerGetErrorsTool: null
|
||||
});
|
||||
function _export(target, all) {
|
||||
for(var name in all)Object.defineProperty(target, name, {
|
||||
enumerable: true,
|
||||
get: all[name]
|
||||
});
|
||||
}
|
||||
_export(exports, {
|
||||
handleErrorStateResponse: function() {
|
||||
return handleErrorStateResponse;
|
||||
},
|
||||
registerGetErrorsTool: function() {
|
||||
return registerGetErrorsTool;
|
||||
}
|
||||
});
|
||||
const _hotreloadertypes = require("../../dev/hot-reloader-types");
|
||||
const _formaterrors = require("./utils/format-errors");
|
||||
const _browsercommunication = require("./utils/browser-communication");
|
||||
const _nextinstanceerrorstate = require("./next-instance-error-state");
|
||||
const _mcptelemetrytracker = require("../mcp-telemetry-tracker");
|
||||
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.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 (0, _browsercommunication.createBrowserRequest)(_hotreloadertypes.HMR_MESSAGE_SENT_TO_BROWSER.REQUEST_CURRENT_ERROR_STATE, sendHmrMessage, getActiveConnectionCount, _browsercommunication.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.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 (0, _formaterrors.formatErrors)(routesErrorState, _nextinstanceerrorstate.NextInstanceErrorState);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: output
|
||||
}
|
||||
]
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
function handleErrorStateResponse(requestId, errorState, url) {
|
||||
(0, _browsercommunication.handleBrowserPageResponse)(requestId, errorState, url || '');
|
||||
}
|
||||
|
||||
//# sourceMappingURL=get-errors.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-errors.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-errors.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
8
apps/public-web/node_modules/next/dist/server/mcp/tools/get-logs.d.ts
generated
vendored
Normal file
8
apps/public-web/node_modules/next/dist/server/mcp/tools/get-logs.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* MCP tool for getting the path to the Next.js development log file.
|
||||
*
|
||||
* This tool returns the path to the {nextConfig.distDir}/logs/next-development.log file
|
||||
* that contains browser console logs and other development information.
|
||||
*/
|
||||
import type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp';
|
||||
export declare function registerGetLogsTool(server: McpServer, distDir: string): void;
|
||||
61
apps/public-web/node_modules/next/dist/server/mcp/tools/get-logs.js
generated
vendored
Normal file
61
apps/public-web/node_modules/next/dist/server/mcp/tools/get-logs.js
generated
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
/**
|
||||
* MCP tool for getting the path to the Next.js development log file.
|
||||
*
|
||||
* This tool returns the path to the {nextConfig.distDir}/logs/next-development.log file
|
||||
* that contains browser console logs and other development information.
|
||||
*/ "use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "registerGetLogsTool", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return registerGetLogsTool;
|
||||
}
|
||||
});
|
||||
const _promises = require("fs/promises");
|
||||
const _path = require("path");
|
||||
const _mcptelemetrytracker = require("../mcp-telemetry-tracker");
|
||||
function registerGetLogsTool(server, distDir) {
|
||||
server.registerTool('get_logs', {
|
||||
description: 'Get the path to the Next.js development log file. Returns the file path so the agent can read the logs directly.'
|
||||
}, async ()=>{
|
||||
// Track telemetry
|
||||
_mcptelemetrytracker.mcpTelemetryTracker.recordToolCall('mcp/get_logs');
|
||||
try {
|
||||
const logFilePath = (0, _path.join)(distDir, 'logs', 'next-development.log');
|
||||
// Check if the log file exists
|
||||
try {
|
||||
await (0, _promises.stat)(logFilePath);
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Log file not found at ${logFilePath}.`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Next.js log file path: ${logFilePath}`
|
||||
}
|
||||
]
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Error getting log file path: ${error instanceof Error ? error.message : String(error)}`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//# sourceMappingURL=get-logs.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-logs.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-logs.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../../src/server/mcp/tools/get-logs.ts"],"sourcesContent":["/**\n * MCP tool for getting the path to the Next.js development log file.\n *\n * This tool returns the path to the {nextConfig.distDir}/logs/next-development.log file\n * that contains browser console logs and other development information.\n */\nimport type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp'\nimport { stat } from 'fs/promises'\nimport { join } from 'path'\nimport { mcpTelemetryTracker } from '../mcp-telemetry-tracker'\n\nexport function registerGetLogsTool(server: McpServer, distDir: string) {\n server.registerTool(\n 'get_logs',\n {\n description:\n 'Get the path to the Next.js development log file. Returns the file path so the agent can read the logs directly.',\n },\n async () => {\n // Track telemetry\n mcpTelemetryTracker.recordToolCall('mcp/get_logs')\n\n try {\n const logFilePath = join(distDir, 'logs', 'next-development.log')\n\n // Check if the log file exists\n try {\n await stat(logFilePath)\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Log file not found at ${logFilePath}.`,\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text',\n text: `Next.js log file path: ${logFilePath}`,\n },\n ],\n }\n } catch (error) {\n return {\n content: [\n {\n type: 'text',\n text: `Error getting log file path: ${error instanceof Error ? error.message : String(error)}`,\n },\n ],\n }\n }\n }\n )\n}\n"],"names":["registerGetLogsTool","server","distDir","registerTool","description","mcpTelemetryTracker","recordToolCall","logFilePath","join","stat","error","content","type","text","Error","message","String"],"mappings":"AAAA;;;;;CAKC;;;;+BAMeA;;;eAAAA;;;0BAJK;sBACA;qCACe;AAE7B,SAASA,oBAAoBC,MAAiB,EAAEC,OAAe;IACpED,OAAOE,YAAY,CACjB,YACA;QACEC,aACE;IACJ,GACA;QACE,kBAAkB;QAClBC,wCAAmB,CAACC,cAAc,CAAC;QAEnC,IAAI;YACF,MAAMC,cAAcC,IAAAA,UAAI,EAACN,SAAS,QAAQ;YAE1C,+BAA+B;YAC/B,IAAI;gBACF,MAAMO,IAAAA,cAAI,EAACF;YACb,EAAE,OAAOG,OAAO;gBACd,OAAO;oBACLC,SAAS;wBACP;4BACEC,MAAM;4BACNC,MAAM,CAAC,sBAAsB,EAAEN,YAAY,CAAC,CAAC;wBAC/C;qBACD;gBACH;YACF;YAEA,OAAO;gBACLI,SAAS;oBACP;wBACEC,MAAM;wBACNC,MAAM,CAAC,uBAAuB,EAAEN,aAAa;oBAC/C;iBACD;YACH;QACF,EAAE,OAAOG,OAAO;YACd,OAAO;gBACLC,SAAS;oBACP;wBACEC,MAAM;wBACNC,MAAM,CAAC,6BAA6B,EAAEH,iBAAiBI,QAAQJ,MAAMK,OAAO,GAAGC,OAAON,QAAQ;oBAChG;iBACD;YACH;QACF;IACF;AAEJ","ignoreList":[0]}
|
||||
5
apps/public-web/node_modules/next/dist/server/mcp/tools/get-page-metadata.d.ts
generated
vendored
Normal file
5
apps/public-web/node_modules/next/dist/server/mcp/tools/get-page-metadata.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp';
|
||||
import { type HmrMessageSentToBrowser } from '../../dev/hot-reloader-types';
|
||||
import type { SegmentTrieData } from '../../../shared/lib/mcp-page-metadata-types';
|
||||
export declare function registerGetPageMetadataTool(server: McpServer, sendHmrMessage: (message: HmrMessageSentToBrowser) => void, getActiveConnectionCount: () => number): void;
|
||||
export declare function handlePageMetadataResponse(requestId: string, segmentTrieData: SegmentTrieData | null, url: string | undefined): void;
|
||||
180
apps/public-web/node_modules/next/dist/server/mcp/tools/get-page-metadata.js
generated
vendored
Normal file
180
apps/public-web/node_modules/next/dist/server/mcp/tools/get-page-metadata.js
generated
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
handlePageMetadataResponse: null,
|
||||
registerGetPageMetadataTool: null
|
||||
});
|
||||
function _export(target, all) {
|
||||
for(var name in all)Object.defineProperty(target, name, {
|
||||
enumerable: true,
|
||||
get: all[name]
|
||||
});
|
||||
}
|
||||
_export(exports, {
|
||||
handlePageMetadataResponse: function() {
|
||||
return handlePageMetadataResponse;
|
||||
},
|
||||
registerGetPageMetadataTool: function() {
|
||||
return registerGetPageMetadataTool;
|
||||
}
|
||||
});
|
||||
const _hotreloadertypes = require("../../dev/hot-reloader-types");
|
||||
const _browsercommunication = require("./utils/browser-communication");
|
||||
const _mcptelemetrytracker = require("../mcp-telemetry-tracker");
|
||||
function registerGetPageMetadataTool(server, sendHmrMessage, getActiveConnectionCount) {
|
||||
server.registerTool('get_page_metadata', {
|
||||
description: 'Get runtime metadata about what contributes to the current page render from active browser sessions.',
|
||||
inputSchema: {}
|
||||
}, async (_request)=>{
|
||||
// Track telemetry
|
||||
_mcptelemetrytracker.mcpTelemetryTracker.recordToolCall('mcp/get_page_metadata');
|
||||
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 page metadata.'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
const responses = await (0, _browsercommunication.createBrowserRequest)(_hotreloadertypes.HMR_MESSAGE_SENT_TO_BROWSER.REQUEST_PAGE_METADATA, sendHmrMessage, getActiveConnectionCount, _browsercommunication.DEFAULT_BROWSER_REQUEST_TIMEOUT_MS);
|
||||
if (responses.length === 0) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'No browser sessions responded.'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
const sessionMetadata = [];
|
||||
for (const response of responses){
|
||||
if (response.data) {
|
||||
// TODO: Add other metadata for the current page render here. Currently, we only have segment trie data.
|
||||
const pageMetadata = convertSegmentTrieToPageMetadata(response.data);
|
||||
sessionMetadata.push({
|
||||
url: response.url,
|
||||
metadata: pageMetadata
|
||||
});
|
||||
}
|
||||
}
|
||||
if (sessionMetadata.length === 0) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `No page metadata available from ${responses.length} browser session(s).`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
const output = formatPageMetadata(sessionMetadata);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: output
|
||||
}
|
||||
]
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
function handlePageMetadataResponse(requestId, segmentTrieData, url) {
|
||||
(0, _browsercommunication.handleBrowserPageResponse)(requestId, segmentTrieData, url || '');
|
||||
}
|
||||
function convertSegmentTrieToPageMetadata(data) {
|
||||
const segments = [];
|
||||
if (data.segmentTrie) {
|
||||
// Traverse the trie and collect all segments
|
||||
function traverseTrie(node) {
|
||||
if (node.value) {
|
||||
segments.push({
|
||||
type: node.value.type,
|
||||
pagePath: node.value.pagePath,
|
||||
boundaryType: node.value.boundaryType
|
||||
});
|
||||
}
|
||||
for (const childNode of Object.values(node.children)){
|
||||
if (childNode) {
|
||||
traverseTrie(childNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
traverseTrie(data.segmentTrie);
|
||||
}
|
||||
return {
|
||||
segments,
|
||||
routerType: data.routerType
|
||||
};
|
||||
}
|
||||
function formatPageMetadata(sessionMetadata) {
|
||||
let output = `# Page metadata from ${sessionMetadata.length} browser session(s)\n\n`;
|
||||
for (const { url, metadata } of sessionMetadata){
|
||||
let displayUrl = url;
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
displayUrl = urlObj.pathname + urlObj.search + urlObj.hash;
|
||||
} catch {
|
||||
// If URL parsing fails, use the original URL
|
||||
}
|
||||
output += `## Session: ${displayUrl}\n\n`;
|
||||
output += `**Router type:** ${metadata.routerType}\n\n`;
|
||||
if (metadata.segments.length === 0) {
|
||||
output += '*No segments found*\n\n';
|
||||
} else {
|
||||
output += '### Files powering this page:\n\n';
|
||||
// Ensure consistent output to avoid flaky tests
|
||||
const sortedSegments = [
|
||||
...metadata.segments
|
||||
].sort((a, b)=>{
|
||||
const typeOrder = (segment)=>{
|
||||
const type = segment.boundaryType || segment.type;
|
||||
if (type === 'layout') return 0;
|
||||
if (type.startsWith('boundary:')) return 1;
|
||||
if (type === 'page') return 2;
|
||||
return 3;
|
||||
};
|
||||
const aOrder = typeOrder(a);
|
||||
const bOrder = typeOrder(b);
|
||||
if (aOrder !== bOrder) return aOrder - bOrder;
|
||||
return a.pagePath.localeCompare(b.pagePath);
|
||||
});
|
||||
for (const segment of sortedSegments){
|
||||
const path = segment.pagePath;
|
||||
const isBuiltin = path.startsWith('__next_builtin__');
|
||||
const type = segment.boundaryType || segment.type;
|
||||
const isBoundary = type.startsWith('boundary:');
|
||||
let displayPath = path.replace(/@boundary$/, '').replace(/^__next_builtin__/, '');
|
||||
if (!isBuiltin && !displayPath.startsWith('app/')) {
|
||||
displayPath = `app/${displayPath}`;
|
||||
}
|
||||
const descriptors = [];
|
||||
if (isBoundary) descriptors.push('boundary');
|
||||
if (isBuiltin) descriptors.push('builtin');
|
||||
const descriptor = descriptors.length > 0 ? ` (${descriptors.join(', ')})` : '';
|
||||
output += `- ${displayPath}${descriptor}\n`;
|
||||
}
|
||||
output += '\n';
|
||||
}
|
||||
output += '---\n\n';
|
||||
}
|
||||
return output.trim();
|
||||
}
|
||||
|
||||
//# sourceMappingURL=get-page-metadata.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-page-metadata.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-page-metadata.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2
apps/public-web/node_modules/next/dist/server/mcp/tools/get-project-metadata.d.ts
generated
vendored
Normal file
2
apps/public-web/node_modules/next/dist/server/mcp/tools/get-project-metadata.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp';
|
||||
export declare function registerGetProjectMetadataTool(server: McpServer, projectPath: string, getDevServerUrl: () => string | undefined): void;
|
||||
55
apps/public-web/node_modules/next/dist/server/mcp/tools/get-project-metadata.js
generated
vendored
Normal file
55
apps/public-web/node_modules/next/dist/server/mcp/tools/get-project-metadata.js
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "registerGetProjectMetadataTool", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return registerGetProjectMetadataTool;
|
||||
}
|
||||
});
|
||||
const _mcptelemetrytracker = require("../mcp-telemetry-tracker");
|
||||
function registerGetProjectMetadataTool(server, projectPath, getDevServerUrl) {
|
||||
server.registerTool('get_project_metadata', {
|
||||
description: 'Returns the the metadata of this Next.js project, including project path, dev server URL, etc.',
|
||||
inputSchema: {}
|
||||
}, async (_request)=>{
|
||||
// Track telemetry
|
||||
_mcptelemetrytracker.mcpTelemetryTracker.recordToolCall('mcp/get_project_metadata');
|
||||
try {
|
||||
if (!projectPath) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'Unable to determine the absolute path of the Next.js project.'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
const devServerUrl = getDevServerUrl();
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: JSON.stringify({
|
||||
projectPath,
|
||||
devServerUrl
|
||||
})
|
||||
}
|
||||
]
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//# sourceMappingURL=get-project-metadata.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-project-metadata.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-project-metadata.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../../src/server/mcp/tools/get-project-metadata.ts"],"sourcesContent":["import type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp'\nimport { mcpTelemetryTracker } from '../mcp-telemetry-tracker'\n\nexport function registerGetProjectMetadataTool(\n server: McpServer,\n projectPath: string,\n getDevServerUrl: () => string | undefined\n) {\n server.registerTool(\n 'get_project_metadata',\n {\n description:\n 'Returns the the metadata of this Next.js project, including project path, dev server URL, etc.',\n inputSchema: {},\n },\n async (_request) => {\n // Track telemetry\n mcpTelemetryTracker.recordToolCall('mcp/get_project_metadata')\n\n try {\n if (!projectPath) {\n return {\n content: [\n {\n type: 'text',\n text: 'Unable to determine the absolute path of the Next.js project.',\n },\n ],\n }\n }\n\n const devServerUrl = getDevServerUrl()\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n projectPath,\n devServerUrl,\n }),\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"],"names":["registerGetProjectMetadataTool","server","projectPath","getDevServerUrl","registerTool","description","inputSchema","_request","mcpTelemetryTracker","recordToolCall","content","type","text","devServerUrl","JSON","stringify","error","Error","message","String"],"mappings":";;;;+BAGgBA;;;eAAAA;;;qCAFoB;AAE7B,SAASA,+BACdC,MAAiB,EACjBC,WAAmB,EACnBC,eAAyC;IAEzCF,OAAOG,YAAY,CACjB,wBACA;QACEC,aACE;QACFC,aAAa,CAAC;IAChB,GACA,OAAOC;QACL,kBAAkB;QAClBC,wCAAmB,CAACC,cAAc,CAAC;QAEnC,IAAI;YACF,IAAI,CAACP,aAAa;gBAChB,OAAO;oBACLQ,SAAS;wBACP;4BACEC,MAAM;4BACNC,MAAM;wBACR;qBACD;gBACH;YACF;YAEA,MAAMC,eAAeV;YAErB,OAAO;gBACLO,SAAS;oBACP;wBACEC,MAAM;wBACNC,MAAME,KAAKC,SAAS,CAAC;4BACnBb;4BACAW;wBACF;oBACF;iBACD;YACH;QACF,EAAE,OAAOG,OAAO;YACd,OAAO;gBACLN,SAAS;oBACP;wBACEC,MAAM;wBACNC,MAAM,CAAC,OAAO,EAAEI,iBAAiBC,QAAQD,MAAME,OAAO,GAAGC,OAAOH,QAAQ;oBAC1E;iBACD;YACH;QACF;IACF;AAEJ","ignoreList":[0]}
|
||||
22
apps/public-web/node_modules/next/dist/server/mcp/tools/get-routes.d.ts
generated
vendored
Normal file
22
apps/public-web/node_modules/next/dist/server/mcp/tools/get-routes.d.ts
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* MCP tool for getting all routes that become entry points in a Next.js application.
|
||||
*
|
||||
* This tool discovers routes by scanning the filesystem directly. It finds all route
|
||||
* files in the app/ and pages/ directories and converts them to route paths.
|
||||
*
|
||||
* Returns routes grouped by router type:
|
||||
* - appRouter: App Router pages and route handlers
|
||||
* - pagesRouter: Pages Router pages and API routes
|
||||
*
|
||||
* Dynamic route segments appear as [id], [slug], or [...slug] patterns. This tool
|
||||
* does NOT expand getStaticParams - it only shows the route patterns as defined in
|
||||
* the filesystem.
|
||||
*/
|
||||
import type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp';
|
||||
import type { NextConfigComplete } from '../../../server/config-shared';
|
||||
export declare function registerGetRoutesTool(server: McpServer, options: {
|
||||
projectPath: string;
|
||||
nextConfig: NextConfigComplete;
|
||||
pagesDir: string | undefined;
|
||||
appDir: string | undefined;
|
||||
}): void;
|
||||
171
apps/public-web/node_modules/next/dist/server/mcp/tools/get-routes.js
generated
vendored
Normal file
171
apps/public-web/node_modules/next/dist/server/mcp/tools/get-routes.js
generated
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
/**
|
||||
* MCP tool for getting all routes that become entry points in a Next.js application.
|
||||
*
|
||||
* This tool discovers routes by scanning the filesystem directly. It finds all route
|
||||
* files in the app/ and pages/ directories and converts them to route paths.
|
||||
*
|
||||
* Returns routes grouped by router type:
|
||||
* - appRouter: App Router pages and route handlers
|
||||
* - pagesRouter: Pages Router pages and API routes
|
||||
*
|
||||
* Dynamic route segments appear as [id], [slug], or [...slug] patterns. This tool
|
||||
* does NOT expand getStaticParams - it only shows the route patterns as defined in
|
||||
* the filesystem.
|
||||
*/ "use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "registerGetRoutesTool", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return registerGetRoutesTool;
|
||||
}
|
||||
});
|
||||
const _mcptelemetrytracker = require("../mcp-telemetry-tracker");
|
||||
const _entries = require("../../../build/entries");
|
||||
const _findpagefile = require("../../lib/find-page-file");
|
||||
const _pagetypes = require("../../../lib/page-types");
|
||||
const _zod = /*#__PURE__*/ _interop_require_default(require("next/dist/compiled/zod"));
|
||||
function _interop_require_default(obj) {
|
||||
return obj && obj.__esModule ? obj : {
|
||||
default: obj
|
||||
};
|
||||
}
|
||||
function registerGetRoutesTool(server, options) {
|
||||
server.registerTool('get_routes', {
|
||||
description: 'Get all routes that will become entry points in the Next.js application by scanning the filesystem. Returns routes grouped by router type (appRouter, pagesRouter). Dynamic segments appear as [param] or [...slug] patterns. API routes are included in their respective routers (e.g., /api/* routes from pages/ are in pagesRouter). Optional parameter: routerType ("app" | "pages") - filter by specific router type, omit to get all routes.',
|
||||
inputSchema: {
|
||||
routerType: _zod.default.union([
|
||||
_zod.default.literal('app'),
|
||||
_zod.default.literal('pages')
|
||||
]).optional()
|
||||
}
|
||||
}, async (request)=>{
|
||||
// Track telemetry
|
||||
_mcptelemetrytracker.mcpTelemetryTracker.recordToolCall('mcp/get_routes');
|
||||
try {
|
||||
const routerType = request.routerType === 'app' || request.routerType === 'pages' ? request.routerType : undefined;
|
||||
const routes = [];
|
||||
const { projectPath, nextConfig, pagesDir, appDir } = options;
|
||||
// Check if we have any directories to scan
|
||||
if (!pagesDir && !appDir) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'No pages or app directory found in the project.'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
const isSrcDir = pagesDir && pagesDir.includes('/src/') || appDir && appDir.includes('/src/');
|
||||
// Create valid file matcher for filtering
|
||||
const validFileMatcher = (0, _findpagefile.createValidFileMatcher)(nextConfig.pageExtensions, appDir);
|
||||
// Collect and process App Router routes if requested
|
||||
if (appDir && (!routerType || routerType === 'app')) {
|
||||
try {
|
||||
const { appPaths } = await (0, _entries.collectAppFiles)(appDir, validFileMatcher);
|
||||
if (appPaths.length > 0) {
|
||||
const mappedAppPages = await (0, _entries.createPagesMapping)({
|
||||
pagePaths: appPaths,
|
||||
isDev: true,
|
||||
pagesType: _pagetypes.PAGE_TYPES.APP,
|
||||
pageExtensions: nextConfig.pageExtensions,
|
||||
pagesDir,
|
||||
appDir,
|
||||
appDirOnly: pagesDir ? false : true
|
||||
});
|
||||
const { appRoutes, appRouteHandlers } = (0, _entries.processAppRoutes)(mappedAppPages, validFileMatcher, projectPath, isSrcDir || false);
|
||||
// Add app page routes
|
||||
for (const { route } of appRoutes){
|
||||
routes.push({
|
||||
route,
|
||||
type: 'app'
|
||||
});
|
||||
}
|
||||
// Add app route handlers
|
||||
for (const { route } of appRouteHandlers){
|
||||
routes.push({
|
||||
route,
|
||||
type: 'app'
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Error collecting app routes - continue anyway
|
||||
}
|
||||
}
|
||||
// Collect and process Pages Router routes if requested
|
||||
if (pagesDir && (!routerType || routerType === 'pages')) {
|
||||
try {
|
||||
const pagePaths = await (0, _entries.collectPagesFiles)(pagesDir, validFileMatcher);
|
||||
if (pagePaths.length > 0) {
|
||||
const mappedPages = await (0, _entries.createPagesMapping)({
|
||||
pagePaths,
|
||||
isDev: true,
|
||||
pagesType: _pagetypes.PAGE_TYPES.PAGES,
|
||||
pageExtensions: nextConfig.pageExtensions,
|
||||
pagesDir,
|
||||
appDir,
|
||||
appDirOnly: false
|
||||
});
|
||||
const { pageRoutes, pageApiRoutes } = (0, _entries.processPageRoutes)(mappedPages, projectPath, isSrcDir || false);
|
||||
// Add page routes
|
||||
for (const { route } of pageRoutes){
|
||||
routes.push({
|
||||
route,
|
||||
type: 'page'
|
||||
});
|
||||
}
|
||||
// Add API routes (always included as part of pages router)
|
||||
for (const { route } of pageApiRoutes){
|
||||
routes.push({
|
||||
route,
|
||||
type: 'api'
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Error collecting pages routes - continue anyway
|
||||
}
|
||||
}
|
||||
if (routes.length === 0) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'No routes found in the project.'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
// Group routes by router type
|
||||
const appRoutes = routes.filter((r)=>r.type === 'app').map((r)=>r.route).sort();
|
||||
const pageRoutes = routes.filter((r)=>r.type === 'page' || r.type === 'api').map((r)=>r.route).sort();
|
||||
// Format the output with grouped routes
|
||||
const output = {
|
||||
appRouter: appRoutes.length > 0 ? appRoutes : undefined,
|
||||
pagesRouter: pageRoutes.length > 0 ? pageRoutes : undefined
|
||||
};
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: JSON.stringify(output, null, 2)
|
||||
}
|
||||
]
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//# sourceMappingURL=get-routes.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-routes.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-routes.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
2
apps/public-web/node_modules/next/dist/server/mcp/tools/get-server-action-by-id.d.ts
generated
vendored
Normal file
2
apps/public-web/node_modules/next/dist/server/mcp/tools/get-server-action-by-id.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
import type { McpServer } from 'next/dist/compiled/@modelcontextprotocol/sdk/server/mcp';
|
||||
export declare function registerGetActionByIdTool(server: McpServer, distDir: string): void;
|
||||
113
apps/public-web/node_modules/next/dist/server/mcp/tools/get-server-action-by-id.js
generated
vendored
Normal file
113
apps/public-web/node_modules/next/dist/server/mcp/tools/get-server-action-by-id.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "registerGetActionByIdTool", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return registerGetActionByIdTool;
|
||||
}
|
||||
});
|
||||
const _zod = require("next/dist/compiled/zod");
|
||||
const _fs = require("fs");
|
||||
const _path = require("path");
|
||||
const _mcptelemetrytracker = require("../mcp-telemetry-tracker");
|
||||
const INLINE_ACTION_PREFIX = '$$RSC_SERVER_ACTION_';
|
||||
function registerGetActionByIdTool(server, distDir) {
|
||||
server.registerTool('get_server_action_by_id', {
|
||||
description: 'Locates a Server Action by its ID in the server-reference-manifest.json. Returns the filename and export name for the action.',
|
||||
inputSchema: {
|
||||
actionId: _zod.z.string()
|
||||
}
|
||||
}, async (request)=>{
|
||||
// Track telemetry
|
||||
_mcptelemetrytracker.mcpTelemetryTracker.recordToolCall('mcp/get_server_action_by_id');
|
||||
try {
|
||||
const { actionId } = request;
|
||||
if (!actionId) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'Error: actionId parameter is required'
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
const manifestPath = (0, _path.join)(distDir, 'server', 'server-reference-manifest.json');
|
||||
let manifestContent;
|
||||
try {
|
||||
manifestContent = await _fs.promises.readFile(manifestPath, 'utf-8');
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Error: Could not read server-reference-manifest.json at ${manifestPath}.`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
const manifest = JSON.parse(manifestContent);
|
||||
// Search in node entries
|
||||
if (manifest.node && manifest.node[actionId]) {
|
||||
const entry = manifest.node[actionId];
|
||||
const isInlineAction = entry.exportedName.startsWith(INLINE_ACTION_PREFIX);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: JSON.stringify({
|
||||
actionId,
|
||||
runtime: 'node',
|
||||
filename: entry.filename,
|
||||
functionName: isInlineAction ? 'inline server action' : entry.exportedName,
|
||||
layer: entry.layer,
|
||||
workers: entry.workers
|
||||
}, null, 2)
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
// Search in edge entries
|
||||
if (manifest.edge && manifest.edge[actionId]) {
|
||||
const entry = manifest.edge[actionId];
|
||||
const isInlineAction = entry.exportedName.startsWith(INLINE_ACTION_PREFIX);
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: JSON.stringify({
|
||||
actionId,
|
||||
runtime: 'edge',
|
||||
filename: entry.filename,
|
||||
functionName: isInlineAction ? 'inline server action' : entry.exportedName,
|
||||
layer: entry.layer,
|
||||
workers: entry.workers
|
||||
}, null, 2)
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Error: Action ID "${actionId}" not found in server-reference-manifest.json`
|
||||
}
|
||||
]
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//# sourceMappingURL=get-server-action-by-id.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-server-action-by-id.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/get-server-action-by-id.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
20
apps/public-web/node_modules/next/dist/server/mcp/tools/next-instance-error-state.d.ts
generated
vendored
Normal file
20
apps/public-web/node_modules/next/dist/server/mcp/tools/next-instance-error-state.d.ts
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Global error state for Next.js instance-level errors that are not associated
|
||||
* with a specific browser session or route. This state is exposed through the MCP server's `get_errors`
|
||||
* tool as well. This covers the errors that are global to the Next.js instance, such as errors in next.config.js.
|
||||
*
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* This state is directly manipulated by various parts of the Next.js dev server:
|
||||
*
|
||||
* // Reset the error state
|
||||
* NextInstanceErrorState.[errorType] = []
|
||||
*
|
||||
* // Capture an error for a specific error type
|
||||
* NextInstanceErrorState.[errorType].push(err)
|
||||
*
|
||||
*/
|
||||
export declare const NextInstanceErrorState: {
|
||||
nextConfig: unknown[];
|
||||
};
|
||||
31
apps/public-web/node_modules/next/dist/server/mcp/tools/next-instance-error-state.js
generated
vendored
Normal file
31
apps/public-web/node_modules/next/dist/server/mcp/tools/next-instance-error-state.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Global error state for Next.js instance-level errors that are not associated
|
||||
* with a specific browser session or route. This state is exposed through the MCP server's `get_errors`
|
||||
* tool as well. This covers the errors that are global to the Next.js instance, such as errors in next.config.js.
|
||||
*
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* This state is directly manipulated by various parts of the Next.js dev server:
|
||||
*
|
||||
* // Reset the error state
|
||||
* NextInstanceErrorState.[errorType] = []
|
||||
*
|
||||
* // Capture an error for a specific error type
|
||||
* NextInstanceErrorState.[errorType].push(err)
|
||||
*
|
||||
*/ "use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
Object.defineProperty(exports, "NextInstanceErrorState", {
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return NextInstanceErrorState;
|
||||
}
|
||||
});
|
||||
const NextInstanceErrorState = {
|
||||
nextConfig: []
|
||||
};
|
||||
|
||||
//# sourceMappingURL=next-instance-error-state.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/next-instance-error-state.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/next-instance-error-state.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../../src/server/mcp/tools/next-instance-error-state.ts"],"sourcesContent":["/**\n * Global error state for Next.js instance-level errors that are not associated\n * with a specific browser session or route. This state is exposed through the MCP server's `get_errors`\n * tool as well. This covers the errors that are global to the Next.js instance, such as errors in next.config.js.\n *\n *\n * ## Usage\n *\n * This state is directly manipulated by various parts of the Next.js dev server:\n *\n * // Reset the error state\n * NextInstanceErrorState.[errorType] = []\n *\n * // Capture an error for a specific error type\n * NextInstanceErrorState.[errorType].push(err)\n *\n */\nexport const NextInstanceErrorState: {\n nextConfig: unknown[]\n} = {\n nextConfig: [],\n}\n"],"names":["NextInstanceErrorState","nextConfig"],"mappings":"AAAA;;;;;;;;;;;;;;;;CAgBC;;;;+BACYA;;;eAAAA;;;AAAN,MAAMA,yBAET;IACFC,YAAY,EAAE;AAChB","ignoreList":[0]}
|
||||
13
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/browser-communication.d.ts
generated
vendored
Normal file
13
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/browser-communication.d.ts
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Shared utilities for MCP tools that communicate with the browser.
|
||||
* This module provides a common infrastructure for request-response
|
||||
* communication between MCP endpoints and browser sessions via HMR.
|
||||
*/
|
||||
import type { HMR_MESSAGE_SENT_TO_BROWSER, HmrMessageSentToBrowser } from '../../../dev/hot-reloader-types';
|
||||
export declare const DEFAULT_BROWSER_REQUEST_TIMEOUT_MS = 5000;
|
||||
export type BrowserResponse<T> = {
|
||||
url: string;
|
||||
data: T;
|
||||
};
|
||||
export declare function createBrowserRequest<T>(messageType: HMR_MESSAGE_SENT_TO_BROWSER, sendHmrMessage: (message: HmrMessageSentToBrowser) => void, getActiveConnectionCount: () => number, timeoutMs: number): Promise<BrowserResponse<T>[]>;
|
||||
export declare function handleBrowserPageResponse<T>(requestId: string, data: T, url: string): void;
|
||||
90
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/browser-communication.js
generated
vendored
Normal file
90
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/browser-communication.js
generated
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/**
|
||||
* Shared utilities for MCP tools that communicate with the browser.
|
||||
* This module provides a common infrastructure for request-response
|
||||
* communication between MCP endpoints and browser sessions via HMR.
|
||||
*/ "use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
DEFAULT_BROWSER_REQUEST_TIMEOUT_MS: null,
|
||||
createBrowserRequest: null,
|
||||
handleBrowserPageResponse: null
|
||||
});
|
||||
function _export(target, all) {
|
||||
for(var name in all)Object.defineProperty(target, name, {
|
||||
enumerable: true,
|
||||
get: all[name]
|
||||
});
|
||||
}
|
||||
_export(exports, {
|
||||
DEFAULT_BROWSER_REQUEST_TIMEOUT_MS: function() {
|
||||
return DEFAULT_BROWSER_REQUEST_TIMEOUT_MS;
|
||||
},
|
||||
createBrowserRequest: function() {
|
||||
return createBrowserRequest;
|
||||
},
|
||||
handleBrowserPageResponse: function() {
|
||||
return handleBrowserPageResponse;
|
||||
}
|
||||
});
|
||||
const _nanoid = require("next/dist/compiled/nanoid");
|
||||
const DEFAULT_BROWSER_REQUEST_TIMEOUT_MS = 5000;
|
||||
const pendingRequests = new Map();
|
||||
function createBrowserRequest(messageType, sendHmrMessage, getActiveConnectionCount, timeoutMs) {
|
||||
const connectionCount = getActiveConnectionCount();
|
||||
if (connectionCount === 0) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
const requestId = `mcp-${messageType}-${(0, _nanoid.nanoid)()}`;
|
||||
const responsePromise = new Promise((resolve, reject)=>{
|
||||
const timeout = setTimeout(()=>{
|
||||
const pending = pendingRequests.get(requestId);
|
||||
if (pending && pending.responses.length > 0) {
|
||||
resolve(pending.responses);
|
||||
} else {
|
||||
reject(Object.defineProperty(new Error(`Timeout waiting for response from frontend. The browser may not be responding to HMR messages.`), "__NEXT_ERROR_CODE", {
|
||||
value: "E825",
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
}));
|
||||
}
|
||||
pendingRequests.delete(requestId);
|
||||
}, timeoutMs);
|
||||
pendingRequests.set(requestId, {
|
||||
responses: [],
|
||||
expectedCount: connectionCount,
|
||||
resolve: resolve,
|
||||
reject,
|
||||
timeout
|
||||
});
|
||||
});
|
||||
sendHmrMessage({
|
||||
type: messageType,
|
||||
requestId
|
||||
});
|
||||
return responsePromise;
|
||||
}
|
||||
function handleBrowserPageResponse(requestId, data, url) {
|
||||
if (!url) {
|
||||
throw Object.defineProperty(new Error('URL is required in MCP browser response. This is a bug in Next.js.'), "__NEXT_ERROR_CODE", {
|
||||
value: "E824",
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
const pending = pendingRequests.get(requestId);
|
||||
if (pending) {
|
||||
pending.responses.push({
|
||||
url,
|
||||
data
|
||||
});
|
||||
if (pending.responses.length >= pending.expectedCount) {
|
||||
clearTimeout(pending.timeout);
|
||||
pending.resolve(pending.responses);
|
||||
pendingRequests.delete(requestId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//# sourceMappingURL=browser-communication.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/browser-communication.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/browser-communication.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"sources":["../../../../../src/server/mcp/tools/utils/browser-communication.ts"],"sourcesContent":["/**\n * Shared utilities for MCP tools that communicate with the browser.\n * This module provides a common infrastructure for request-response\n * communication between MCP endpoints and browser sessions via HMR.\n */\n\nimport { nanoid } from 'next/dist/compiled/nanoid'\nimport type {\n HMR_MESSAGE_SENT_TO_BROWSER,\n HmrMessageSentToBrowser,\n} from '../../../dev/hot-reloader-types'\n\nexport const DEFAULT_BROWSER_REQUEST_TIMEOUT_MS = 5000\n\nexport type BrowserResponse<T> = {\n url: string\n data: T\n}\n\ntype PendingRequest<T> = {\n responses: BrowserResponse<T>[]\n expectedCount: number\n resolve: (value: BrowserResponse<T>[]) => void\n reject: (reason?: unknown) => void\n timeout: NodeJS.Timeout\n}\n\nconst pendingRequests = new Map<string, PendingRequest<unknown>>()\n\nexport function createBrowserRequest<T>(\n messageType: HMR_MESSAGE_SENT_TO_BROWSER,\n sendHmrMessage: (message: HmrMessageSentToBrowser) => void,\n getActiveConnectionCount: () => number,\n timeoutMs: number\n): Promise<BrowserResponse<T>[]> {\n const connectionCount = getActiveConnectionCount()\n if (connectionCount === 0) {\n return Promise.resolve([])\n }\n\n const requestId = `mcp-${messageType}-${nanoid()}`\n\n const responsePromise = new Promise<BrowserResponse<T>[]>(\n (resolve, reject) => {\n const timeout = setTimeout(() => {\n const pending = pendingRequests.get(requestId)\n if (pending && pending.responses.length > 0) {\n resolve(pending.responses as BrowserResponse<T>[])\n } else {\n reject(\n new Error(\n `Timeout waiting for response from frontend. The browser may not be responding to HMR messages.`\n )\n )\n }\n pendingRequests.delete(requestId)\n }, timeoutMs)\n\n pendingRequests.set(requestId, {\n responses: [],\n expectedCount: connectionCount,\n resolve: resolve as (value: BrowserResponse<unknown>[]) => void,\n reject,\n timeout,\n })\n }\n )\n\n sendHmrMessage({\n type: messageType,\n requestId,\n } as HmrMessageSentToBrowser)\n\n return responsePromise\n}\n\nexport function handleBrowserPageResponse<T>(\n requestId: string,\n data: T,\n url: string\n): void {\n if (!url) {\n throw new Error(\n 'URL is required in MCP browser response. This is a bug in Next.js.'\n )\n }\n\n const pending = pendingRequests.get(requestId)\n if (pending) {\n pending.responses.push({ url, data })\n if (pending.responses.length >= pending.expectedCount) {\n clearTimeout(pending.timeout)\n pending.resolve(pending.responses)\n pendingRequests.delete(requestId)\n }\n }\n}\n"],"names":["DEFAULT_BROWSER_REQUEST_TIMEOUT_MS","createBrowserRequest","handleBrowserPageResponse","pendingRequests","Map","messageType","sendHmrMessage","getActiveConnectionCount","timeoutMs","connectionCount","Promise","resolve","requestId","nanoid","responsePromise","reject","timeout","setTimeout","pending","get","responses","length","Error","delete","set","expectedCount","type","data","url","push","clearTimeout"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;;;;;;IAQYA,kCAAkC;eAAlCA;;IAiBGC,oBAAoB;eAApBA;;IA+CAC,yBAAyB;eAAzBA;;;wBAtEO;AAMhB,MAAMF,qCAAqC;AAelD,MAAMG,kBAAkB,IAAIC;AAErB,SAASH,qBACdI,WAAwC,EACxCC,cAA0D,EAC1DC,wBAAsC,EACtCC,SAAiB;IAEjB,MAAMC,kBAAkBF;IACxB,IAAIE,oBAAoB,GAAG;QACzB,OAAOC,QAAQC,OAAO,CAAC,EAAE;IAC3B;IAEA,MAAMC,YAAY,CAAC,IAAI,EAAEP,YAAY,CAAC,EAAEQ,IAAAA,cAAM,KAAI;IAElD,MAAMC,kBAAkB,IAAIJ,QAC1B,CAACC,SAASI;QACR,MAAMC,UAAUC,WAAW;YACzB,MAAMC,UAAUf,gBAAgBgB,GAAG,CAACP;YACpC,IAAIM,WAAWA,QAAQE,SAAS,CAACC,MAAM,GAAG,GAAG;gBAC3CV,QAAQO,QAAQE,SAAS;YAC3B,OAAO;gBACLL,OACE,qBAEC,CAFD,IAAIO,MACF,CAAC,8FAA8F,CAAC,GADlG,qBAAA;2BAAA;gCAAA;kCAAA;gBAEA;YAEJ;YACAnB,gBAAgBoB,MAAM,CAACX;QACzB,GAAGJ;QAEHL,gBAAgBqB,GAAG,CAACZ,WAAW;YAC7BQ,WAAW,EAAE;YACbK,eAAehB;YACfE,SAASA;YACTI;YACAC;QACF;IACF;IAGFV,eAAe;QACboB,MAAMrB;QACNO;IACF;IAEA,OAAOE;AACT;AAEO,SAASZ,0BACdU,SAAiB,EACjBe,IAAO,EACPC,GAAW;IAEX,IAAI,CAACA,KAAK;QACR,MAAM,qBAEL,CAFK,IAAIN,MACR,uEADI,qBAAA;mBAAA;wBAAA;0BAAA;QAEN;IACF;IAEA,MAAMJ,UAAUf,gBAAgBgB,GAAG,CAACP;IACpC,IAAIM,SAAS;QACXA,QAAQE,SAAS,CAACS,IAAI,CAAC;YAAED;YAAKD;QAAK;QACnC,IAAIT,QAAQE,SAAS,CAACC,MAAM,IAAIH,QAAQO,aAAa,EAAE;YACrDK,aAAaZ,QAAQF,OAAO;YAC5BE,QAAQP,OAAO,CAACO,QAAQE,SAAS;YACjCjB,gBAAgBoB,MAAM,CAACX;QACzB;IACF;AACF","ignoreList":[0]}
|
||||
8
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/format-errors.d.ts
generated
vendored
Normal file
8
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/format-errors.d.ts
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { OverlayState } from '../../../../next-devtools/dev-overlay/shared';
|
||||
import type { OriginalStackFramesRequest, OriginalStackFramesResponse } from '../../../../next-devtools/server/shared';
|
||||
type StackFrameResolver = (request: OriginalStackFramesRequest) => Promise<OriginalStackFramesResponse>;
|
||||
export declare function setStackFrameResolver(fn: StackFrameResolver): void;
|
||||
export declare function formatErrors(errorsByUrl: Map<string, OverlayState>, nextInstanceErrors?: {
|
||||
nextConfig: unknown[];
|
||||
}): Promise<string>;
|
||||
export {};
|
||||
147
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/format-errors.js
generated
vendored
Normal file
147
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/format-errors.js
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
0 && (module.exports = {
|
||||
formatErrors: null,
|
||||
setStackFrameResolver: null
|
||||
});
|
||||
function _export(target, all) {
|
||||
for(var name in all)Object.defineProperty(target, name, {
|
||||
enumerable: true,
|
||||
get: all[name]
|
||||
});
|
||||
}
|
||||
_export(exports, {
|
||||
formatErrors: function() {
|
||||
return formatErrors;
|
||||
},
|
||||
setStackFrameResolver: function() {
|
||||
return setStackFrameResolver;
|
||||
}
|
||||
});
|
||||
const _errorsource = require("../../../../shared/lib/error-source");
|
||||
// Dependency injection for stack frame resolver
|
||||
let stackFrameResolver;
|
||||
function setStackFrameResolver(fn) {
|
||||
stackFrameResolver = fn;
|
||||
}
|
||||
async function resolveStackFrames(request) {
|
||||
if (!stackFrameResolver) {
|
||||
throw Object.defineProperty(new Error('Stack frame resolver not initialized. This is a bug in Next.js.'), "__NEXT_ERROR_CODE", {
|
||||
value: "E822",
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
return stackFrameResolver(request);
|
||||
}
|
||||
const formatStackFrame = (frame)=>{
|
||||
const file = frame.file || '<unknown>';
|
||||
const method = frame.methodName || '<anonymous>';
|
||||
const { line1: line, column1: column } = frame;
|
||||
return line && column ? ` at ${method} (${file}:${line}:${column})` : line ? ` at ${method} (${file}:${line})` : ` at ${method} (${file})`;
|
||||
};
|
||||
const formatErrorFrames = async (frames, context)=>{
|
||||
try {
|
||||
const resolvedFrames = await resolveStackFrames({
|
||||
frames: frames.map((frame)=>({
|
||||
file: frame.file || null,
|
||||
methodName: frame.methodName || '<anonymous>',
|
||||
arguments: [],
|
||||
line1: frame.line1 || null,
|
||||
column1: frame.column1 || null
|
||||
})),
|
||||
isServer: context.isServer,
|
||||
isEdgeServer: context.isEdgeServer,
|
||||
isAppDirectory: context.isAppDirectory
|
||||
});
|
||||
return resolvedFrames.filter((resolvedFrame)=>{
|
||||
var _resolvedFrame_value_originalStackFrame;
|
||||
return !(resolvedFrame.status === 'fulfilled' && ((_resolvedFrame_value_originalStackFrame = resolvedFrame.value.originalStackFrame) == null ? void 0 : _resolvedFrame_value_originalStackFrame.ignored));
|
||||
}).map((resolvedFrame, j)=>resolvedFrame.status === 'fulfilled' && resolvedFrame.value.originalStackFrame ? formatStackFrame(resolvedFrame.value.originalStackFrame) : formatStackFrame(frames[j])).join('\n') + '\n';
|
||||
} catch {
|
||||
return frames.map(formatStackFrame).join('\n') + '\n';
|
||||
}
|
||||
};
|
||||
async function formatRuntimeError(errors, isAppDirectory) {
|
||||
const formatError = async (error, index)=>{
|
||||
var _error_error, _error_error1, _error_frames;
|
||||
const errorHeader = `\n#### Error ${index + 1} (Type: ${error.type})\n\n`;
|
||||
const errorName = ((_error_error = error.error) == null ? void 0 : _error_error.name) || 'Error';
|
||||
const errorMsg = ((_error_error1 = error.error) == null ? void 0 : _error_error1.message) || 'Unknown error';
|
||||
const errorMessage = `**${errorName}**: ${errorMsg}\n\n`;
|
||||
if (!((_error_frames = error.frames) == null ? void 0 : _error_frames.length)) {
|
||||
var _error_error2;
|
||||
const stack = ((_error_error2 = error.error) == null ? void 0 : _error_error2.stack) || '';
|
||||
return errorHeader + errorMessage + (stack ? `\`\`\`\n${stack}\n\`\`\`\n` : '');
|
||||
}
|
||||
const errorSource = (0, _errorsource.getErrorSource)(error.error);
|
||||
const frames = await formatErrorFrames(error.frames, {
|
||||
isServer: errorSource === 'server',
|
||||
isEdgeServer: errorSource === 'edge-server',
|
||||
isAppDirectory
|
||||
});
|
||||
return errorHeader + errorMessage + `\`\`\`\n${frames}\`\`\`\n`;
|
||||
};
|
||||
const formattedErrors = await Promise.all(errors.map(formatError));
|
||||
return '### Runtime Errors\n' + formattedErrors.join('\n---\n');
|
||||
}
|
||||
async function formatErrors(errorsByUrl, nextInstanceErrors = {
|
||||
nextConfig: []
|
||||
}) {
|
||||
let output = '';
|
||||
// Format Next.js instance errors first (e.g., next.config.js errors)
|
||||
if (nextInstanceErrors.nextConfig.length > 0) {
|
||||
output += `# Next.js Configuration Errors\n\n`;
|
||||
output += `**${nextInstanceErrors.nextConfig.length} error(s) found in next.config**\n\n`;
|
||||
nextInstanceErrors.nextConfig.forEach((error, index)=>{
|
||||
output += `## Error ${index + 1}\n\n`;
|
||||
output += '```\n';
|
||||
if (error instanceof Error) {
|
||||
output += `${error.name}: ${error.message}\n`;
|
||||
if (error.stack) {
|
||||
output += error.stack;
|
||||
}
|
||||
} else {
|
||||
output += String(error);
|
||||
}
|
||||
output += '\n```\n\n';
|
||||
});
|
||||
output += '---\n\n';
|
||||
}
|
||||
// Format browser session errors
|
||||
if (errorsByUrl.size > 0) {
|
||||
output += `# Found errors in ${errorsByUrl.size} browser session(s)\n\n`;
|
||||
for (const [url, overlayState] of errorsByUrl){
|
||||
const totalErrorCount = overlayState.errors.length + (overlayState.buildError ? 1 : 0);
|
||||
if (totalErrorCount === 0) continue;
|
||||
let displayUrl = url;
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
displayUrl = urlObj.pathname + urlObj.search + urlObj.hash;
|
||||
} catch {
|
||||
// If URL parsing fails, use the original URL
|
||||
}
|
||||
output += `## Session: ${displayUrl}\n\n`;
|
||||
output += `**${totalErrorCount} error(s) found**\n\n`;
|
||||
// Build errors
|
||||
if (overlayState.buildError) {
|
||||
output += '### Build Error\n\n';
|
||||
output += '```\n';
|
||||
output += overlayState.buildError;
|
||||
output += '\n```\n\n';
|
||||
}
|
||||
// Runtime errors with source-mapped stack traces
|
||||
if (overlayState.errors.length > 0) {
|
||||
const runtimeErrors = await formatRuntimeError(overlayState.errors, overlayState.routerType === 'app');
|
||||
output += runtimeErrors;
|
||||
output += '\n';
|
||||
}
|
||||
output += '---\n\n';
|
||||
}
|
||||
}
|
||||
return output.trim();
|
||||
}
|
||||
|
||||
//# sourceMappingURL=format-errors.js.map
|
||||
1
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/format-errors.js.map
generated
vendored
Normal file
1
apps/public-web/node_modules/next/dist/server/mcp/tools/utils/format-errors.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user