vite-plugin-opencode-assistant 1.1.24 → 1.1.25

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.
@@ -0,0 +1,325 @@
1
+ const CUSTOM_TOOLS = [
2
+ {
3
+ name: "devtools_select_page",
4
+ description: "\u9009\u62E9\u5F53\u524D\u9879\u76EE\u4E2D\u7684\u67D0\u4E2A\u9875\u9762\u4F5C\u4E3A\u540E\u7EED\u5DE5\u5177\u64CD\u4F5C\u7684\u76EE\u6807",
5
+ inputSchema: {
6
+ type: "object",
7
+ properties: {
8
+ pageId: { type: "number", description: "\u9875\u9762 ID\uFF08\u4ECE devtools_list_pages \u83B7\u53D6\uFF09" }
9
+ },
10
+ required: ["pageId"]
11
+ }
12
+ },
13
+ {
14
+ name: "devtools_list_pages",
15
+ description: "\u83B7\u53D6\u5F53\u524D\u9879\u76EE\u6240\u6709\u6253\u5F00\u7684\u9875\u9762\u5217\u8868\uFF0C\u542B active\uFF08\u7528\u6237\u6B63\u5728\u6D4F\u89C8\uFF09\u548C selected\uFF08Chrome DevTools \u5F53\u524D\u64CD\u4F5C\u76EE\u6807\uFF09\u6807\u8BB0",
16
+ inputSchema: {
17
+ type: "object",
18
+ properties: {}
19
+ }
20
+ },
21
+ {
22
+ name: "devtools_snapshot",
23
+ description: "\u83B7\u53D6\u5F53\u524D\u9875\u9762\u53EF\u8BBF\u95EE\u6027\u6811\u5FEB\u7167\uFF0C\u8FD4\u56DE\u5143\u7D20 uid\u3001\u89D2\u8272\u3001\u6587\u672C\u7B49",
24
+ inputSchema: {
25
+ type: "object",
26
+ properties: {
27
+ verbose: { type: "boolean", description: "\u662F\u5426\u83B7\u53D6\u5B8C\u6574\u8282\u70B9\u4FE1\u606F" }
28
+ }
29
+ }
30
+ },
31
+ {
32
+ name: "devtools_screenshot",
33
+ description: "\u622A\u53D6\u5F53\u524D\u9875\u9762\u5C4F\u5E55\u622A\u56FE\uFF0C\u8FD4\u56DE base64 \u56FE\u7247\u6570\u636E",
34
+ inputSchema: {
35
+ type: "object",
36
+ properties: {
37
+ format: { type: "string", description: "\u56FE\u7247\u683C\u5F0F: png \u6216 jpeg" },
38
+ quality: { type: "number", description: "jpeg \u8D28\u91CF 0-100" },
39
+ fullPage: { type: "boolean", description: "\u662F\u5426\u622A\u53D6\u5B8C\u6574\u9875\u9762" }
40
+ }
41
+ }
42
+ },
43
+ {
44
+ name: "devtools_evaluate",
45
+ description: "\u5728\u5F53\u524D\u9875\u9762\u6267\u884C JavaScript \u4EE3\u7801\u5E76\u8FD4\u56DE\u7ED3\u679C\uFF08\u8FD4\u56DE\u503C\u9700\u53EF JSON \u5E8F\u5217\u5316\uFF09",
46
+ inputSchema: {
47
+ type: "object",
48
+ properties: {
49
+ function: { type: "string", description: "JS \u51FD\u6570\u58F0\u660E\uFF0C\u5982 () => document.title" }
50
+ },
51
+ required: ["function"]
52
+ }
53
+ },
54
+ {
55
+ name: "devtools_click",
56
+ description: "\u70B9\u51FB\u9875\u9762\u5143\u7D20",
57
+ inputSchema: {
58
+ type: "object",
59
+ properties: {
60
+ uid: { type: "string", description: "\u5143\u7D20 uid\uFF08\u4ECE devtools_snapshot \u83B7\u53D6\uFF09" },
61
+ dblClick: { type: "boolean", description: "\u662F\u5426\u53CC\u51FB" }
62
+ },
63
+ required: ["uid"]
64
+ }
65
+ },
66
+ {
67
+ name: "devtools_hover",
68
+ description: "\u9F20\u6807\u60AC\u505C\u5728\u9875\u9762\u5143\u7D20\u4E0A",
69
+ inputSchema: {
70
+ type: "object",
71
+ properties: {
72
+ uid: { type: "string", description: "\u5143\u7D20 uid" }
73
+ },
74
+ required: ["uid"]
75
+ }
76
+ },
77
+ {
78
+ name: "devtools_drag",
79
+ description: "\u62D6\u62FD\u9875\u9762\u5143\u7D20",
80
+ inputSchema: {
81
+ type: "object",
82
+ properties: {
83
+ uid: { type: "string", description: "\u6E90\u5143\u7D20 uid" },
84
+ targetUid: { type: "string", description: "\u76EE\u6807\u5143\u7D20 uid" }
85
+ },
86
+ required: ["uid", "targetUid"]
87
+ }
88
+ },
89
+ {
90
+ name: "devtools_type",
91
+ description: "\u5728\u805A\u7126\u5143\u7D20\u4E2D\u8F93\u5165\u6587\u672C",
92
+ inputSchema: {
93
+ type: "object",
94
+ properties: {
95
+ text: { type: "string", description: "\u8981\u8F93\u5165\u7684\u6587\u672C" }
96
+ },
97
+ required: ["text"]
98
+ }
99
+ },
100
+ {
101
+ name: "devtools_press_key",
102
+ description: "\u6309\u4E0B\u952E\u76D8\u6309\u952E",
103
+ inputSchema: {
104
+ type: "object",
105
+ properties: {
106
+ key: { type: "string", description: "\u6309\u952E\u540D\u79F0\uFF0C\u5982 Enter\u3001Control+A" }
107
+ },
108
+ required: ["key"]
109
+ }
110
+ },
111
+ {
112
+ name: "devtools_fill",
113
+ description: "\u586B\u5199\u8F93\u5165\u6846\u503C\u5E76\u89E6\u53D1 input/change \u4E8B\u4EF6",
114
+ inputSchema: {
115
+ type: "object",
116
+ properties: {
117
+ uid: { type: "string", description: "\u8F93\u5165\u6846\u5143\u7D20 uid" },
118
+ value: { type: "string", description: "\u8981\u586B\u5165\u7684\u503C" }
119
+ },
120
+ required: ["uid", "value"]
121
+ }
122
+ },
123
+ {
124
+ name: "devtools_fill_form",
125
+ description: "\u6279\u91CF\u586B\u5199\u8868\u5355\u5B57\u6BB5",
126
+ inputSchema: {
127
+ type: "object",
128
+ properties: {
129
+ fields: {
130
+ type: "array",
131
+ items: {
132
+ type: "object",
133
+ properties: { uid: { type: "string" }, value: { type: "string" } }
134
+ },
135
+ description: "\u5B57\u6BB5\u6570\u7EC4 [{ uid, value }]"
136
+ }
137
+ },
138
+ required: ["fields"]
139
+ }
140
+ },
141
+ {
142
+ name: "devtools_navigate",
143
+ description: "\u5BFC\u822A\u9875\u9762\uFF08url/reload/back/forward\uFF09",
144
+ inputSchema: {
145
+ type: "object",
146
+ properties: {
147
+ type: { type: "string", description: "url | reload | back | forward" },
148
+ url: { type: "string", description: "\u76EE\u6807 URL\uFF08type=url \u65F6\uFF09" }
149
+ },
150
+ required: ["type"]
151
+ }
152
+ },
153
+ {
154
+ name: "devtools_resize_page",
155
+ description: "\u8C03\u6574\u9875\u9762\u89C6\u53E3\u5927\u5C0F",
156
+ inputSchema: {
157
+ type: "object",
158
+ properties: {
159
+ width: { type: "number", description: "\u89C6\u53E3\u5BBD\u5EA6" },
160
+ height: { type: "number", description: "\u89C6\u53E3\u9AD8\u5EA6" }
161
+ },
162
+ required: ["width", "height"]
163
+ }
164
+ },
165
+ {
166
+ name: "devtools_emulate",
167
+ description: "\u6A21\u62DF\u79FB\u52A8\u8BBE\u5907",
168
+ inputSchema: {
169
+ type: "object",
170
+ properties: {
171
+ device: { type: "string", description: "\u8BBE\u5907\u540D\u79F0\uFF0C\u5982 iPhone 15" }
172
+ },
173
+ required: ["device"]
174
+ }
175
+ },
176
+ {
177
+ name: "devtools_network",
178
+ description: "\u83B7\u53D6\u5F53\u524D\u9875\u9762\u7F51\u7EDC\u8BF7\u6C42\u5217\u8868",
179
+ inputSchema: { type: "object", properties: {} }
180
+ },
181
+ {
182
+ name: "devtools_network_request",
183
+ description: "\u83B7\u53D6\u67D0\u6761\u7F51\u7EDC\u8BF7\u6C42\u7684\u8BE6\u7EC6\u4FE1\u606F",
184
+ inputSchema: {
185
+ type: "object",
186
+ properties: {
187
+ reqid: { type: "number", description: "\u8BF7\u6C42 ID\uFF08\u4ECE devtools_network \u83B7\u53D6\uFF09" }
188
+ },
189
+ required: ["reqid"]
190
+ }
191
+ },
192
+ {
193
+ name: "devtools_console",
194
+ description: "\u83B7\u53D6\u5F53\u524D\u9875\u9762\u63A7\u5236\u53F0\u6D88\u606F",
195
+ inputSchema: { type: "object", properties: {} }
196
+ },
197
+ {
198
+ name: "devtools_console_message",
199
+ description: "\u83B7\u53D6\u67D0\u6761\u63A7\u5236\u53F0\u6D88\u606F\u7684\u8BE6\u7EC6\u4FE1\u606F",
200
+ inputSchema: {
201
+ type: "object",
202
+ properties: {
203
+ msgid: { type: "number", description: "\u6D88\u606F ID\uFF08\u4ECE devtools_console \u83B7\u53D6\uFF09" }
204
+ },
205
+ required: ["msgid"]
206
+ }
207
+ },
208
+ {
209
+ name: "devtools_wait_for",
210
+ description: "\u7B49\u5F85\u9875\u9762\u51FA\u73B0\u6307\u5B9A\u6587\u672C",
211
+ inputSchema: {
212
+ type: "object",
213
+ properties: {
214
+ text: { type: "string", description: "\u7B49\u5F85\u51FA\u73B0\u7684\u6587\u672C" }
215
+ },
216
+ required: ["text"]
217
+ }
218
+ },
219
+ {
220
+ name: "devtools_handle_dialog",
221
+ description: "\u5904\u7406 JavaScript \u5BF9\u8BDD\u6846\uFF08accept/dismiss/\u8F93\u5165\u6587\u672C\uFF09",
222
+ inputSchema: {
223
+ type: "object",
224
+ properties: {
225
+ action: { type: "string", description: "accept | dismiss | prompt \u8F93\u5165\u6587\u672C" }
226
+ },
227
+ required: ["action"]
228
+ }
229
+ },
230
+ {
231
+ name: "devtools_upload_file",
232
+ description: "\u4E0A\u4F20\u6587\u4EF6\u5230\u6587\u4EF6\u8F93\u5165\u6846",
233
+ inputSchema: {
234
+ type: "object",
235
+ properties: {
236
+ uid: { type: "string", description: "\u6587\u4EF6\u8F93\u5165\u6846\u5143\u7D20 uid" },
237
+ filePath: { type: "string", description: "\u6587\u4EF6\u7EDD\u5BF9\u8DEF\u5F84" }
238
+ },
239
+ required: ["uid", "filePath"]
240
+ }
241
+ },
242
+ {
243
+ name: "devtools_performance_start",
244
+ description: "\u5F00\u59CB\u8BB0\u5F55\u6027\u80FD trace",
245
+ inputSchema: {
246
+ type: "object",
247
+ properties: {
248
+ reload: { type: "boolean", description: "\u662F\u5426\u81EA\u52A8\u5237\u65B0" },
249
+ autoStop: { type: "boolean", description: "\u662F\u5426\u81EA\u52A8\u505C\u6B62" }
250
+ }
251
+ }
252
+ },
253
+ {
254
+ name: "devtools_performance_stop",
255
+ description: "\u505C\u6B62\u6027\u80FD trace \u8BB0\u5F55\u5E76\u8FD4\u56DE\u7ED3\u679C",
256
+ inputSchema: { type: "object", properties: {} }
257
+ },
258
+ {
259
+ name: "devtools_performance_insight",
260
+ description: "\u83B7\u53D6\u6027\u80FD\u6307\u6807\u8BE6\u7EC6\u5206\u6790",
261
+ inputSchema: {
262
+ type: "object",
263
+ properties: {
264
+ insightSetId: { type: "string", description: "\u6307\u6807\u96C6 ID" },
265
+ insightName: { type: "string", description: "\u6307\u6807\u540D\u79F0" }
266
+ },
267
+ required: ["insightSetId", "insightName"]
268
+ }
269
+ },
270
+ {
271
+ name: "devtools_lighthouse",
272
+ description: "\u8FD0\u884C Lighthouse \u5BA1\u8BA1\uFF08\u53EF\u8BBF\u95EE\u6027/SEO/\u6700\u4F73\u5B9E\u8DF5\uFF0C\u4E0D\u542B\u6027\u80FD\uFF09",
273
+ inputSchema: {
274
+ type: "object",
275
+ properties: {
276
+ mode: { type: "string", description: "navigation \u6216 snapshot" },
277
+ device: { type: "string", description: "desktop \u6216 mobile" }
278
+ }
279
+ }
280
+ },
281
+ {
282
+ name: "devtools_heapsnapshot",
283
+ description: "\u6355\u83B7\u5806\u5185\u5B58\u5FEB\u7167",
284
+ inputSchema: {
285
+ type: "object",
286
+ properties: {
287
+ filePath: { type: "string", description: "\u4FDD\u5B58\u8DEF\u5F84" }
288
+ },
289
+ required: ["filePath"]
290
+ }
291
+ }
292
+ ];
293
+ const TOOL_MAP = {
294
+ devtools_select_page: "select_page",
295
+ devtools_list_pages: "list_pages",
296
+ devtools_snapshot: "take_snapshot",
297
+ devtools_screenshot: "take_screenshot",
298
+ devtools_evaluate: "evaluate_script",
299
+ devtools_click: "click",
300
+ devtools_hover: "hover",
301
+ devtools_drag: "drag",
302
+ devtools_type: "type_text",
303
+ devtools_press_key: "press_key",
304
+ devtools_fill: "fill",
305
+ devtools_fill_form: "fill_form",
306
+ devtools_navigate: "navigate_page",
307
+ devtools_resize_page: "resize_page",
308
+ devtools_emulate: "emulate",
309
+ devtools_network: "list_network_requests",
310
+ devtools_network_request: "get_network_request",
311
+ devtools_console: "list_console_messages",
312
+ devtools_console_message: "get_console_message",
313
+ devtools_wait_for: "wait_for",
314
+ devtools_handle_dialog: "handle_dialog",
315
+ devtools_upload_file: "upload_file",
316
+ devtools_performance_start: "performance_start_trace",
317
+ devtools_performance_stop: "performance_stop_trace",
318
+ devtools_performance_insight: "performance_analyze_insight",
319
+ devtools_lighthouse: "lighthouse_audit",
320
+ devtools_heapsnapshot: "take_heapsnapshot"
321
+ };
322
+ export {
323
+ CUSTOM_TOOLS,
324
+ TOOL_MAP
325
+ };
@@ -0,0 +1,6 @@
1
+ import type { ViteDevServer } from "vite";
2
+ import type { PageContext } from "@vite-plugin-opencode-assistant/shared";
3
+ import { MCP_API_PATH } from "@vite-plugin-opencode-assistant/shared";
4
+ import { McpProxy } from "../core/mcp-proxy";
5
+ export { MCP_API_PATH };
6
+ export declare function setupMcpEndpoint(server: ViteDevServer, mcp: McpProxy, getPageContext: () => PageContext): void;
@@ -0,0 +1,259 @@
1
+ var __async = (__this, __arguments, generator) => {
2
+ return new Promise((resolve, reject) => {
3
+ var fulfilled = (value) => {
4
+ try {
5
+ step(generator.next(value));
6
+ } catch (e) {
7
+ reject(e);
8
+ }
9
+ };
10
+ var rejected = (value) => {
11
+ try {
12
+ step(generator.throw(value));
13
+ } catch (e) {
14
+ reject(e);
15
+ }
16
+ };
17
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
18
+ step((generator = generator.apply(__this, __arguments)).next());
19
+ });
20
+ };
21
+ import { MCP_API_PATH } from "@vite-plugin-opencode-assistant/shared";
22
+ import { createLogger } from "@vite-plugin-opencode-assistant/shared/node";
23
+ import { parseListPages, resolveChromePageId, getProjectOrigin } from "../endpoints/context.mjs";
24
+ import { CUSTOM_TOOLS, TOOL_MAP } from "./mcp-tools.mjs";
25
+ const log = createLogger("McpEndpoint");
26
+ function setupMcpEndpoint(server, mcp, getPageContext) {
27
+ server.middlewares.use((req, res, next) => __async(null, null, function* () {
28
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
29
+ if (!((_a = req.url) == null ? void 0 : _a.startsWith(MCP_API_PATH))) return next();
30
+ const url = new URL(req.url, `http://localhost`);
31
+ const token = (_c = url.searchParams.get("token")) != null ? _c : (_b = req.headers["authorization"]) == null ? void 0 : _b.replace(/^Bearer /i, "");
32
+ if (token !== mcp.accessToken) {
33
+ res.writeHead(401, { "Content-Type": "application/json" });
34
+ res.end(JSON.stringify({ error: "Unauthorized" }));
35
+ return;
36
+ }
37
+ res.setHeader("Access-Control-Allow-Origin", "*");
38
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
39
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Mcp-Session-Id, Authorization");
40
+ res.setHeader("Access-Control-Expose-Headers", "Mcp-Session-Id");
41
+ if (req.method === "OPTIONS") {
42
+ res.writeHead(204);
43
+ res.end();
44
+ return;
45
+ }
46
+ if (req.method === "GET") {
47
+ res.writeHead(200, {
48
+ "Content-Type": "text/event-stream",
49
+ "Cache-Control": "no-cache",
50
+ Connection: "keep-alive",
51
+ "Mcp-Session-Id": mcp.sessionId
52
+ });
53
+ res.write(":ok\n\n");
54
+ const keepAlive = setInterval(() => res.write(":ping\n\n"), 15e3);
55
+ req.on("close", () => clearInterval(keepAlive));
56
+ return;
57
+ }
58
+ if (req.method === "DELETE") {
59
+ res.writeHead(200);
60
+ res.end();
61
+ return;
62
+ }
63
+ if (req.method === "POST") {
64
+ try {
65
+ const body = yield readBody(req);
66
+ if (!body) {
67
+ res.writeHead(400);
68
+ res.end("Empty body");
69
+ return;
70
+ }
71
+ const { method, id } = tryParseRequest(body);
72
+ log.debug("MCP request", { method, body: body.substring(0, 150) });
73
+ if (method === "tools/list") {
74
+ res.writeHead(200, {
75
+ "Content-Type": "application/json",
76
+ "Mcp-Session-Id": mcp.sessionId
77
+ });
78
+ res.end(JSON.stringify({ jsonrpc: "2.0", id, result: { tools: CUSTOM_TOOLS } }));
79
+ return;
80
+ }
81
+ if (method === "tools/call") {
82
+ const params = tryParseParams(body);
83
+ const toolName = params == null ? void 0 : params.name;
84
+ const mapped = toolName != null ? TOOL_MAP[toolName] : void 0;
85
+ if (!mapped) {
86
+ res.writeHead(200, {
87
+ "Content-Type": "application/json",
88
+ "Mcp-Session-Id": mcp.sessionId
89
+ });
90
+ res.end(
91
+ JSON.stringify({
92
+ jsonrpc: "2.0",
93
+ id,
94
+ error: { code: -32601, message: `Tool not found: ${toolName}` }
95
+ })
96
+ );
97
+ return;
98
+ }
99
+ if (toolName === "devtools_list_pages") {
100
+ const listResult = yield mcp.callChromeDevTool("list_pages", {});
101
+ const text = (_f = (_e = (_d = listResult == null ? void 0 : listResult.result) == null ? void 0 : _d.content) == null ? void 0 : _e[0]) == null ? void 0 : _f.text;
102
+ const allPages = text ? parseListPages(text) : [];
103
+ const pc = getPageContext();
104
+ const projectOrigin = getProjectOrigin(pc.url);
105
+ if (!projectOrigin) {
106
+ res.writeHead(200, {
107
+ "Content-Type": "application/json",
108
+ "Mcp-Session-Id": mcp.sessionId
109
+ });
110
+ res.end(
111
+ JSON.stringify({
112
+ jsonrpc: "2.0",
113
+ id,
114
+ result: {
115
+ content: [
116
+ { type: "text", text: "\u6682\u65E0\u9879\u76EE\u9875\u9762\uFF0C\u8BF7\u5148\u5728\u6D4F\u89C8\u5668\u4E2D\u6253\u5F00\u672C\u5730\u5F00\u53D1\u9875\u9762" }
117
+ ]
118
+ }
119
+ })
120
+ );
121
+ return;
122
+ }
123
+ const filtered = allPages.filter((p) => p.url.startsWith(projectOrigin));
124
+ const chromeSelectedPageId = (_g = allPages.find((p) => p.selected)) == null ? void 0 : _g.pageId;
125
+ const resolved = yield resolveChromePageId(
126
+ mcp,
127
+ pc.url,
128
+ pc.title,
129
+ pc.sessionId,
130
+ filtered,
131
+ chromeSelectedPageId
132
+ );
133
+ const activePageId = resolved.ok ? resolved.pageId : null;
134
+ res.writeHead(200, {
135
+ "Content-Type": "application/json",
136
+ "Mcp-Session-Id": mcp.sessionId
137
+ });
138
+ res.end(
139
+ JSON.stringify({
140
+ jsonrpc: "2.0",
141
+ id,
142
+ result: {
143
+ content: [
144
+ {
145
+ type: "text",
146
+ text: JSON.stringify(
147
+ filtered.map((p) => ({
148
+ pageId: p.pageId,
149
+ url: p.url,
150
+ title: p.title,
151
+ active: activePageId != null ? p.pageId === activePageId : false,
152
+ selected: p.selected
153
+ })),
154
+ null,
155
+ 2
156
+ )
157
+ }
158
+ ]
159
+ }
160
+ })
161
+ );
162
+ return;
163
+ }
164
+ if (toolName !== "devtools_select_page") {
165
+ const checkResult = yield mcp.callChromeDevTool("list_pages", {});
166
+ const checkText = (_j = (_i = (_h = checkResult == null ? void 0 : checkResult.result) == null ? void 0 : _h.content) == null ? void 0 : _i[0]) == null ? void 0 : _j.text;
167
+ const checkPages = checkText ? parseListPages(checkText) : [];
168
+ const pc = getPageContext();
169
+ const origin = getProjectOrigin(pc.url);
170
+ const hasProjectSelected = origin ? checkPages.some((p) => p.selected && p.url.startsWith(origin)) : true;
171
+ if (!hasProjectSelected) {
172
+ res.writeHead(200, {
173
+ "Content-Type": "application/json",
174
+ "Mcp-Session-Id": mcp.sessionId
175
+ });
176
+ res.end(
177
+ JSON.stringify({
178
+ jsonrpc: "2.0",
179
+ id,
180
+ error: {
181
+ code: -32e3,
182
+ message: "Chrome DevTools \u5F53\u524D\u672A\u9009\u4E2D\u9879\u76EE\u9875\u9762\uFF0C\u8BF7\u5148\u8C03\u7528 devtools_list_pages \u67E5\u770B\u53EF\u7528\u9875\u9762\uFF0C\u518D\u8C03\u7528 devtools_select_page \u9009\u62E9\u76EE\u6807\u9875\u9762"
183
+ }
184
+ })
185
+ );
186
+ return;
187
+ }
188
+ }
189
+ const forwardBody = JSON.stringify({
190
+ jsonrpc: "2.0",
191
+ id,
192
+ method: "tools/call",
193
+ params: {
194
+ name: mapped,
195
+ arguments: (params == null ? void 0 : params.arguments) || {}
196
+ }
197
+ });
198
+ const responseText2 = yield mcp.forward(forwardBody);
199
+ log.debug("MCP response", { method: toolName, response: responseText2.substring(0, 100) });
200
+ res.writeHead(200, {
201
+ "Content-Type": "application/json",
202
+ "Mcp-Session-Id": mcp.sessionId
203
+ });
204
+ res.end(responseText2);
205
+ return;
206
+ }
207
+ const responseText = yield mcp.forward(body);
208
+ res.writeHead(200, { "Content-Type": "application/json", "Mcp-Session-Id": mcp.sessionId });
209
+ res.end(responseText);
210
+ } catch (e) {
211
+ log.debug("MCP POST error", { error: e.message });
212
+ res.writeHead(500, { "Content-Type": "application/json" });
213
+ res.end(
214
+ JSON.stringify({
215
+ jsonrpc: "2.0",
216
+ error: { code: -32603, message: e.message }
217
+ })
218
+ );
219
+ }
220
+ return;
221
+ }
222
+ next();
223
+ }));
224
+ }
225
+ function readBody(req, maxSize = 1024 * 1024) {
226
+ return new Promise((resolve, reject) => {
227
+ let body = "";
228
+ req.on("data", (chunk) => {
229
+ body += chunk.toString();
230
+ if (body.length > maxSize) {
231
+ req.destroy();
232
+ reject(new Error("Request body too large"));
233
+ }
234
+ });
235
+ req.on("end", () => resolve(body));
236
+ req.on("error", reject);
237
+ });
238
+ }
239
+ function tryParseRequest(body) {
240
+ var _a;
241
+ try {
242
+ const data = JSON.parse(body);
243
+ return { method: data.method || "unknown", id: (_a = data.id) != null ? _a : null };
244
+ } catch (e) {
245
+ return { method: "unknown", id: null };
246
+ }
247
+ }
248
+ function tryParseParams(body) {
249
+ var _a;
250
+ try {
251
+ return (_a = JSON.parse(body).params) != null ? _a : null;
252
+ } catch (e) {
253
+ return null;
254
+ }
255
+ }
256
+ export {
257
+ MCP_API_PATH,
258
+ setupMcpEndpoint
259
+ };