@agiflowai/scaffold-mcp 1.0.21 → 1.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +23 -22
- package/dist/cli.mjs +6 -5
- package/dist/index.cjs +12 -11
- package/dist/index.mjs +2 -1
- package/dist/stdio-BqcCsHuC.mjs +331 -0
- package/dist/stdio-D8getFsj.cjs +350 -0
- package/dist/{stdio-Boc4SGGT.mjs → tools-DRfJ2LZc.mjs} +1 -330
- package/dist/{stdio-Bw7Hyv3X.cjs → tools-S18iKO9I.cjs} +0 -348
- package/dist/{useScaffoldMethod-BR3ESqor.cjs → useScaffoldMethod-CmnKY0Vu.cjs} +80 -40
- package/dist/{useScaffoldMethod-DlrzH-3H.mjs → useScaffoldMethod-blx199pL.mjs} +80 -40
- package/package.json +5 -5
- /package/dist/{phantomCodeCheck-BXQonrXo.mjs → phantomCodeCheck-BwQWRJ9Q.mjs} +0 -0
- /package/dist/{phantomCodeCheck-DNkWyMRE.cjs → phantomCodeCheck-DhzeymO-.cjs} +0 -0
- /package/dist/{useScaffoldMethod-DaAZTyIM.mjs → useScaffoldMethod-BE2tHUMc.mjs} +0 -0
- /package/dist/{useScaffoldMethod-CJG7ngkT.cjs → useScaffoldMethod-CejnYNDD.cjs} +0 -0
package/dist/cli.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const require_ListScaffoldingMethodsTool = require('./ListScaffoldingMethodsTool-Dnd3E5X_.cjs');
|
|
3
|
-
const
|
|
3
|
+
const require_tools = require('./tools-S18iKO9I.cjs');
|
|
4
|
+
const require_stdio = require('./stdio-D8getFsj.cjs');
|
|
4
5
|
let node_path = require("node:path");
|
|
5
6
|
node_path = require_ListScaffoldingMethodsTool.__toESM(node_path);
|
|
6
7
|
let __agiflowai_aicode_utils = require("@agiflowai/aicode-utils");
|
|
@@ -12,7 +13,7 @@ let __agiflowai_coding_agent_bridge = require("@agiflowai/coding-agent-bridge");
|
|
|
12
13
|
let __agiflowai_hooks_adapter = require("@agiflowai/hooks-adapter");
|
|
13
14
|
|
|
14
15
|
//#region package.json
|
|
15
|
-
var version = "1.0.
|
|
16
|
+
var version = "1.0.21";
|
|
16
17
|
|
|
17
18
|
//#endregion
|
|
18
19
|
//#region src/commands/boilerplate.ts
|
|
@@ -27,7 +28,7 @@ boilerplateCommand.command("list").description("List all available boilerplate t
|
|
|
27
28
|
__agiflowai_aicode_utils.messages.error("Templates folder not found. Create a templates folder or specify templatesPath in toolkit.yaml");
|
|
28
29
|
process.exit(1);
|
|
29
30
|
}
|
|
30
|
-
const { boilerplates, nextCursor } = await new
|
|
31
|
+
const { boilerplates, nextCursor } = await new require_tools.BoilerplateService(templatesDir).listBoilerplates(options.cursor);
|
|
31
32
|
if (boilerplates.length === 0) {
|
|
32
33
|
__agiflowai_aicode_utils.messages.warning("No boilerplate templates found.");
|
|
33
34
|
return;
|
|
@@ -58,7 +59,7 @@ boilerplateCommand.command("create <boilerplateName>").description("Create a new
|
|
|
58
59
|
__agiflowai_aicode_utils.messages.error("Templates folder not found. Create a templates folder or specify templatesPath in toolkit.yaml");
|
|
59
60
|
process.exit(1);
|
|
60
61
|
}
|
|
61
|
-
const boilerplateService = new
|
|
62
|
+
const boilerplateService = new require_tools.BoilerplateService(templatesDir);
|
|
62
63
|
let variables = {};
|
|
63
64
|
if (options.vars) try {
|
|
64
65
|
variables = JSON.parse(options.vars);
|
|
@@ -135,7 +136,7 @@ boilerplateCommand.command("info <boilerplateName>").description("Show detailed
|
|
|
135
136
|
__agiflowai_aicode_utils.messages.error("Templates folder not found. Create a templates folder or specify templatesPath in toolkit.yaml");
|
|
136
137
|
process.exit(1);
|
|
137
138
|
}
|
|
138
|
-
const bp = await new
|
|
139
|
+
const bp = await new require_tools.BoilerplateService(templatesDir).getBoilerplate(boilerplateName);
|
|
139
140
|
if (!bp) {
|
|
140
141
|
__agiflowai_aicode_utils.messages.error(`Boilerplate '${boilerplateName}' not found.`);
|
|
141
142
|
process.exit(1);
|
|
@@ -474,14 +475,14 @@ function createServer(options = {}) {
|
|
|
474
475
|
const { adminEnabled = false, isMonolith = false, promptAsSkill = false } = options;
|
|
475
476
|
const templatesPath = __agiflowai_aicode_utils.TemplatesManagerService.findTemplatesPathSync();
|
|
476
477
|
if (!templatesPath) throw new Error("Templates folder not found. Please create a \"templates\" folder in your workspace root, or specify \"templatesPath\" in toolkit.yaml to point to your templates directory.");
|
|
477
|
-
const listBoilerplatesTool = !isMonolith ? new
|
|
478
|
-
const useBoilerplateTool = !isMonolith ? new
|
|
478
|
+
const listBoilerplatesTool = !isMonolith ? new require_tools.ListBoilerplatesTool(templatesPath, isMonolith) : null;
|
|
479
|
+
const useBoilerplateTool = !isMonolith ? new require_tools.UseBoilerplateTool(templatesPath, isMonolith) : null;
|
|
479
480
|
const listScaffoldingMethodsTool = new require_ListScaffoldingMethodsTool.ListScaffoldingMethodsTool(templatesPath, isMonolith);
|
|
480
|
-
const useScaffoldMethodTool = new
|
|
481
|
-
const writeToFileTool = new
|
|
482
|
-
const generateBoilerplateTool = adminEnabled ? new
|
|
483
|
-
const generateBoilerplateFileTool = adminEnabled ? new
|
|
484
|
-
const generateFeatureScaffoldTool = adminEnabled ? new
|
|
481
|
+
const useScaffoldMethodTool = new require_tools.UseScaffoldMethodTool(templatesPath, isMonolith);
|
|
482
|
+
const writeToFileTool = new require_tools.WriteToFileTool();
|
|
483
|
+
const generateBoilerplateTool = adminEnabled ? new require_tools.GenerateBoilerplateTool(templatesPath, isMonolith) : null;
|
|
484
|
+
const generateBoilerplateFileTool = adminEnabled ? new require_tools.GenerateBoilerplateFileTool(templatesPath, isMonolith) : null;
|
|
485
|
+
const generateFeatureScaffoldTool = adminEnabled ? new require_tools.GenerateFeatureScaffoldTool(templatesPath, isMonolith) : null;
|
|
485
486
|
const generateBoilerplatePrompt = adminEnabled ? new GenerateBoilerplatePrompt({
|
|
486
487
|
isMonolith,
|
|
487
488
|
promptAsSkill
|
|
@@ -535,26 +536,26 @@ function createServer(options = {}) {
|
|
|
535
536
|
});
|
|
536
537
|
server.setRequestHandler(__modelcontextprotocol_sdk_types_js.CallToolRequestSchema, async (request) => {
|
|
537
538
|
const { name, arguments: args } = request.params;
|
|
538
|
-
if (name ===
|
|
539
|
+
if (name === require_tools.ListBoilerplatesTool.TOOL_NAME) {
|
|
539
540
|
if (isMonolith || !listBoilerplatesTool) throw new Error("Boilerplate tools are not available for monolith projects");
|
|
540
541
|
return await listBoilerplatesTool.execute(args || {});
|
|
541
542
|
}
|
|
542
|
-
if (name ===
|
|
543
|
+
if (name === require_tools.UseBoilerplateTool.TOOL_NAME) {
|
|
543
544
|
if (isMonolith || !useBoilerplateTool) throw new Error("Boilerplate tools are not available for monolith projects");
|
|
544
545
|
return await useBoilerplateTool.execute(args || {});
|
|
545
546
|
}
|
|
546
547
|
if (name === require_ListScaffoldingMethodsTool.ListScaffoldingMethodsTool.TOOL_NAME) return await listScaffoldingMethodsTool.execute(args || {});
|
|
547
|
-
if (name ===
|
|
548
|
-
if (name ===
|
|
549
|
-
if (name ===
|
|
548
|
+
if (name === require_tools.UseScaffoldMethodTool.TOOL_NAME) return await useScaffoldMethodTool.execute(args || {});
|
|
549
|
+
if (name === require_tools.WriteToFileTool.TOOL_NAME) return await writeToFileTool.execute(args || {});
|
|
550
|
+
if (name === require_tools.GenerateBoilerplateTool.TOOL_NAME) {
|
|
550
551
|
if (!adminEnabled || !generateBoilerplateTool) throw new Error("Admin tools are not enabled. Use --admin-enable flag to enable.");
|
|
551
552
|
return await generateBoilerplateTool.execute(args);
|
|
552
553
|
}
|
|
553
|
-
if (name ===
|
|
554
|
+
if (name === require_tools.GenerateBoilerplateFileTool.TOOL_NAME) {
|
|
554
555
|
if (!adminEnabled || !generateBoilerplateFileTool) throw new Error("Admin tools are not enabled. Use --admin-enable flag to enable.");
|
|
555
556
|
return await generateBoilerplateFileTool.execute(args);
|
|
556
557
|
}
|
|
557
|
-
if (name ===
|
|
558
|
+
if (name === require_tools.GenerateFeatureScaffoldTool.TOOL_NAME) {
|
|
558
559
|
if (!adminEnabled || !generateFeatureScaffoldTool) throw new Error("Admin tools are not enabled. Use --admin-enable flag to enable.");
|
|
559
560
|
return await generateFeatureScaffoldTool.execute(args);
|
|
560
561
|
}
|
|
@@ -906,8 +907,8 @@ const hookCommand = new commander.Command("hook").description("Execute scaffold
|
|
|
906
907
|
}
|
|
907
908
|
const { agent, hookMethod } = (0, __agiflowai_hooks_adapter.parseHookType)(options.type);
|
|
908
909
|
if (agent === __agiflowai_coding_agent_bridge.CLAUDE_CODE) {
|
|
909
|
-
const useScaffoldMethodModule = await Promise.resolve().then(() => require("./useScaffoldMethod-
|
|
910
|
-
const phantomCodeCheckModule = await Promise.resolve().then(() => require("./phantomCodeCheck-
|
|
910
|
+
const useScaffoldMethodModule = await Promise.resolve().then(() => require("./useScaffoldMethod-CmnKY0Vu.cjs"));
|
|
911
|
+
const phantomCodeCheckModule = await Promise.resolve().then(() => require("./phantomCodeCheck-DhzeymO-.cjs"));
|
|
911
912
|
const claudeCallbacks = [];
|
|
912
913
|
if (useScaffoldMethodModule.UseScaffoldMethodHook) {
|
|
913
914
|
const hookInstance = new useScaffoldMethodModule.UseScaffoldMethodHook();
|
|
@@ -923,7 +924,7 @@ const hookCommand = new commander.Command("hook").description("Execute scaffold
|
|
|
923
924
|
if (claudeCallbacks.length === 0) process.exit(0);
|
|
924
925
|
await new __agiflowai_hooks_adapter.ClaudeCodeAdapter().executeMultiple(claudeCallbacks);
|
|
925
926
|
} else if (agent === __agiflowai_coding_agent_bridge.GEMINI_CLI) {
|
|
926
|
-
const useScaffoldMethodModule = await Promise.resolve().then(() => require("./useScaffoldMethod-
|
|
927
|
+
const useScaffoldMethodModule = await Promise.resolve().then(() => require("./useScaffoldMethod-CejnYNDD.cjs"));
|
|
927
928
|
const geminiCallbacks = [];
|
|
928
929
|
if (useScaffoldMethodModule.UseScaffoldMethodHook) {
|
|
929
930
|
const hookInstance = new useScaffoldMethodModule.UseScaffoldMethodHook();
|
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as
|
|
2
|
+
import { a as GenerateFeatureScaffoldTool, i as ListBoilerplatesTool, l as BoilerplateService, n as UseScaffoldMethodTool, o as GenerateBoilerplateTool, r as UseBoilerplateTool, s as GenerateBoilerplateFileTool, t as WriteToFileTool } from "./tools-DRfJ2LZc.mjs";
|
|
3
3
|
import { c as FileSystemService, i as TemplateService, n as ScaffoldingMethodsService, t as ListScaffoldingMethodsTool } from "./ListScaffoldingMethodsTool-DjhhMWjh.mjs";
|
|
4
|
+
import { n as SseTransportHandler, r as HttpTransportHandler, t as StdioTransportHandler } from "./stdio-BqcCsHuC.mjs";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { ProjectConfigResolver, TemplatesManagerService, icons, messages, print, sections } from "@agiflowai/aicode-utils";
|
|
6
7
|
import { z } from "zod";
|
|
@@ -11,7 +12,7 @@ import { CLAUDE_CODE, GEMINI_CLI } from "@agiflowai/coding-agent-bridge";
|
|
|
11
12
|
import { ClaudeCodeAdapter, GeminiCliAdapter, parseHookType } from "@agiflowai/hooks-adapter";
|
|
12
13
|
|
|
13
14
|
//#region package.json
|
|
14
|
-
var version = "1.0.
|
|
15
|
+
var version = "1.0.21";
|
|
15
16
|
|
|
16
17
|
//#endregion
|
|
17
18
|
//#region src/commands/boilerplate.ts
|
|
@@ -905,8 +906,8 @@ const hookCommand = new Command("hook").description("Execute scaffold hooks for
|
|
|
905
906
|
}
|
|
906
907
|
const { agent, hookMethod } = parseHookType(options.type);
|
|
907
908
|
if (agent === CLAUDE_CODE) {
|
|
908
|
-
const useScaffoldMethodModule = await import("./useScaffoldMethod-
|
|
909
|
-
const phantomCodeCheckModule = await import("./phantomCodeCheck-
|
|
909
|
+
const useScaffoldMethodModule = await import("./useScaffoldMethod-blx199pL.mjs");
|
|
910
|
+
const phantomCodeCheckModule = await import("./phantomCodeCheck-BwQWRJ9Q.mjs");
|
|
910
911
|
const claudeCallbacks = [];
|
|
911
912
|
if (useScaffoldMethodModule.UseScaffoldMethodHook) {
|
|
912
913
|
const hookInstance = new useScaffoldMethodModule.UseScaffoldMethodHook();
|
|
@@ -922,7 +923,7 @@ const hookCommand = new Command("hook").description("Execute scaffold hooks for
|
|
|
922
923
|
if (claudeCallbacks.length === 0) process.exit(0);
|
|
923
924
|
await new ClaudeCodeAdapter().executeMultiple(claudeCallbacks);
|
|
924
925
|
} else if (agent === GEMINI_CLI) {
|
|
925
|
-
const useScaffoldMethodModule = await import("./useScaffoldMethod-
|
|
926
|
+
const useScaffoldMethodModule = await import("./useScaffoldMethod-BE2tHUMc.mjs");
|
|
926
927
|
const geminiCallbacks = [];
|
|
927
928
|
if (useScaffoldMethodModule.UseScaffoldMethodHook) {
|
|
928
929
|
const hookInstance = new useScaffoldMethodModule.UseScaffoldMethodHook();
|
package/dist/index.cjs
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
const require_ListScaffoldingMethodsTool = require('./ListScaffoldingMethodsTool-Dnd3E5X_.cjs');
|
|
2
|
-
const
|
|
2
|
+
const require_tools = require('./tools-S18iKO9I.cjs');
|
|
3
|
+
const require_stdio = require('./stdio-D8getFsj.cjs');
|
|
3
4
|
|
|
4
|
-
exports.BoilerplateGeneratorService =
|
|
5
|
-
exports.BoilerplateService =
|
|
5
|
+
exports.BoilerplateGeneratorService = require_tools.BoilerplateGeneratorService;
|
|
6
|
+
exports.BoilerplateService = require_tools.BoilerplateService;
|
|
6
7
|
exports.FileSystemService = require_ListScaffoldingMethodsTool.FileSystemService;
|
|
7
|
-
exports.GenerateBoilerplateFileTool =
|
|
8
|
-
exports.GenerateBoilerplateTool =
|
|
9
|
-
exports.GenerateFeatureScaffoldTool =
|
|
8
|
+
exports.GenerateBoilerplateFileTool = require_tools.GenerateBoilerplateFileTool;
|
|
9
|
+
exports.GenerateBoilerplateTool = require_tools.GenerateBoilerplateTool;
|
|
10
|
+
exports.GenerateFeatureScaffoldTool = require_tools.GenerateFeatureScaffoldTool;
|
|
10
11
|
exports.HttpTransportHandler = require_stdio.HttpTransportHandler;
|
|
11
|
-
exports.ListBoilerplatesTool =
|
|
12
|
+
exports.ListBoilerplatesTool = require_tools.ListBoilerplatesTool;
|
|
12
13
|
exports.ListScaffoldingMethodsTool = require_ListScaffoldingMethodsTool.ListScaffoldingMethodsTool;
|
|
13
14
|
exports.ScaffoldConfigLoader = require_ListScaffoldingMethodsTool.ScaffoldConfigLoader;
|
|
14
|
-
exports.ScaffoldGeneratorService =
|
|
15
|
+
exports.ScaffoldGeneratorService = require_tools.ScaffoldGeneratorService;
|
|
15
16
|
exports.ScaffoldProcessingService = require_ListScaffoldingMethodsTool.ScaffoldProcessingService;
|
|
16
17
|
exports.ScaffoldService = require_ListScaffoldingMethodsTool.ScaffoldService;
|
|
17
18
|
exports.ScaffoldingMethodsService = require_ListScaffoldingMethodsTool.ScaffoldingMethodsService;
|
|
18
19
|
exports.SseTransportHandler = require_stdio.SseTransportHandler;
|
|
19
20
|
exports.StdioTransportHandler = require_stdio.StdioTransportHandler;
|
|
20
21
|
exports.TemplateService = require_ListScaffoldingMethodsTool.TemplateService;
|
|
21
|
-
exports.UseBoilerplateTool =
|
|
22
|
-
exports.UseScaffoldMethodTool =
|
|
22
|
+
exports.UseBoilerplateTool = require_tools.UseBoilerplateTool;
|
|
23
|
+
exports.UseScaffoldMethodTool = require_tools.UseScaffoldMethodTool;
|
|
23
24
|
exports.VariableReplacementService = require_ListScaffoldingMethodsTool.VariableReplacementService;
|
|
24
|
-
exports.WriteToFileTool =
|
|
25
|
+
exports.WriteToFileTool = require_tools.WriteToFileTool;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as GenerateFeatureScaffoldTool, c as ScaffoldGeneratorService, i as ListBoilerplatesTool, l as BoilerplateService, n as UseScaffoldMethodTool, o as GenerateBoilerplateTool, r as UseBoilerplateTool, s as GenerateBoilerplateFileTool, t as WriteToFileTool, u as BoilerplateGeneratorService } from "./tools-DRfJ2LZc.mjs";
|
|
2
2
|
import { a as ScaffoldService, c as FileSystemService, i as TemplateService, n as ScaffoldingMethodsService, o as ScaffoldProcessingService, r as VariableReplacementService, s as ScaffoldConfigLoader, t as ListScaffoldingMethodsTool } from "./ListScaffoldingMethodsTool-DjhhMWjh.mjs";
|
|
3
|
+
import { n as SseTransportHandler, r as HttpTransportHandler, t as StdioTransportHandler } from "./stdio-BqcCsHuC.mjs";
|
|
3
4
|
|
|
4
5
|
export { BoilerplateGeneratorService, BoilerplateService, FileSystemService, GenerateBoilerplateFileTool, GenerateBoilerplateTool, GenerateFeatureScaffoldTool, HttpTransportHandler, ListBoilerplatesTool, ListScaffoldingMethodsTool, ScaffoldConfigLoader, ScaffoldGeneratorService, ScaffoldProcessingService, ScaffoldService, ScaffoldingMethodsService, SseTransportHandler, StdioTransportHandler, TemplateService, UseBoilerplateTool, UseScaffoldMethodTool, VariableReplacementService, WriteToFileTool };
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
3
|
+
import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js";
|
|
4
|
+
import express from "express";
|
|
5
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
6
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
+
|
|
8
|
+
//#region src/transports/http.ts
|
|
9
|
+
/**
|
|
10
|
+
* HTTP session manager
|
|
11
|
+
*/
|
|
12
|
+
var HttpFullSessionManager = class {
|
|
13
|
+
sessions = /* @__PURE__ */ new Map();
|
|
14
|
+
getSession(sessionId) {
|
|
15
|
+
return this.sessions.get(sessionId);
|
|
16
|
+
}
|
|
17
|
+
setSession(sessionId, transport, server) {
|
|
18
|
+
this.sessions.set(sessionId, {
|
|
19
|
+
transport,
|
|
20
|
+
server
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
deleteSession(sessionId) {
|
|
24
|
+
const session = this.sessions.get(sessionId);
|
|
25
|
+
if (session) session.server.close();
|
|
26
|
+
this.sessions.delete(sessionId);
|
|
27
|
+
}
|
|
28
|
+
hasSession(sessionId) {
|
|
29
|
+
return this.sessions.has(sessionId);
|
|
30
|
+
}
|
|
31
|
+
clear() {
|
|
32
|
+
for (const session of this.sessions.values()) session.server.close();
|
|
33
|
+
this.sessions.clear();
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* HTTP transport handler using Streamable HTTP (protocol version 2025-03-26)
|
|
38
|
+
* Provides stateful session management with resumability support
|
|
39
|
+
*/
|
|
40
|
+
var HttpTransportHandler = class {
|
|
41
|
+
serverFactory;
|
|
42
|
+
app;
|
|
43
|
+
server = null;
|
|
44
|
+
sessionManager;
|
|
45
|
+
config;
|
|
46
|
+
constructor(serverFactory, config) {
|
|
47
|
+
this.serverFactory = typeof serverFactory === "function" ? serverFactory : () => serverFactory;
|
|
48
|
+
this.app = express();
|
|
49
|
+
this.sessionManager = new HttpFullSessionManager();
|
|
50
|
+
this.config = {
|
|
51
|
+
mode: config.mode,
|
|
52
|
+
port: config.port ?? 3e3,
|
|
53
|
+
host: config.host ?? "localhost"
|
|
54
|
+
};
|
|
55
|
+
this.setupMiddleware();
|
|
56
|
+
this.setupRoutes();
|
|
57
|
+
}
|
|
58
|
+
setupMiddleware() {
|
|
59
|
+
this.app.use(express.json());
|
|
60
|
+
}
|
|
61
|
+
setupRoutes() {
|
|
62
|
+
this.app.post("/mcp", async (req, res) => {
|
|
63
|
+
await this.handlePostRequest(req, res);
|
|
64
|
+
});
|
|
65
|
+
this.app.get("/mcp", async (req, res) => {
|
|
66
|
+
await this.handleGetRequest(req, res);
|
|
67
|
+
});
|
|
68
|
+
this.app.delete("/mcp", async (req, res) => {
|
|
69
|
+
await this.handleDeleteRequest(req, res);
|
|
70
|
+
});
|
|
71
|
+
this.app.get("/health", (_req, res) => {
|
|
72
|
+
res.json({
|
|
73
|
+
status: "ok",
|
|
74
|
+
transport: "http"
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
async handlePostRequest(req, res) {
|
|
79
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
80
|
+
let transport;
|
|
81
|
+
if (sessionId && this.sessionManager.hasSession(sessionId)) transport = this.sessionManager.getSession(sessionId).transport;
|
|
82
|
+
else if (!sessionId && isInitializeRequest(req.body)) {
|
|
83
|
+
const mcpServer = this.serverFactory();
|
|
84
|
+
transport = new StreamableHTTPServerTransport({
|
|
85
|
+
sessionIdGenerator: () => randomUUID(),
|
|
86
|
+
enableJsonResponse: true,
|
|
87
|
+
onsessioninitialized: (sessionId$1) => {
|
|
88
|
+
this.sessionManager.setSession(sessionId$1, transport, mcpServer);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
transport.onclose = () => {
|
|
92
|
+
if (transport.sessionId) this.sessionManager.deleteSession(transport.sessionId);
|
|
93
|
+
};
|
|
94
|
+
await mcpServer.connect(transport);
|
|
95
|
+
} else {
|
|
96
|
+
res.status(400).json({
|
|
97
|
+
jsonrpc: "2.0",
|
|
98
|
+
error: {
|
|
99
|
+
code: -32e3,
|
|
100
|
+
message: "Bad Request: No valid session ID provided"
|
|
101
|
+
},
|
|
102
|
+
id: null
|
|
103
|
+
});
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
await transport.handleRequest(req, res, req.body);
|
|
107
|
+
}
|
|
108
|
+
async handleGetRequest(req, res) {
|
|
109
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
110
|
+
if (!sessionId || !this.sessionManager.hasSession(sessionId)) {
|
|
111
|
+
res.status(400).send("Invalid or missing session ID");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
await this.sessionManager.getSession(sessionId).transport.handleRequest(req, res);
|
|
115
|
+
}
|
|
116
|
+
async handleDeleteRequest(req, res) {
|
|
117
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
118
|
+
if (!sessionId || !this.sessionManager.hasSession(sessionId)) {
|
|
119
|
+
res.status(400).send("Invalid or missing session ID");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
await this.sessionManager.getSession(sessionId).transport.handleRequest(req, res);
|
|
123
|
+
this.sessionManager.deleteSession(sessionId);
|
|
124
|
+
}
|
|
125
|
+
async start() {
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
try {
|
|
128
|
+
this.server = this.app.listen(this.config.port, this.config.host, () => {
|
|
129
|
+
console.error(`Scaffolding MCP server started on http://${this.config.host}:${this.config.port}/mcp`);
|
|
130
|
+
console.error(`Health check: http://${this.config.host}:${this.config.port}/health`);
|
|
131
|
+
resolve();
|
|
132
|
+
});
|
|
133
|
+
this.server.on("error", (error) => {
|
|
134
|
+
reject(error);
|
|
135
|
+
});
|
|
136
|
+
} catch (error) {
|
|
137
|
+
reject(error);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async stop() {
|
|
142
|
+
return new Promise((resolve, reject) => {
|
|
143
|
+
if (this.server) {
|
|
144
|
+
this.sessionManager.clear();
|
|
145
|
+
this.server.close((err) => {
|
|
146
|
+
if (err) reject(err);
|
|
147
|
+
else {
|
|
148
|
+
this.server = null;
|
|
149
|
+
resolve();
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
} else resolve();
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
getPort() {
|
|
156
|
+
return this.config.port;
|
|
157
|
+
}
|
|
158
|
+
getHost() {
|
|
159
|
+
return this.config.host;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/transports/sse.ts
|
|
165
|
+
/**
|
|
166
|
+
* Session manager for SSE transports
|
|
167
|
+
*/
|
|
168
|
+
var SseSessionManager = class {
|
|
169
|
+
sessions = /* @__PURE__ */ new Map();
|
|
170
|
+
getSession(sessionId) {
|
|
171
|
+
return this.sessions.get(sessionId)?.transport;
|
|
172
|
+
}
|
|
173
|
+
setSession(sessionId, transport, server) {
|
|
174
|
+
this.sessions.set(sessionId, {
|
|
175
|
+
transport,
|
|
176
|
+
server
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
deleteSession(sessionId) {
|
|
180
|
+
const session = this.sessions.get(sessionId);
|
|
181
|
+
if (session) session.server.close();
|
|
182
|
+
this.sessions.delete(sessionId);
|
|
183
|
+
}
|
|
184
|
+
hasSession(sessionId) {
|
|
185
|
+
return this.sessions.has(sessionId);
|
|
186
|
+
}
|
|
187
|
+
clear() {
|
|
188
|
+
for (const session of this.sessions.values()) session.server.close();
|
|
189
|
+
this.sessions.clear();
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* SSE (Server-Sent Events) transport handler
|
|
194
|
+
* Legacy transport for backwards compatibility (protocol version 2024-11-05)
|
|
195
|
+
* Uses separate endpoints: /sse for SSE stream (GET) and /messages for client messages (POST)
|
|
196
|
+
*/
|
|
197
|
+
var SseTransportHandler = class {
|
|
198
|
+
serverFactory;
|
|
199
|
+
app;
|
|
200
|
+
server = null;
|
|
201
|
+
sessionManager;
|
|
202
|
+
config;
|
|
203
|
+
constructor(serverFactory, config) {
|
|
204
|
+
this.serverFactory = typeof serverFactory === "function" ? serverFactory : () => serverFactory;
|
|
205
|
+
this.app = express();
|
|
206
|
+
this.sessionManager = new SseSessionManager();
|
|
207
|
+
this.config = {
|
|
208
|
+
mode: config.mode,
|
|
209
|
+
port: config.port ?? 3e3,
|
|
210
|
+
host: config.host ?? "localhost"
|
|
211
|
+
};
|
|
212
|
+
this.setupMiddleware();
|
|
213
|
+
this.setupRoutes();
|
|
214
|
+
}
|
|
215
|
+
setupMiddleware() {
|
|
216
|
+
this.app.use(express.json());
|
|
217
|
+
}
|
|
218
|
+
setupRoutes() {
|
|
219
|
+
this.app.get("/sse", async (req, res) => {
|
|
220
|
+
await this.handleSseConnection(req, res);
|
|
221
|
+
});
|
|
222
|
+
this.app.post("/messages", async (req, res) => {
|
|
223
|
+
await this.handlePostMessage(req, res);
|
|
224
|
+
});
|
|
225
|
+
this.app.get("/health", (_req, res) => {
|
|
226
|
+
res.json({
|
|
227
|
+
status: "ok",
|
|
228
|
+
transport: "sse"
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
async handleSseConnection(_req, res) {
|
|
233
|
+
try {
|
|
234
|
+
const mcpServer = this.serverFactory();
|
|
235
|
+
const transport = new SSEServerTransport("/messages", res);
|
|
236
|
+
this.sessionManager.setSession(transport.sessionId, transport, mcpServer);
|
|
237
|
+
res.on("close", () => {
|
|
238
|
+
this.sessionManager.deleteSession(transport.sessionId);
|
|
239
|
+
});
|
|
240
|
+
await mcpServer.connect(transport);
|
|
241
|
+
console.error(`SSE session established: ${transport.sessionId}`);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
console.error("Error handling SSE connection:", error);
|
|
244
|
+
if (!res.headersSent) res.status(500).send("Internal Server Error");
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
async handlePostMessage(req, res) {
|
|
248
|
+
const sessionId = req.query.sessionId;
|
|
249
|
+
if (!sessionId) {
|
|
250
|
+
res.status(400).send("Missing sessionId query parameter");
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
const transport = this.sessionManager.getSession(sessionId);
|
|
254
|
+
if (!transport) {
|
|
255
|
+
res.status(404).send("No transport found for sessionId");
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
try {
|
|
259
|
+
await transport.handlePostMessage(req, res, req.body);
|
|
260
|
+
} catch (error) {
|
|
261
|
+
console.error("Error handling post message:", error);
|
|
262
|
+
if (!res.headersSent) res.status(500).send("Internal Server Error");
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async start() {
|
|
266
|
+
return new Promise((resolve, reject) => {
|
|
267
|
+
try {
|
|
268
|
+
this.server = this.app.listen(this.config.port, this.config.host, () => {
|
|
269
|
+
console.error(`Scaffolding MCP server started with SSE transport on http://${this.config.host}:${this.config.port}`);
|
|
270
|
+
console.error(`SSE endpoint: http://${this.config.host}:${this.config.port}/sse`);
|
|
271
|
+
console.error(`Messages endpoint: http://${this.config.host}:${this.config.port}/messages`);
|
|
272
|
+
console.error(`Health check: http://${this.config.host}:${this.config.port}/health`);
|
|
273
|
+
resolve();
|
|
274
|
+
});
|
|
275
|
+
this.server.on("error", (error) => {
|
|
276
|
+
reject(error);
|
|
277
|
+
});
|
|
278
|
+
} catch (error) {
|
|
279
|
+
reject(error);
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
async stop() {
|
|
284
|
+
return new Promise((resolve, reject) => {
|
|
285
|
+
if (this.server) {
|
|
286
|
+
this.sessionManager.clear();
|
|
287
|
+
this.server.close((err) => {
|
|
288
|
+
if (err) reject(err);
|
|
289
|
+
else {
|
|
290
|
+
this.server = null;
|
|
291
|
+
resolve();
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
} else resolve();
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
getPort() {
|
|
298
|
+
return this.config.port;
|
|
299
|
+
}
|
|
300
|
+
getHost() {
|
|
301
|
+
return this.config.host;
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
//#endregion
|
|
306
|
+
//#region src/transports/stdio.ts
|
|
307
|
+
/**
|
|
308
|
+
* Stdio transport handler for MCP server
|
|
309
|
+
* Used for command-line and direct integrations
|
|
310
|
+
*/
|
|
311
|
+
var StdioTransportHandler = class {
|
|
312
|
+
server;
|
|
313
|
+
transport = null;
|
|
314
|
+
constructor(server) {
|
|
315
|
+
this.server = server;
|
|
316
|
+
}
|
|
317
|
+
async start() {
|
|
318
|
+
this.transport = new StdioServerTransport();
|
|
319
|
+
await this.server.connect(this.transport);
|
|
320
|
+
console.error("Scaffolding MCP server started on stdio");
|
|
321
|
+
}
|
|
322
|
+
async stop() {
|
|
323
|
+
if (this.transport) {
|
|
324
|
+
await this.transport.close();
|
|
325
|
+
this.transport = null;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
//#endregion
|
|
331
|
+
export { SseTransportHandler as n, HttpTransportHandler as r, StdioTransportHandler as t };
|