vite-plugin-swagger-mcp 0.0.12 → 0.0.14

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/cjs/index.js CHANGED
@@ -210,7 +210,6 @@ function vitePluginSwaggerMcp({
210
210
  ]
211
211
  })
212
212
  );
213
- await mcpServer.connect(transport);
214
213
  console.log(
215
214
  "MCP server connected:",
216
215
  `http://localhost:${(_b = (_a = server.config) == null ? void 0 : _a.server) == null ? void 0 : _b.port}/_mcp/sse/swagger`
@@ -218,26 +217,42 @@ function vitePluginSwaggerMcp({
218
217
  server.middlewares.use("/_mcp/sse/swagger", async (req, res) => {
219
218
  var _a2;
220
219
  if (req.method === "POST") {
220
+ const sessionId = req.headers["mcp-session-id"];
221
221
  let body = "";
222
222
  for await (const chunk of req)
223
223
  body += chunk;
224
224
  const json = JSON.parse(body);
225
+ console.log("post request received");
226
+ console.log("body: ", json);
227
+ let transport2;
225
228
  try {
226
- const result = await transport.handleRequest(req, res, json);
227
- res.writeHead(200, {
228
- "Content-Type": "application/json"
229
- });
230
- res.end(JSON.stringify(result));
229
+ if (sessionId && transports[sessionId]) {
230
+ transport2 = transports[sessionId];
231
+ await transport2.handleRequest(req, res, json);
232
+ return;
233
+ }
234
+ if (!sessionId) {
235
+ const transport3 = new import_streamableHttp.StreamableHTTPServerTransport({
236
+ sessionIdGenerator: () => (0, import_node_crypto.randomUUID)()
237
+ // for stateless mode:
238
+ // sessionIdGenerator: () => undefined
239
+ });
240
+ await mcpServer.connect(transport3);
241
+ await transport3.handleRequest(req, res, json);
242
+ const sessionId2 = transport3.sessionId;
243
+ if (sessionId2) {
244
+ transports[sessionId2] = transport3;
245
+ }
246
+ return;
247
+ }
248
+ res.statusCode = 400;
249
+ res.end("Bad Request: invalid session ID or method.");
250
+ return;
251
+ } catch (error) {
252
+ console.error("Error handling MCP request:", error);
253
+ res.statusCode = 500;
254
+ res.end("Internal server error.");
231
255
  return;
232
- } catch (err) {
233
- res.writeHead(500);
234
- res.end(
235
- JSON.stringify({
236
- jsonrpc: "2.0",
237
- id: (json == null ? void 0 : json.id) ?? null,
238
- error: { message: err == null ? void 0 : err.message }
239
- })
240
- );
241
256
  }
242
257
  }
243
258
  if (req.method === "GET") {
@@ -255,8 +270,6 @@ function vitePluginSwaggerMcp({
255
270
  };
256
271
  return;
257
272
  }
258
- res.statusCode = 405;
259
- res.end();
260
273
  });
261
274
  } catch (error) {
262
275
  console.log("MCP server error", error);
package/dist/esm/index.js CHANGED
@@ -242,264 +242,282 @@ export default function vitePluginSwaggerMcp(_ref) {
242
242
  return _regeneratorRuntime().wrap(function _callee9$(_context9) {
243
243
  while (1) switch (_context9.prev = _context9.next) {
244
244
  case 0:
245
- _context9.prev = 0;
246
- transport = new StreamableHTTPServerTransport({
247
- sessionIdGenerator: function sessionIdGenerator() {
248
- return randomUUID();
249
- },
250
- onsessioninitialized: function onsessioninitialized(sessionId) {
251
- // Store the transport by session ID
252
- transports[sessionId] = transport;
253
- }
254
- }); // Clean up transport when closed
255
- transport.onclose = function () {
256
- if (transport.sessionId) {
257
- delete transports[transport.sessionId];
258
- }
259
- };
260
- swaggerServer = new SwaggerMcpServer(swaggerUrl, token); // 实例化 MCP Server
261
- mcpServer = new McpServer({
262
- name: "swagger-mcp-server",
263
- version: "0.1.0"
264
- }); // 注册工具
265
- /***
266
- * 获取模块列表
267
- */
268
- mcpServer.tool("getModules", "获取模块列表", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
269
- var res;
270
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
271
- while (1) switch (_context5.prev = _context5.next) {
272
- case 0:
273
- _context5.next = 2;
274
- return swaggerServer.getModules();
275
- case 2:
276
- res = _context5.sent;
277
- return _context5.abrupt("return", {
278
- content: [{
279
- type: "text",
280
- text: JSON.stringify(res)
281
- }]
282
- });
283
- case 4:
284
- case "end":
285
- return _context5.stop();
245
+ try {
246
+ transport = new StreamableHTTPServerTransport({
247
+ sessionIdGenerator: function sessionIdGenerator() {
248
+ return randomUUID();
249
+ },
250
+ onsessioninitialized: function onsessioninitialized(sessionId) {
251
+ // Store the transport by session ID
252
+ transports[sessionId] = transport;
286
253
  }
287
- }, _callee5);
288
- })));
289
-
290
- /***
291
- * 获取特定模块下的所有接口及返回值类型
292
- */
293
- mcpServer.tool("getModuleApis", "获取特定模块下的所有接口及返回值类型", {
294
- module: z.string().describe("模块名称")
295
- }, /*#__PURE__*/function () {
296
- var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(_ref3) {
297
- var module, res;
298
- return _regeneratorRuntime().wrap(function _callee6$(_context6) {
299
- while (1) switch (_context6.prev = _context6.next) {
254
+ }); // Clean up transport when closed
255
+ transport.onclose = function () {
256
+ if (transport.sessionId) {
257
+ delete transports[transport.sessionId];
258
+ }
259
+ };
260
+ swaggerServer = new SwaggerMcpServer(swaggerUrl, token); // 实例化 MCP Server
261
+ mcpServer = new McpServer({
262
+ name: "swagger-mcp-server",
263
+ version: "0.1.0"
264
+ }); // 注册工具
265
+ /***
266
+ * 获取模块列表
267
+ */
268
+ mcpServer.tool("getModules", "获取模块列表", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
269
+ var res;
270
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
271
+ while (1) switch (_context5.prev = _context5.next) {
300
272
  case 0:
301
- module = _ref3.module;
302
- if (module) {
303
- _context6.next = 3;
304
- break;
305
- }
306
- return _context6.abrupt("return", {
307
- content: [{
308
- type: "text",
309
- text: JSON.stringify({
310
- error: "模块名称不能为空"
311
- })
312
- }]
313
- });
314
- case 3:
315
- _context6.next = 5;
316
- return swaggerServer.getModuleApis(module);
317
- case 5:
318
- res = _context6.sent;
319
- return _context6.abrupt("return", {
273
+ _context5.next = 2;
274
+ return swaggerServer.getModules();
275
+ case 2:
276
+ res = _context5.sent;
277
+ return _context5.abrupt("return", {
320
278
  content: [{
321
279
  type: "text",
322
280
  text: JSON.stringify(res)
323
281
  }]
324
282
  });
325
- case 7:
283
+ case 4:
326
284
  case "end":
327
- return _context6.stop();
285
+ return _context5.stop();
328
286
  }
329
- }, _callee6);
330
- }));
331
- return function (_x4) {
332
- return _ref4.apply(this, arguments);
333
- };
334
- }());
287
+ }, _callee5);
288
+ })));
335
289
 
336
- /***
337
- * 获取特定接口的参数及返回值类型
338
- */
339
- mcpServer.tool("getApiTypes", "获取特定接口的参数及返回值类型", {
340
- path: z.string(),
341
- method: z.string()
342
- }, /*#__PURE__*/function () {
343
- var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(args) {
344
- return _regeneratorRuntime().wrap(function _callee7$(_context7) {
345
- while (1) switch (_context7.prev = _context7.next) {
346
- case 0:
347
- _context7.t0 = JSON;
348
- _context7.next = 3;
349
- return swaggerServer.getApiTypes(args.path, args.method);
350
- case 3:
351
- _context7.t1 = _context7.sent;
352
- _context7.t2 = _context7.t0.stringify.call(_context7.t0, _context7.t1);
353
- _context7.t3 = {
354
- type: "text",
355
- text: _context7.t2
356
- };
357
- _context7.t4 = [_context7.t3];
358
- return _context7.abrupt("return", {
359
- content: _context7.t4
360
- });
361
- case 8:
362
- case "end":
363
- return _context7.stop();
364
- }
365
- }, _callee7);
366
- }));
367
- return function (_x5) {
368
- return _ref5.apply(this, arguments);
369
- };
370
- }());
290
+ /***
291
+ * 获取特定模块下的所有接口及返回值类型
292
+ */
293
+ mcpServer.tool("getModuleApis", "获取特定模块下的所有接口及返回值类型", {
294
+ module: z.string().describe("模块名称")
295
+ }, /*#__PURE__*/function () {
296
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(_ref3) {
297
+ var module, res;
298
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
299
+ while (1) switch (_context6.prev = _context6.next) {
300
+ case 0:
301
+ module = _ref3.module;
302
+ if (module) {
303
+ _context6.next = 3;
304
+ break;
305
+ }
306
+ return _context6.abrupt("return", {
307
+ content: [{
308
+ type: "text",
309
+ text: JSON.stringify({
310
+ error: "模块名称不能为空"
311
+ })
312
+ }]
313
+ });
314
+ case 3:
315
+ _context6.next = 5;
316
+ return swaggerServer.getModuleApis(module);
317
+ case 5:
318
+ res = _context6.sent;
319
+ return _context6.abrupt("return", {
320
+ content: [{
321
+ type: "text",
322
+ text: JSON.stringify(res)
323
+ }]
324
+ });
325
+ case 7:
326
+ case "end":
327
+ return _context6.stop();
328
+ }
329
+ }, _callee6);
330
+ }));
331
+ return function (_x4) {
332
+ return _ref4.apply(this, arguments);
333
+ };
334
+ }());
371
335
 
