vite-plugin-swagger-mcp 0.0.17 → 0.0.19

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.
@@ -42,7 +42,7 @@ export declare class SwaggerMcpServer {
42
42
  method: string;
43
43
  }>;
44
44
  }
45
- export default function vitePluginSwaggerMcp(options: {
45
+ export default function vitePluginSwaggerMcp({ swaggerUrl, token, }: {
46
46
  swaggerUrl: string;
47
47
  token?: string;
48
48
  }): Plugin;
package/dist/cjs/index.js CHANGED
@@ -1,8 +1,6 @@
1
- var __create = Object.create;
2
1
  var __defProp = Object.defineProperty;
3
2
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
4
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
5
  var __export = (target, all) => {
8
6
  for (var name in all)
@@ -16,14 +14,6 @@ var __copyProps = (to, from, except, desc) => {
16
14
  }
17
15
  return to;
18
16
  };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
18
 
29
19
  // src/index.ts
@@ -34,10 +24,16 @@ __export(src_exports, {
34
24
  });
35
25
  module.exports = __toCommonJS(src_exports);
36
26
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
37
- var import_node_crypto = require("node:crypto");
38
- var z = __toESM(require("zod"));
39
- var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp");
27
+ var import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
40
28
  var import_types = require("@modelcontextprotocol/sdk/types");
29
+ var import_node_crypto = require("node:crypto");
30
+ var import_v4 = require("zod/v4");
31
+ async function readJsonBody(req) {
32
+ let body = "";
33
+ for await (const chunk of req)
34
+ body += chunk;
35
+ return JSON.parse(body || "{}");
36
+ }
41
37
  var SwaggerMcpServer = class {
42
38
  constructor(swaggerUrl, token) {
43
39
  this.swaggerUrl = swaggerUrl;
@@ -145,118 +141,100 @@ var SwaggerMcpServer = class {
145
141
  };
146
142
  }
147
143
  };
148
- function vitePluginSwaggerMcp(options) {
149
- const transports = {};
144
+ var transports = {};
145
+ function vitePluginSwaggerMcp({
146
+ swaggerUrl,
147
+ token
148
+ }) {
150
149
  return {
151
150
  name: "vite-plugin-swagger-mcp",
152
- configureServer(vite) {
153
- var _a;
154
- const swaggerServer = new SwaggerMcpServer(
155
- options.swaggerUrl,
156
- options.token
157
- );
158
- const createMcpServer = () => {
159
- const server = new import_mcp.McpServer({
151
+ enforce: "pre",
152
+ async configureServer(server) {
153
+ var _a, _b;
154
+ const swaggerServer = new SwaggerMcpServer(swaggerUrl, token);
155
+ const createNewServer = () => {
156
+ const mcpServer = new import_mcp.McpServer({
160
157
  name: "swagger-mcp-server",
161
158
  version: "0.1.0"
162
159
  });
163
- server.tool("getModules", "获取模块列表", async () => {
160
+ mcpServer.tool("getModules", "获取模块列表", async () => {
164
161
  const res = await swaggerServer.getModules();
165
- return {
166
- content: [
167
- {
168
- type: "text",
169
- text: JSON.stringify(res)
170
- }
171
- ]
172
- };
162
+ return { content: [{ type: "text", text: JSON.stringify(res) }] };
173
163
  });
174
- server.tool(
164
+ mcpServer.tool(
165
+ "getModuleApis",
166
+ "获取特定模块下的所有接口",
167
+ { module: import_v4.z.string().describe("模块名称") },
168
+ async ({ module: module2 }) => {
169
+ const res = await swaggerServer.getModuleApis(module2);
170
+ return { content: [{ type: "text", text: JSON.stringify(res) }] };
171
+ }
172
+ );
173
+ mcpServer.tool(
175
174
  "getApiTypes",
176
175
  "获取特定接口的参数及返回值类型",
177
- { path: z.string(), method: z.string() },
176
+ { path: import_v4.z.string(), method: import_v4.z.string() },
178
177
  async (args) => ({
179
- content: [
180
- {
181
- type: "text",
182
- text: JSON.stringify(
183
- await swaggerServer.getApiTypes(args.path, args.method)
184
- )
185
- }
186
- ]
178
+ content: [{ type: "text", text: JSON.stringify(await swaggerServer.getApiTypes(args.path, args.method)) }]
187
179
  })
188
180
  );
189
- server.registerTool(
190
- "getApiTypes",
191
- {
192
- description: "获取接口类型定义",
193
- inputSchema: {
194
- path: z.string(),
195
- method: z.string()
196
- }
197
- },
198
- async ({ path, method }) => ({
199
- content: [
200
- {
201
- type: "text",
202
- text: JSON.stringify(await swaggerServer.getApiTypes(path, method))
203
- }
204
- ]
205
- })
206
- );
207
- return server;
181
+ return mcpServer;
208
182
  };
209
- vite.middlewares.use("/_mcp/swagger", async (req, res) => {
210
- const sessionId = req.headers["mcp-session-id"];
211
- if (req.method === "POST") {
212
- let body = "";
213
- for await (const chunk of req)
214
- body += chunk;
215
- const json = JSON.parse(body);
216
- try {
183
+ const ENDPOINT = "/_mcp/sse/swagger";
184
+ server.middlewares.use(ENDPOINT, async (req, res, next) => {
185
+ try {
186
+ const url = new URL(req.url || "", `http://${req.headers.host}`);
187
+ const sessionId = req.headers["mcp-session-id"] || url.searchParams.get("sessionId");
188
+ if (req.method === "POST") {
189
+ const json = await readJsonBody(req);
217
190
  let transport;
218
191
  if (sessionId && transports[sessionId]) {
219
192
  transport = transports[sessionId];
220
193
  } else if (!sessionId && (0, import_types.isInitializeRequest)(json)) {
221
194
  transport = new import_streamableHttp.StreamableHTTPServerTransport({
222
195
  sessionIdGenerator: () => (0, import_node_crypto.randomUUID)(),
223
- onsessioninitialized(id) {
224
- transports[id] = transport;
196
+ // 如果你的编辑器不支持 SSE 只能接收 JSON 响应,可以设为 true
197
+ // 但大多数现代编辑器建议保持默认(false)以支持标准流
198
+ enableJsonResponse: false,
199
+ onsessioninitialized: (sid) => {
200
+ transports[sid] = transport;
201
+ console.log(`[MCP] Session initialized: ${sid}`);
225
202
  }
226
203
  });
227
204
  transport.onclose = () => {
228
- if (transport.sessionId) {
205
+ if (transport.sessionId)
229
206
  delete transports[transport.sessionId];
230
- }
207
+ console.log(`[MCP] Session closed: ${transport.sessionId}`);
231
208
  };
232
- const mcpServer = createMcpServer();
209
+ const mcpServer = createNewServer();
233
210
  await mcpServer.connect(transport);
234
211
  } else {
235
212
  res.statusCode = 400;
236
- return res.end("Bad Request");
213
+ return res.end(JSON.stringify({ error: "Invalid session or not an initialize request" }));
237
214
  }
238
215
  await transport.handleRequest(req, res, json);
239
- } catch (err) {
240
- console.error(err);
241
- res.statusCode = 500;
242
- res.end("Internal Error");
216
+ return;
243
217
  }
244
- return;
245
- }
246
- if (req.method === "GET") {
247
- if (!sessionId || !transports[sessionId]) {
248
- res.statusCode = 400;
249
- return res.end("Missing session");
218
+ if (req.method === "GET") {
219
+ if (!sessionId || !transports[sessionId]) {
220
+ const initTransport = new import_streamableHttp.StreamableHTTPServerTransport();
221
+ await initTransport.handleRequest(req, res);
222
+ return;
223
+ }
224
+ await transports[sessionId].handleRequest(req, res);
225
+ return;
226
+ }
227
+ res.statusCode = 405;
228
+ res.end("Method Not Allowed");
229
+ } catch (error) {
230
+ console.error("[MCP Error]", error);
231
+ if (!res.headersSent) {
232
+ res.statusCode = 500;
233
+ res.end("Internal Server Error");
250
234
  }
251
- await transports[sessionId].handleRequest(req, res);
252
- return;
253
235
  }
254
- res.statusCode = 405;
255
- res.end();
256
236
  });
257
- console.log(
258
- `Swagger MCP ready: http://localhost:${(_a = vite.config.server) == null ? void 0 : _a.port}/_mcp/swagger`
259
- );
237
+ console.log(`✅ MCP Swagger Server mounted at http://localhost:${(_b = (_a = server.config) == null ? void 0 : _a.server) == null ? void 0 : _b.port}${ENDPOINT}`);
260
238
  }
261
239
  };
262
240
  }
@@ -42,7 +42,7 @@ export declare class SwaggerMcpServer {
42
42
  method: string;
43
43
  }>;
44
44
  }
45
- export default function vitePluginSwaggerMcp(options: {
45
+ export default function vitePluginSwaggerMcp({ swaggerUrl, token, }: {
46
46
  swaggerUrl: string;
47
47
  token?: string;
48
48
  }): Plugin;
package/dist/esm/index.js CHANGED
@@ -2,24 +2,88 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
2
2
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
3
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
4
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
5
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
6
- function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
7
5
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
8
6
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
9
7
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
10
8
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
9
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
12
10
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
11
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
12
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
13
13
  function _asyncIterator(r) { var n, t, o, e = 2; for ("undefined" != typeof Symbol && (t = Symbol.asyncIterator, o = Symbol.iterator); e--;) { if (t && null != (n = r[t])) return n.call(r); if (o && null != (n = r[o])) return new AsyncFromSyncIterator(n.call(r)); t = "@@asyncIterator", o = "@@iterator"; } throw new TypeError("Object is not async iterable"); }
14
14
  function AsyncFromSyncIterator(r) { function AsyncFromSyncIteratorContinuation(r) { if (Object(r) !== r) return Promise.reject(new TypeError(r + " is not an object.")); var n = r.done; return Promise.resolve(r.value).then(function (r) { return { value: r, done: n }; }); } return AsyncFromSyncIterator = function AsyncFromSyncIterator(r) { this.s = r, this.n = r.next; }, AsyncFromSyncIterator.prototype = { s: null, n: null, next: function next() { return AsyncFromSyncIteratorContinuation(this.n.apply(this.s, arguments)); }, return: function _return(r) { var n = this.s.return; return void 0 === n ? Promise.resolve({ value: r, done: !0 }) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); }, throw: function _throw(r) { var n = this.s.return; return void 0 === n ? Promise.reject(r) : AsyncFromSyncIteratorContinuation(n.apply(this.s, arguments)); } }, new AsyncFromSyncIterator(r); }
15
15
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
16
- import { randomUUID } from "node:crypto";
17
- import * as z from "zod";
18
- import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp";
16
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
19
17
  import { isInitializeRequest } from "@modelcontextprotocol/sdk/types";
20
- /* =========================
21
- * Swagger MCP Server
22
- * ========================= */
18
+ import { randomUUID } from "node:crypto";
19
+ import { z } from "zod/v4";
20
+ // --- 辅助函数:解析 JSON Body ---
21
+ function readJsonBody(_x) {
22
+ return _readJsonBody.apply(this, arguments);
23
+ }
24
+ function _readJsonBody() {
25
+ _readJsonBody = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10(req) {
26
+ var body, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, chunk;
27
+ return _regeneratorRuntime().wrap(function _callee10$(_context10) {
28
+ while (1) switch (_context10.prev = _context10.next) {
29
+ case 0:
30
+ body = "";
31
+ _iteratorAbruptCompletion = false;
32
+ _didIteratorError = false;
33
+ _context10.prev = 3;
34
+ _iterator = _asyncIterator(req);
35
+ case 5:
36
+ _context10.next = 7;
37
+ return _iterator.next();
38
+ case 7:
39
+ if (!(_iteratorAbruptCompletion = !(_step = _context10.sent).done)) {
40
+ _context10.next = 13;
41
+ break;
42
+ }
43
+ chunk = _step.value;
44
+ body += chunk;
45
+ case 10:
46
+ _iteratorAbruptCompletion = false;
47
+ _context10.next = 5;
48
+ break;
49
+ case 13:
50
+ _context10.next = 19;
51
+ break;
52
+ case 15:
53
+ _context10.prev = 15;
54
+ _context10.t0 = _context10["catch"](3);
55
+ _didIteratorError = true;
56
+ _iteratorError = _context10.t0;
57
+ case 19:
58
+ _context10.prev = 19;
59
+ _context10.prev = 20;
60
+ if (!(_iteratorAbruptCompletion && _iterator.return != null)) {
61
+ _context10.next = 24;
62
+ break;
63
+ }
64
+ _context10.next = 24;
65
+ return _iterator.return();
66
+ case 24:
67
+ _context10.prev = 24;
68
+ if (!_didIteratorError) {
69
+ _context10.next = 27;
70
+ break;
71
+ }
72
+ throw _iteratorError;
73
+ case 27:
74
+ return _context10.finish(24);
75
+ case 28:
76
+ return _context10.finish(19);
77
+ case 29:
78
+ return _context10.abrupt("return", JSON.parse(body || "{}"));
79
+ case 30:
80
+ case "end":
81
+ return _context10.stop();
82
+ }
83
+ }, _callee10, null, [[3, 15, 19, 29], [20,, 24, 28]]);
84
+ }));
85
+ return _readJsonBody.apply(this, arguments);
86
+ }
23
87
  export var SwaggerMcpServer = /*#__PURE__*/function () {
24
88
  function SwaggerMcpServer(swaggerUrl, token) {
25
89
  _classCallCheck(this, SwaggerMcpServer);
@@ -184,7 +248,7 @@ export var SwaggerMcpServer = /*#__PURE__*/function () {
184
248
  }
185
249
  }, _callee3, this);
186
250
  }));
187
- function getModuleApis(_x) {
251
+ function getModuleApis(_x2) {
188
252
  return _getModuleApis.apply(this, arguments);
189
253
  }
190
254
  return getModuleApis;
@@ -223,7 +287,7 @@ export var SwaggerMcpServer = /*#__PURE__*/function () {
223
287
  }
224
288
  }, _callee4, this);
225
289
  }));
226
- function getApiTypes(_x2, _x3) {
290
+ function getApiTypes(_x3, _x4) {
227
291
  return _getApiTypes.apply(this, arguments);
228
292
  }
229
293
  return getApiTypes;
@@ -232,269 +296,229 @@ export var SwaggerMcpServer = /*#__PURE__*/function () {
232
296
  return SwaggerMcpServer;
233
297
  }();
234
298
 
235
- /* =========================
236
- * Vite Plugin
237
- * ========================= */
238
-
239
- export default function vitePluginSwaggerMcp(options) {
240
- var transports = {};
299
+ // 存储会话 ID 对应的 Transport 实例
300
+ var transports = {};
301
+ export default function vitePluginSwaggerMcp(_ref) {
302
+ var swaggerUrl = _ref.swaggerUrl,
303
+ token = _ref.token;
241
304
  return {
242
305
  name: "vite-plugin-swagger-mcp",
243
- configureServer: function configureServer(vite) {
244
- var _vite$config$server;
245
- var swaggerServer = new SwaggerMcpServer(options.swaggerUrl, options.token);
246
-
247
- /** 创建 MCP Server(每个 session 共享一个 definition) */
248
- var createMcpServer = function createMcpServer() {
249
- var server = new McpServer({
250
- name: "swagger-mcp-server",
251
- version: "0.1.0"
252
- });
253
-
254
- /***
255
- * 获取模块列表
256
- */
257
- server.tool("getModules", "获取模块列表", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
258
- var res;
259
- return _regeneratorRuntime().wrap(function _callee5$(_context5) {
260
- while (1) switch (_context5.prev = _context5.next) {
261
- case 0:
262
- _context5.next = 2;
263
- return swaggerServer.getModules();
264
- case 2:
265
- res = _context5.sent;
266
- return _context5.abrupt("return", {
267
- content: [{
268
- type: "text",
269
- text: JSON.stringify(res)
270
- }]
306
+ enforce: "pre",
307
+ configureServer: function configureServer(server) {
308
+ return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee9() {
309
+ var _server$config;
310
+ var swaggerServer, createNewServer, ENDPOINT;
311
+ return _regeneratorRuntime().wrap(function _callee9$(_context9) {
312
+ while (1) switch (_context9.prev = _context9.next) {
313
+ case 0:
314
+ swaggerServer = new SwaggerMcpServer(swaggerUrl, token); // --- 辅助函数:创建并配置一个新的 MCP Server 实例 ---
315
+ createNewServer = function createNewServer() {
316
+ var mcpServer = new McpServer({
317
+ name: "swagger-mcp-server",
318
+ version: "0.1.0"
271
319
  });
272
- case 4:
273
- case "end":
274
- return _context5.stop();
275
- }
276
- }, _callee5);
277
- })));
278
320
 
279
- /***
280
- * 获取特定接口的参数及返回值类型
281
- */
282
- server.tool("getApiTypes", "获取特定接口的参数及返回值类型", {
283
- path: z.string(),
284
- method: z.string()
285
- }, /*#__PURE__*/function () {
286
- var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(args) {
287
- return _regeneratorRuntime().wrap(function _callee6$(_context6) {
288
- while (1) switch (_context6.prev = _context6.next) {
289
- case 0:
290
- _context6.t0 = JSON;
291
- _context6.next = 3;
292
- return swaggerServer.getApiTypes(args.path, args.method);
293
- case 3:
294
- _context6.t1 = _context6.sent;
295
- _context6.t2 = _context6.t0.stringify.call(_context6.t0, _context6.t1);
296
- _context6.t3 = {
297
- type: "text",
298
- text: _context6.t2
321
+ // 注册所有工具
322
+ mcpServer.tool("getModules", "获取模块列表", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5() {
323
+ var res;
324
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
325
+ while (1) switch (_context5.prev = _context5.next) {
326
+ case 0:
327
+ _context5.next = 2;
328
+ return swaggerServer.getModules();
329
+ case 2:
330
+ res = _context5.sent;
331
+ return _context5.abrupt("return", {
332
+ content: [{
333
+ type: "text",
334
+ text: JSON.stringify(res)
335
+ }]
336
+ });
337
+ case 4:
338
+ case "end":
339
+ return _context5.stop();
340
+ }
341
+ }, _callee5);
342
+ })));
343
+ mcpServer.tool("getModuleApis", "获取特定模块下的所有接口", {
344
+ module: z.string().describe("模块名称")
345
+ }, /*#__PURE__*/function () {
346
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(_ref3) {
347
+ var module, res;
348
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
349
+ while (1) switch (_context6.prev = _context6.next) {
350
+ case 0:
351
+ module = _ref3.module;
352
+ _context6.next = 3;
353
+ return swaggerServer.getModuleApis(module);
354
+ case 3:
355
+ res = _context6.sent;
356
+ return _context6.abrupt("return", {
357
+ content: [{
358
+ type: "text",
359
+ text: JSON.stringify(res)
360
+ }]
361
+ });
362
+ case 5:
363
+ case "end":
364
+ return _context6.stop();
365
+ }
366
+ }, _callee6);
367
+ }));
368
+ return function (_x5) {
369
+ return _ref4.apply(this, arguments);
299
370
  };
300
- _context6.t4 = [_context6.t3];
301
- return _context6.abrupt("return", {
302
- content: _context6.t4
303
- });
304
- case 8:
305
- case "end":
306
- return _context6.stop();
307
- }
308
- }, _callee6);
309
- }));
310
- return function (_x4) {
311
- return _ref2.apply(this, arguments);
312
- };
313
- }());
314
- server.registerTool("getApiTypes", {
315
- description: "获取接口类型定义",
316
- inputSchema: {
317
- path: z.string(),
318
- method: z.string()
319
- }
320
- }, /*#__PURE__*/function () {
321
- var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(_ref3) {
322
- var path, method;
323
- return _regeneratorRuntime().wrap(function _callee7$(_context7) {
324
- while (1) switch (_context7.prev = _context7.next) {
325
- case 0:
326
- path = _ref3.path, method = _ref3.method;
327
- _context7.t0 = JSON;
328
- _context7.next = 4;
329
- return swaggerServer.getApiTypes(path, method);
330
- case 4:
331
- _context7.t1 = _context7.sent;
332
- _context7.t2 = _context7.t0.stringify.call(_context7.t0, _context7.t1);
333
- _context7.t3 = {
334
- type: "text",
335
- text: _context7.t2
371
+ }());
372
+ mcpServer.tool("getApiTypes", "获取特定接口的参数及返回值类型", {
373
+ path: z.string(),
374
+ method: z.string()
375
+ }, /*#__PURE__*/function () {
376
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee7(args) {
377
+ return _regeneratorRuntime().wrap(function _callee7$(_context7) {
378
+ while (1) switch (_context7.prev = _context7.next) {
379
+ case 0:
380
+ _context7.t0 = JSON;
381
+ _context7.next = 3;
382
+ return swaggerServer.getApiTypes(args.path, args.method);
383
+ case 3:
384
+ _context7.t1 = _context7.sent;
385
+ _context7.t2 = _context7.t0.stringify.call(_context7.t0, _context7.t1);
386
+ _context7.t3 = {
387
+ type: "text",
388
+ text: _context7.t2
389
+ };
390
+ _context7.t4 = [_context7.t3];
391
+ return _context7.abrupt("return", {
392
+ content: _context7.t4
393
+ });
394
+ case 8:
395
+ case "end":
396
+ return _context7.stop();
397
+ }
398
+ }, _callee7);
399
+ }));
400
+ return function (_x6) {
401
+ return _ref5.apply(this, arguments);
336
402
  };
337
- _context7.t4 = [_context7.t3];
338
- return _context7.abrupt("return", {
339
- content: _context7.t4
340
- });
341
- case 9:
342
- case "end":
343
- return _context7.stop();
344
- }
345
- }, _callee7);
346
- }));
347
- return function (_x5) {
348
- return _ref4.apply(this, arguments);
349
- };
350
- }());
351
- return server;
352
- };
353
-
354
- /* =========================
355
- * MCP HTTP Endpoint
356
- * ========================= */
403
+ }());
404
+ return mcpServer;
405
+ };
406
+ ENDPOINT = "/_mcp/sse/swagger";
407
+ server.middlewares.use(ENDPOINT, /*#__PURE__*/function () {
408
+ var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(req, res, next) {
409
+ var url, _sessionId, json, transport, mcpServer, initTransport;
410
+ return _regeneratorRuntime().wrap(function _callee8$(_context8) {
411
+ while (1) switch (_context8.prev = _context8.next) {
412
+ case 0:
413
+ _context8.prev = 0;
414
+ url = new URL(req.url || "", "http://".concat(req.headers.host));
415
+ _sessionId = req.headers["mcp-session-id"] || url.searchParams.get("sessionId");
416
+ /* ================= POST 请求处理 ================= */
417
+ if (!(req.method === "POST")) {
418
+ _context8.next = 24;
419
+ break;
420
+ }
421
+ _context8.next = 6;
422
+ return readJsonBody(req);
423
+ case 6:
424
+ json = _context8.sent;
425
+ if (!(_sessionId && transports[_sessionId])) {
426
+ _context8.next = 11;
427
+ break;
428
+ }
429
+ transport = transports[_sessionId];
430
+ _context8.next = 21;
431
+ break;
432
+ case 11:
433
+ if (!(!_sessionId && isInitializeRequest(json))) {
434
+ _context8.next = 19;
435
+ break;
436
+ }
437
+ transport = new StreamableHTTPServerTransport({
438
+ sessionIdGenerator: function sessionIdGenerator() {
439
+ return randomUUID();
440
+ },
441
+ // 如果你的编辑器不支持 SSE 只能接收 JSON 响应,可以设为 true
442
+ // 但大多数现代编辑器建议保持默认(false)以支持标准流
443
+ enableJsonResponse: false,
444
+ onsessioninitialized: function onsessioninitialized(sid) {
445
+ transports[sid] = transport;
446
+ console.log("[MCP] Session initialized: ".concat(sid));
447
+ }
448
+ });
449
+ transport.onclose = function () {
450
+ if (transport.sessionId) delete transports[transport.sessionId];
451
+ console.log("[MCP] Session closed: ".concat(transport.sessionId));
452
+ };
357
453
 
358
- vite.middlewares.use("/_mcp/swagger", /*#__PURE__*/function () {
359
- var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee8(req, res) {
360
- var sessionId, body, _iteratorAbruptCompletion, _didIteratorError, _iteratorError, _iterator, _step, chunk, json, transport, mcpServer;
361
- return _regeneratorRuntime().wrap(function _callee8$(_context8) {
362
- while (1) switch (_context8.prev = _context8.next) {
363
- case 0:
364
- sessionId = req.headers["mcp-session-id"];
365
- /* ---------- POST (JSON-RPC) ---------- */
366
- if (!(req.method === "POST")) {
367
- _context8.next = 57;
368
- break;
369
- }
370
- body = "";
371
- _iteratorAbruptCompletion = false;
372
- _didIteratorError = false;
373
- _context8.prev = 5;
374
- _iterator = _asyncIterator(req);
375
- case 7:
376
- _context8.next = 9;
377
- return _iterator.next();
378
- case 9:
379
- if (!(_iteratorAbruptCompletion = !(_step = _context8.sent).done)) {
380
- _context8.next = 15;
381
- break;
382
- }
383
- chunk = _step.value;
384
- body += chunk;
385
- case 12:
386
- _iteratorAbruptCompletion = false;
387
- _context8.next = 7;
388
- break;
389
- case 15:
390
- _context8.next = 21;
391
- break;
392
- case 17:
393
- _context8.prev = 17;
394
- _context8.t0 = _context8["catch"](5);
395
- _didIteratorError = true;
396
- _iteratorError = _context8.t0;
397
- case 21:
398
- _context8.prev = 21;
399
- _context8.prev = 22;
400
- if (!(_iteratorAbruptCompletion && _iterator.return != null)) {
401
- _context8.next = 26;
402
- break;
403
- }
404
- _context8.next = 26;
405
- return _iterator.return();
406
- case 26:
407
- _context8.prev = 26;
408
- if (!_didIteratorError) {
409
- _context8.next = 29;
410
- break;
411
- }
412
- throw _iteratorError;
413
- case 29:
414
- return _context8.finish(26);
415
- case 30:
416
- return _context8.finish(21);
417
- case 31:
418
- json = JSON.parse(body);
419
- _context8.prev = 32;
420
- if (!(sessionId && transports[sessionId])) {
421
- _context8.next = 37;
422
- break;
423
- }
424
- transport = transports[sessionId];
425
- _context8.next = 47;
426
- break;
427
- case 37:
428
- if (!(!sessionId && isInitializeRequest(json))) {
429
- _context8.next = 45;
430
- break;
431
- }
432
- transport = new StreamableHTTPServerTransport({
433
- sessionIdGenerator: function sessionIdGenerator() {
434
- return randomUUID();
435
- },
436
- onsessioninitialized: function onsessioninitialized(id) {
437
- transports[id] = transport;
438
- }
439
- });
440
- transport.onclose = function () {
441
- if (transport.sessionId) {
442
- delete transports[transport.sessionId];
443
- }
454
+ // 为这个 Transport 绑定一个新的 Server 实例,防止 "Already initialized"
455
+ mcpServer = createNewServer();
456
+ _context8.next = 17;
457
+ return mcpServer.connect(transport);
458
+ case 17:
459
+ _context8.next = 21;
460
+ break;
461
+ case 19:
462
+ res.statusCode = 400;
463
+ return _context8.abrupt("return", res.end(JSON.stringify({
464
+ error: "Invalid session or not an initialize request"
465
+ })));
466
+ case 21:
467
+ _context8.next = 23;
468
+ return transport.handleRequest(req, res, json);
469
+ case 23:
470
+ return _context8.abrupt("return");
471
+ case 24:
472
+ if (!(req.method === "GET")) {
473
+ _context8.next = 33;
474
+ break;
475
+ }
476
+ if (!(!_sessionId || !transports[_sessionId])) {
477
+ _context8.next = 30;
478
+ break;
479
+ }
480
+ // 如果是初次连接请求且没有 sessionId,让 transport 处理以发送 endpoint 事件
481
+ // 这里创建一个临时的 transport 来引导客户端
482
+ initTransport = new StreamableHTTPServerTransport();
483
+ _context8.next = 29;
484
+ return initTransport.handleRequest(req, res);
485
+ case 29:
486
+ return _context8.abrupt("return");
487
+ case 30:
488
+ _context8.next = 32;
489
+ return transports[_sessionId].handleRequest(req, res);
490
+ case 32:
491
+ return _context8.abrupt("return");
492
+ case 33:
493
+ res.statusCode = 405;
494
+ res.end("Method Not Allowed");
495
+ _context8.next = 41;
496
+ break;
497
+ case 37:
498
+ _context8.prev = 37;
499
+ _context8.t0 = _context8["catch"](0);
500
+ console.error("[MCP Error]", _context8.t0);
501
+ if (!res.headersSent) {
502
+ res.statusCode = 500;
503
+ res.end("Internal Server Error");
504
+ }
505
+ case 41:
506
+ case "end":
507
+ return _context8.stop();
508
+ }
509
+ }, _callee8, null, [[0, 37]]);
510
+ }));
511
+ return function (_x7, _x8, _x9) {
512
+ return _ref6.apply(this, arguments);
444
513
  };
445
- mcpServer = createMcpServer();
446
- _context8.next = 43;
447
- return mcpServer.connect(transport);
448
- case 43:
449
- _context8.next = 47;
450
- break;
451
- case 45:
452
- res.statusCode = 400;
453
- return _context8.abrupt("return", res.end("Bad Request"));
454
- case 47:
455
- _context8.next = 49;
456
- return transport.handleRequest(req, res, json);
457
- case 49:
458
- _context8.next = 56;
459
- break;
460
- case 51:
461
- _context8.prev = 51;
462
- _context8.t1 = _context8["catch"](32);
463
- console.error(_context8.t1);
464
- res.statusCode = 500;
465
- res.end("Internal Error");
466
- case 56:
467
- return _context8.abrupt("return");
468
- case 57:
469
- if (!(req.method === "GET")) {
470
- _context8.next = 64;
471
- break;
472
- }
473
- if (!(!sessionId || !transports[sessionId])) {
474
- _context8.next = 61;
475
- break;
476
- }
477
- res.statusCode = 400;
478
- return _context8.abrupt("return", res.end("Missing session"));
479
- case 61:
480
- _context8.next = 63;
481
- return transports[sessionId].handleRequest(req, res);
482
- case 63:
483
- return _context8.abrupt("return");
484
- case 64:
485
- res.statusCode = 405;
486
- res.end();
487
- case 66:
488
- case "end":
489
- return _context8.stop();
490
- }
491
- }, _callee8, null, [[5, 17, 21, 31], [22,, 26, 30], [32, 51]]);
492
- }));
493
- return function (_x6, _x7) {
494
- return _ref5.apply(this, arguments);
495
- };
496
- }());
497
- console.log("Swagger MCP ready: http://localhost:".concat((_vite$config$server = vite.config.server) === null || _vite$config$server === void 0 ? void 0 : _vite$config$server.port, "/_mcp/swagger"));
514
+ }());
515
+ console.log("\u2705 MCP Swagger Server mounted at 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).concat(ENDPOINT));
516
+ case 5:
517
+ case "end":
518
+ return _context9.stop();
519
+ }
520
+ }, _callee9);
521
+ }))();
498
522
  }
499
523
  };
500
524
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-plugin-swagger-mcp",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "description": "vite plugin for swagger mcp",
5
5
  "homepage": "https://github.com/mmdctjj/vite-plugin-swagger-mcp",
6
6
  "repository": {