@xiaou66/vite-plugin-vue-mcp-next 0.0.2 → 0.0.3
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/README.md +17 -14
- package/dist/index.cjs +57 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +57 -17
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -809,18 +809,39 @@ function createMcpServer(ctx, vite) {
|
|
|
809
809
|
|
|
810
810
|
// src/mcp/transport.ts
|
|
811
811
|
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
812
|
-
|
|
812
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
813
|
+
function setupMcpTransport(base, createServer, vite) {
|
|
813
814
|
const transports = /* @__PURE__ */ new Map();
|
|
814
815
|
vite.middlewares.use(`${base}/sse`, (_req, res) => {
|
|
815
816
|
const transport = new SSEServerTransport(`${base}/messages`, res);
|
|
816
|
-
|
|
817
|
+
const server = createServer();
|
|
818
|
+
transports.set(transport.sessionId, { server, transport });
|
|
817
819
|
res.on("close", () => {
|
|
818
820
|
transports.delete(transport.sessionId);
|
|
821
|
+
void server.close();
|
|
819
822
|
});
|
|
820
823
|
void server.connect(transport).catch((error) => {
|
|
821
824
|
res.destroy(error instanceof Error ? error : new Error(String(error)));
|
|
822
825
|
});
|
|
823
826
|
});
|
|
827
|
+
vite.middlewares.use(`${base}/mcp`, (req, res) => {
|
|
828
|
+
if (req.method !== "POST") {
|
|
829
|
+
res.statusCode = 405;
|
|
830
|
+
res.end("Method Not Allowed");
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
const transport = new StreamableHTTPServerTransport({
|
|
834
|
+
sessionIdGenerator: void 0
|
|
835
|
+
});
|
|
836
|
+
const server = createServer();
|
|
837
|
+
res.on("close", () => {
|
|
838
|
+
void transport.close();
|
|
839
|
+
void server.close();
|
|
840
|
+
});
|
|
841
|
+
void server.connect(transport).then(() => transport.handleRequest(req, res)).catch((error) => {
|
|
842
|
+
res.destroy(error instanceof Error ? error : new Error(String(error)));
|
|
843
|
+
});
|
|
844
|
+
});
|
|
824
845
|
vite.middlewares.use(`${base}/messages`, (req, res) => {
|
|
825
846
|
if (req.method !== "POST") {
|
|
826
847
|
res.statusCode = 405;
|
|
@@ -834,13 +855,13 @@ function setupMcpTransport(base, server, vite) {
|
|
|
834
855
|
res.end("Bad Request");
|
|
835
856
|
return;
|
|
836
857
|
}
|
|
837
|
-
const
|
|
838
|
-
if (!
|
|
858
|
+
const entry = transports.get(sessionId);
|
|
859
|
+
if (!entry) {
|
|
839
860
|
res.statusCode = 404;
|
|
840
861
|
res.end("Not Found");
|
|
841
862
|
return;
|
|
842
863
|
}
|
|
843
|
-
void transport.handlePostMessage(req, res).catch((error) => {
|
|
864
|
+
void entry.transport.handlePostMessage(req, res).catch((error) => {
|
|
844
865
|
res.destroy(error instanceof Error ? error : new Error(String(error)));
|
|
845
866
|
});
|
|
846
867
|
});
|
|
@@ -1216,7 +1237,7 @@ function replaceOrAppendOwnedBlock(current, options) {
|
|
|
1216
1237
|
const block = createCodexServerBlock(options);
|
|
1217
1238
|
const matcher = createOwnedBlockMatcher(options.serverName);
|
|
1218
1239
|
if (matcher.test(current)) {
|
|
1219
|
-
return current
|
|
1240
|
+
return ensureTrailingNewline(current);
|
|
1220
1241
|
}
|
|
1221
1242
|
const separator = current.trim() ? "\n\n" : "";
|
|
1222
1243
|
return `${trimEndNewline(current)}${separator}${block}`;
|
|
@@ -1258,6 +1279,10 @@ async function readOptionalTextFile(filePath) {
|
|
|
1258
1279
|
function trimEndNewline(value) {
|
|
1259
1280
|
return value.replace(/\n+$/u, "");
|
|
1260
1281
|
}
|
|
1282
|
+
function ensureTrailingNewline(value) {
|
|
1283
|
+
return value.endsWith("\n") ? value : `${value}
|
|
1284
|
+
`;
|
|
1285
|
+
}
|
|
1261
1286
|
function escapeRegExp(value) {
|
|
1262
1287
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1263
1288
|
}
|
|
@@ -1279,7 +1304,10 @@ async function updateJsonMcpClientConfig(options) {
|
|
|
1279
1304
|
return;
|
|
1280
1305
|
}
|
|
1281
1306
|
const mcpServers = isPlainRecord(config.mcpServers) ? config.mcpServers : {};
|
|
1282
|
-
mcpServers
|
|
1307
|
+
if (Object.hasOwn(mcpServers, options.serverName)) {
|
|
1308
|
+
return;
|
|
1309
|
+
}
|
|
1310
|
+
mcpServers[options.serverName] = { type: "sse", url: options.mcpUrl };
|
|
1283
1311
|
config.mcpServers = mcpServers;
|
|
1284
1312
|
await fs3.mkdir(path3.dirname(options.configPath), { recursive: true });
|
|
1285
1313
|
await fs3.writeFile(
|
|
@@ -1324,7 +1352,7 @@ function isNodeError2(error) {
|
|
|
1324
1352
|
}
|
|
1325
1353
|
|
|
1326
1354
|
// src/plugin/mcpClientConfig/index.ts
|
|
1327
|
-
async function updateMcpClientConfigs(root,
|
|
1355
|
+
async function updateMcpClientConfigs(root, sseUrl, streamableHttpUrl, options) {
|
|
1328
1356
|
const serverName = options.serverName;
|
|
1329
1357
|
const jobs = [];
|
|
1330
1358
|
if (options.cursor) {
|
|
@@ -1332,7 +1360,7 @@ async function updateMcpClientConfigs(root, mcpUrl, options) {
|
|
|
1332
1360
|
updateJsonMcpClientConfig({
|
|
1333
1361
|
clientName: "Cursor",
|
|
1334
1362
|
configPath: path4.join(root, ".cursor", "mcp.json"),
|
|
1335
|
-
mcpUrl,
|
|
1363
|
+
mcpUrl: sseUrl,
|
|
1336
1364
|
serverName
|
|
1337
1365
|
})
|
|
1338
1366
|
);
|
|
@@ -1341,7 +1369,7 @@ async function updateMcpClientConfigs(root, mcpUrl, options) {
|
|
|
1341
1369
|
jobs.push(
|
|
1342
1370
|
updateCodexMcpClientConfig({
|
|
1343
1371
|
configPath: path4.join(root, ".codex", "config.toml"),
|
|
1344
|
-
mcpUrl,
|
|
1372
|
+
mcpUrl: streamableHttpUrl,
|
|
1345
1373
|
serverName
|
|
1346
1374
|
})
|
|
1347
1375
|
);
|
|
@@ -1351,7 +1379,7 @@ async function updateMcpClientConfigs(root, mcpUrl, options) {
|
|
|
1351
1379
|
updateJsonMcpClientConfig({
|
|
1352
1380
|
clientName: "Claude Code",
|
|
1353
1381
|
configPath: path4.join(root, ".mcp.json"),
|
|
1354
|
-
mcpUrl,
|
|
1382
|
+
mcpUrl: sseUrl,
|
|
1355
1383
|
serverName
|
|
1356
1384
|
})
|
|
1357
1385
|
);
|
|
@@ -1361,7 +1389,7 @@ async function updateMcpClientConfigs(root, mcpUrl, options) {
|
|
|
1361
1389
|
updateJsonMcpClientConfig({
|
|
1362
1390
|
clientName: "Trae",
|
|
1363
1391
|
configPath: path4.join(root, ".trae", "mcp.json"),
|
|
1364
|
-
mcpUrl,
|
|
1392
|
+
mcpUrl: sseUrl,
|
|
1365
1393
|
serverName
|
|
1366
1394
|
})
|
|
1367
1395
|
);
|
|
@@ -1397,8 +1425,11 @@ function vueMcpNext(userOptions = {}) {
|
|
|
1397
1425
|
timeout: -1
|
|
1398
1426
|
}
|
|
1399
1427
|
);
|
|
1400
|
-
|
|
1401
|
-
|
|
1428
|
+
setupMcpTransport(
|
|
1429
|
+
options.mcpPath,
|
|
1430
|
+
() => createMcpServer(ctx, server),
|
|
1431
|
+
server
|
|
1432
|
+
);
|
|
1402
1433
|
server.ws.on(
|
|
1403
1434
|
"vite-plugin-vue-mcp-next:page-connected",
|
|
1404
1435
|
(payload) => {
|
|
@@ -1425,12 +1456,21 @@ function vueMcpNext(userOptions = {}) {
|
|
|
1425
1456
|
}
|
|
1426
1457
|
);
|
|
1427
1458
|
const port = String(server.config.server.port || 5173);
|
|
1428
|
-
const
|
|
1459
|
+
const mcpSseUrl = `http://${options.host}:${port}${options.mcpPath}/sse`;
|
|
1460
|
+
const mcpStreamableHttpUrl = `http://${options.host}:${port}${options.mcpPath}/mcp`;
|
|
1429
1461
|
const root = searchForWorkspaceRoot(server.config.root);
|
|
1430
|
-
await updateMcpClientConfigs(
|
|
1462
|
+
await updateMcpClientConfigs(
|
|
1463
|
+
root,
|
|
1464
|
+
mcpSseUrl,
|
|
1465
|
+
mcpStreamableHttpUrl,
|
|
1466
|
+
options.mcpClients
|
|
1467
|
+
);
|
|
1431
1468
|
if (options.printUrl) {
|
|
1432
1469
|
setTimeout(() => {
|
|
1433
|
-
console.log(` \u279C MCP:
|
|
1470
|
+
console.log(` \u279C MCP: SSE server is running at ${mcpSseUrl}`);
|
|
1471
|
+
console.log(
|
|
1472
|
+
` \u279C MCP: Streamable HTTP server is running at ${mcpStreamableHttpUrl}`
|
|
1473
|
+
);
|
|
1434
1474
|
}, 300);
|
|
1435
1475
|
}
|
|
1436
1476
|
server.httpServer?.once("close", () => {
|