372
- // Connect to the MCP mcpServer
373
- _context9.next = 10;
374
- return mcpServer.connect(transport);
375
- case 10:
376
- console.log("MCP server connected:", "http://localhost:".concat((_server$config = server.config) === null || _server$config === void 0 || (_server$config = _server$config.server) === null || _server$config === void 0 ? void 0 : _server$config.port, "/_mcp/sse/swagger"));
377
- server.middlewares.use('/_mcp/sse/swagger', /*#__PURE__*/function () {
378
- var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(req, res) {
379
- var body, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, chunk, json, result, _json$id, _req$headers$accept;
380
- return _regeneratorRuntime().wrap(function _callee8$(_context8) {
381
- while (1) switch (_context8.prev = _context8.next) {
382
- case 0:
383
- if (!(req.method === 'POST')) {
384
- _context8.next = 44;
385
- break;
386
- }
387
- body = '';
388
- _iteratorAbruptCompletion = false;
389
- _didIteratorError = false;
390
- _context8.prev = 4;
391
- _iterator = _asyncIterator(req);
392
- case 6:
393
- _context8.next = 8;
394
- return _iterator.next();
395
- case 8:
396
- if (!(_iteratorAbruptCompletion = !(_step = _context8.sent).done)) {
397
- _context8.next = 14;
398
- break;
399
- }
400
- chunk = _step.value;
401
- body += chunk;
402
- case 11:
403
- _iteratorAbruptCompletion = false;
404
- _context8.next = 6;
405
- break;
406
- case 14:
407
- _context8.next = 20;
408
- break;
409
- case 16:
410
- _context8.prev = 16;
411
- _context8.t0 = _context8["catch"](4);
412
- _didIteratorError = true;
413
- _iteratorError = _context8.t0;
414
- case 20:
415
- _context8.prev = 20;
416
- _context8.prev = 21;
417
- if (!(_iteratorAbruptCompletion && _iterator.return != null)) {
418
- _context8.next = 25;
419
- break;
420
- }
421
- _context8.next = 25;
422
- return _iterator.return();
423
- case 25:
424
- _context8.prev = 25;
425
- if (!_didIteratorError) {
426
- _context8.next = 28;
427
- break;
428
- }
429
- throw _iteratorError;
430
- case 28:
431
- return _context8.finish(25);
432
- case 29:
433
- return _context8.finish(20);
434
- case 30:
435
- json = JSON.parse(body);
436
- _context8.prev = 31;
437
- _context8.next = 34;
438
- return transport.handleRequest(req, res, json);
439
- case 34:
440
- result = _context8.sent;
441
- // 规范:POST 一定返回 response
442
- res.writeHead(200, {
443
- 'Content-Type': 'application/json'
444
- });
445
- res.end(JSON.stringify(result));
446
- return _context8.abrupt("return");
447
- case 40:
448
- _context8.prev = 40;
449
- _context8.t1 = _context8["catch"](31);
450
- res.writeHead(500);
451
- res.end(JSON.stringify({
452
- jsonrpc: '2.0',
453
- id: (_json$id = json === null || json === void 0 ? void 0 : json.id) !== null && _json$id !== void 0 ? _json$id : null,
454
- error: {
455
- message: _context8.t1 === null || _context8.t1 === void 0 ? void 0 : _context8.t1.message
336
+ /***
337
+ * 获取特定接口的参数及返回值类型
338
+ */
339
+ mcpServer.tool("getApiTypes", "获取特定接口的参数及返回值类型", {
340
+ path: z.string(),
341
+ method: z.string()
342
+ }, /*#__PURE__*/function () {
343
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(args) {
344
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
345
+ while (1) switch (_context7.prev = _context7.next) {
346
+ case 0:
347
+ _context7.t0 = JSON;
348
+ _context7.next = 3;
349
+ return swaggerServer.getApiTypes(args.path, args.method);
350
+ case 3:
351
+ _context7.t1 = _context7.sent;
352
+ _context7.t2 = _context7.t0.stringify.call(_context7.t0, _context7.t1);
353
+ _context7.t3 = {
354
+ type: "text",
355
+ text: _context7.t2
356
+ };
357
+ _context7.t4 = [_context7.t3];
358
+ return _context7.abrupt("return", {
359
+ content: _context7.t4
360
+ });
361
+ case 8:
362
+ case "end":
363
+ return _context7.stop();
364
+ }
365
+ }, _callee7);
366
+ }));
367
+ return function (_x5) {
368
+ return _ref5.apply(this, arguments);
369
+ };
370
+ }());
371
+
372
+ // Connect to the MCP mcpServer
373
+ console.log("MCP server connected:", "http://localhost:".concat((_server$config = server.config) === null || _server$config === void 0 || (_server$config = _server$config.server) === null || _server$config === void 0 ? void 0 : _server$config.port, "/_mcp/sse/swagger"));
374
+ server.middlewares.use('/_mcp/sse/swagger', /*#__PURE__*/function () {
375
+ var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(req, res) {
376
+ var _sessionId, body, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, chunk, json, _transport, _transport2, _sessionId2, _req$headers$accept;
377
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
378
+ while (1) switch (_context8.prev = _context8.next) {
379
+ case 0:
380
+ if (!(req.method === 'POST')) {
381
+ _context8.next = 60;
382
+ break;
456
383
  }
457
- }));
458
- case 44:
459
- if (!(req.method === 'GET')) {
460
- _context8.next = 51;
384
+ _sessionId = req.headers["mcp-session-id"];
385
+ body = '';
386
+ _iteratorAbruptCompletion = false;
387
+ _didIteratorError = false;
388
+ _context8.prev = 5;
389
+ _iterator = _asyncIterator(req);
390
+ case 7:
391
+ _context8.next = 9;
392
+ return _iterator.next();
393
+ case 9:
394
+ if (!(_iteratorAbruptCompletion = !(_step = _context8.sent).done)) {
395
+ _context8.next = 15;
396
+ break;
397
+ }
398
+ chunk = _step.value;
399
+ body += chunk;
400
+ case 12:
401
+ _iteratorAbruptCompletion = false;
402
+ _context8.next = 7;
461
403
  break;
462
- }
463
- if ((_req$headers$accept = req.headers.accept) !== null && _req$headers$accept !== void 0 && _req$headers$accept.includes('text/event-stream')) {
464
- _context8.next = 48;
404
+ case 15:
405
+ _context8.next = 21;
465
406
  break;
466
- }
467
- res.writeHead(405);
468
- return _context8.abrupt("return", res.end());
469
- case 48:
470
- res.writeHead(200, {
471
- 'Content-Type': 'text/event-stream',
472
- 'Cache-Control': 'no-cache',
473
- Connection: 'keep-alive'
474
- });
475
- transport.onmessage = function (message) {
476
- res.write(message);
477
- };
478
- return _context8.abrupt("return");
479
- case 51:
480
- res.statusCode = 405;
481
- res.end();
482
- case 53:
483
- case "end":
484
- return _context8.stop();
485
- }
486
- }, _callee8, null, [[4, 16, 20, 30], [21,, 25, 29], [31, 40]]);
487
- }));
488
- return function (_x6, _x7) {
489
- return _ref6.apply(this, arguments);
490
- };
491
- }());
492
- _context9.next = 17;
493
- break;
494
- case 14:
495
- _context9.prev = 14;
496
- _context9.t0 = _context9["catch"](0);
497
- console.log("MCP server error", _context9.t0);
498
- case 17:
407
+ case 17:
408
+ _context8.prev = 17;
409
+ _context8.t0 = _context8["catch"](5);
410
+ _didIteratorError = true;
411
+ _iteratorError = _context8.t0;
412
+ case 21:
413
+ _context8.prev = 21;
414
+ _context8.prev = 22;
415
+ if (!(_iteratorAbruptCompletion && _iterator.return != null)) {
416
+ _context8.next = 26;
417
+ break;
418
+ }
419
+ _context8.next = 26;
420
+ return _iterator.return();
421
+ case 26:
422
+ _context8.prev = 26;
423
+ if (!_didIteratorError) {
424
+ _context8.next = 29;
425
+ break;
426
+ }
427
+ throw _iteratorError;
428
+ case 29:
429
+ return _context8.finish(26);
430
+ case 30:
431
+ return _context8.finish(21);
432
+ case 31:
433
+ json = JSON.parse(body);
434
+ console.log("post request received");
435
+ console.log("body: ", json);
436
+ _context8.prev = 34;
437
+ if (!(_sessionId && transports[_sessionId])) {
438
+ _context8.next = 40;
439
+ break;
440
+ }
441
+ _transport = transports[_sessionId];
442
+ _context8.next = 39;
443
+ return _transport.handleRequest(req, res, json);
444
+ case 39:
445
+ return _context8.abrupt("return");
446
+ case 40:
447
+ if (_sessionId) {
448
+ _context8.next = 49;
449
+ break;
450
+ }
451
+ _transport2 = new StreamableHTTPServerTransport({
452
+ sessionIdGenerator: function sessionIdGenerator() {
453
+ return randomUUID();
454
+ }
455
+ // for stateless mode:
456
+ // sessionIdGenerator: () => undefined
457
+ });
458
+ _context8.next = 44;
459
+ return mcpServer.connect(_transport2);
460
+ case 44:
461
+ _context8.next = 46;
462
+ return _transport2.handleRequest(req, res, json);
463
+ case 46:
464
+ // session ID will only be available (if in not Stateless-Mode)
465
+ // after handling the first request
466
+ _sessionId2 = _transport2.sessionId;
467
+ if (_sessionId2) {
468
+ transports[_sessionId2] = _transport2;
469
+ }
470
+ return _context8.abrupt("return");
471
+ case 49:
472
+ res.statusCode = 400;
473
+ res.end("Bad Request: invalid session ID or method.");
474
+ return _context8.abrupt("return");
475
+ case 54:
476
+ _context8.prev = 54;
477
+ _context8.t1 = _context8["catch"](34);
478
+ console.error('Error handling MCP request:', _context8.t1);
479
+ res.statusCode = 500;
480
+ res.end("Internal server error.");
481
+ return _context8.abrupt("return");
482
+ case 60:
483
+ if (!(req.method === 'GET')) {
484
+ _context8.next = 67;
485
+ break;
486
+ }
487
+ if ((_req$headers$accept = req.headers.accept) !== null && _req$headers$accept !== void 0 && _req$headers$accept.includes('text/event-stream')) {
488
+ _context8.next = 64;
489
+ break;
490
+ }
491
+ res.writeHead(405);
492
+ return _context8.abrupt("return", res.end());
493
+ case 64:
494
+ res.writeHead(200, {
495
+ 'Content-Type': 'text/event-stream',
496
+ 'Cache-Control': 'no-cache',
497
+ Connection: 'keep-alive'
498
+ });
499
+ transport.onmessage = function (message) {
500
+ res.write(message);
501
+ };
502
+ return _context8.abrupt("return");
503
+ case 67:
504
+ case "end":
505
+ return _context8.stop();
506
+ }
507
+ }, _callee8, null, [[5, 17, 21, 31], [22,, 26, 30], [34, 54]]);
508
+ }));
509
+ return function (_x6, _x7) {
510
+ return _ref6.apply(this, arguments);
511
+ };
512
+ }());
513
+ } catch (error) {
514
+ console.log("MCP server error", error);
515
+ }
516
+ case 1:
499
517
  case "end":
500
518
  return _context9.stop();
501
519
  }
502
- }, _callee9, null, [[0, 14]]);
520
+ }, _callee9);
503
521
  }))();
504
522
  }
505
523
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-swagger-mcp",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "description": "vite plugin for swagger mcp",
5
5
  "homepage": "https://github.com/mmdctjj/vite-plugin-swagger-mcp",
6
6
  "repository": {