mcp-use 2.0.0-beta.5 → 2.0.0-beta.6
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/.tsbuildinfo +1 -1
- package/dist/{chunk-SFI2T6TE.js → chunk-PMPGMSYA.js} +8 -1
- package/dist/chunk-PMPGMSYA.js.map +1 -0
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/config.d.ts +41 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/fetch-app.d.ts +17 -0
- package/dist/fetch-app.d.ts.map +1 -1
- package/dist/index.d.ts +13 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +428 -46
- package/dist/index.js.map +1 -1
- package/dist/middleware/cors.d.ts +11 -0
- package/dist/middleware/cors.d.ts.map +1 -0
- package/dist/middleware/mcp-middleware.d.ts +135 -0
- package/dist/middleware/mcp-middleware.d.ts.map +1 -0
- package/dist/oauth/index.js +1 -1
- package/dist/{public-route-7IK5D7V7.js → public-route-26FUVRO5.js} +5 -3
- package/dist/public-route-26FUVRO5.js.map +1 -0
- package/dist/react/index.js.map +1 -1
- package/dist/resources.d.ts +22 -1
- package/dist/resources.d.ts.map +1 -1
- package/dist/server.d.ts +49 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/tools.d.ts +12 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/views/public-route.d.ts +7 -3
- package/dist/views/public-route.d.ts.map +1 -1
- package/dist/views/routes.d.ts +2 -0
- package/dist/views/routes.d.ts.map +1 -1
- package/dist/views/wire.d.ts +7 -3
- package/dist/views/wire.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-SFI2T6TE.js.map +0 -1
- package/dist/public-route-7IK5D7V7.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -18,8 +18,9 @@ import {
|
|
|
18
18
|
originValidationMiddleware,
|
|
19
19
|
pathnameOf,
|
|
20
20
|
requireBearerAuth,
|
|
21
|
-
routeFetch
|
|
22
|
-
|
|
21
|
+
routeFetch,
|
|
22
|
+
toFrameworkHandler
|
|
23
|
+
} from "./chunk-PMPGMSYA.js";
|
|
23
24
|
import {
|
|
24
25
|
getOAuthProviderOptions,
|
|
25
26
|
resolveConfiguredOAuthResource,
|
|
@@ -229,6 +230,176 @@ function toAuthenticatedRequestContext(ctx) {
|
|
|
229
230
|
};
|
|
230
231
|
}
|
|
231
232
|
|
|
233
|
+
// src/middleware/cors.ts
|
|
234
|
+
var DEFAULT_METHODS = ["GET", "HEAD", "POST", "OPTIONS"];
|
|
235
|
+
var DEFAULT_ALLOWED_HEADERS = [
|
|
236
|
+
"Content-Type",
|
|
237
|
+
"Authorization",
|
|
238
|
+
"mcp-protocol-version",
|
|
239
|
+
"mcp-method",
|
|
240
|
+
"mcp-name"
|
|
241
|
+
];
|
|
242
|
+
function resolveAllowedOrigin(origin, requestOrigin) {
|
|
243
|
+
if (origin === void 0) {
|
|
244
|
+
return requestOrigin;
|
|
245
|
+
}
|
|
246
|
+
if (typeof origin === "function") {
|
|
247
|
+
return origin(requestOrigin);
|
|
248
|
+
}
|
|
249
|
+
if (origin === "*") {
|
|
250
|
+
return "*";
|
|
251
|
+
}
|
|
252
|
+
if (Array.isArray(origin)) {
|
|
253
|
+
if (requestOrigin !== null && origin.includes(requestOrigin)) {
|
|
254
|
+
return requestOrigin;
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
return origin;
|
|
259
|
+
}
|
|
260
|
+
function corsHeaders(options, request) {
|
|
261
|
+
if (request.headers.has("Access-Control-Allow-Origin")) {
|
|
262
|
+
return void 0;
|
|
263
|
+
}
|
|
264
|
+
const requestOrigin = request.headers.get("Origin");
|
|
265
|
+
const allowedOrigin = resolveAllowedOrigin(options.origin, requestOrigin);
|
|
266
|
+
if (allowedOrigin === null) {
|
|
267
|
+
return void 0;
|
|
268
|
+
}
|
|
269
|
+
const headers = {
|
|
270
|
+
"Access-Control-Allow-Origin": allowedOrigin,
|
|
271
|
+
"Access-Control-Allow-Methods": options.methods.join(", "),
|
|
272
|
+
"Access-Control-Allow-Headers": options.allowedHeaders.join(", ")
|
|
273
|
+
};
|
|
274
|
+
if (options.credentials) {
|
|
275
|
+
headers["Access-Control-Allow-Credentials"] = "true";
|
|
276
|
+
}
|
|
277
|
+
if (allowedOrigin !== "*") {
|
|
278
|
+
headers.Vary = "Origin";
|
|
279
|
+
}
|
|
280
|
+
return headers;
|
|
281
|
+
}
|
|
282
|
+
function mergeCorsHeaders(response, headers) {
|
|
283
|
+
if (response.headers.has("Access-Control-Allow-Origin")) {
|
|
284
|
+
return response;
|
|
285
|
+
}
|
|
286
|
+
const merged = new Headers(response.headers);
|
|
287
|
+
const corsHeaders2 = new Headers(headers);
|
|
288
|
+
corsHeaders2.forEach((value, key) => {
|
|
289
|
+
merged.set(key, value);
|
|
290
|
+
});
|
|
291
|
+
return new Response(response.body, {
|
|
292
|
+
status: response.status,
|
|
293
|
+
statusText: response.statusText,
|
|
294
|
+
headers: merged
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function corsFetchMiddleware(options) {
|
|
298
|
+
const enabled = options.enabled !== false;
|
|
299
|
+
if (!enabled) {
|
|
300
|
+
return async (_request, next) => next();
|
|
301
|
+
}
|
|
302
|
+
const resolved = {
|
|
303
|
+
...options.origin !== void 0 && { origin: options.origin },
|
|
304
|
+
methods: options.methods ?? DEFAULT_METHODS,
|
|
305
|
+
allowedHeaders: options.allowedHeaders ?? DEFAULT_ALLOWED_HEADERS,
|
|
306
|
+
credentials: options.credentials ?? false
|
|
307
|
+
};
|
|
308
|
+
return async (request, next) => {
|
|
309
|
+
const headers = corsHeaders(resolved, request);
|
|
310
|
+
if (headers === void 0) {
|
|
311
|
+
return next();
|
|
312
|
+
}
|
|
313
|
+
if (request.method === "OPTIONS") {
|
|
314
|
+
return new Response(null, { status: 204, headers });
|
|
315
|
+
}
|
|
316
|
+
const response = await next();
|
|
317
|
+
return mergeCorsHeaders(response, headers);
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function isGlobalCorsEnabled(cors) {
|
|
321
|
+
return cors !== void 0 && cors.enabled !== false;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// src/middleware/mcp-middleware.ts
|
|
325
|
+
function matchesPattern(pattern, method) {
|
|
326
|
+
if (pattern === "*") return true;
|
|
327
|
+
if (pattern.endsWith("/*")) {
|
|
328
|
+
const prefix = pattern.slice(0, -1);
|
|
329
|
+
return method.startsWith(prefix);
|
|
330
|
+
}
|
|
331
|
+
return pattern === method;
|
|
332
|
+
}
|
|
333
|
+
function composeMiddleware(entries, method, innerFn) {
|
|
334
|
+
const matching = entries.filter((e) => matchesPattern(e.pattern, method));
|
|
335
|
+
if (matching.length === 0) {
|
|
336
|
+
return (_ctx) => innerFn();
|
|
337
|
+
}
|
|
338
|
+
return (ctx) => {
|
|
339
|
+
let index = -1;
|
|
340
|
+
const dispatch = (i) => {
|
|
341
|
+
if (i <= index) {
|
|
342
|
+
return Promise.reject(new Error("next() called multiple times"));
|
|
343
|
+
}
|
|
344
|
+
index = i;
|
|
345
|
+
if (i === matching.length) {
|
|
346
|
+
return innerFn();
|
|
347
|
+
}
|
|
348
|
+
const entry = matching[i];
|
|
349
|
+
return entry.handler(ctx, () => dispatch(i + 1));
|
|
350
|
+
};
|
|
351
|
+
return dispatch(0);
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function freezeMiddlewareContext(ctx) {
|
|
355
|
+
return Object.freeze({
|
|
356
|
+
method: ctx.method,
|
|
357
|
+
params: Object.freeze({ ...ctx.params }),
|
|
358
|
+
...ctx.auth !== void 0 && { auth: ctx.auth },
|
|
359
|
+
state: ctx.state
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
async function runMcpOperation(middlewares, events, method, ctx, innerFn) {
|
|
363
|
+
dispatchMcpEvents(events, method, "before", ctx);
|
|
364
|
+
const chained = composeMiddleware(middlewares, method, innerFn);
|
|
365
|
+
const result = await chained(ctx);
|
|
366
|
+
dispatchMcpEvents(events, method, "complete", ctx, result);
|
|
367
|
+
return result;
|
|
368
|
+
}
|
|
369
|
+
function dispatchMcpEvents(events, method, phase, ctx, result) {
|
|
370
|
+
const frozen = freezeMiddlewareContext(ctx);
|
|
371
|
+
for (const entry of events) {
|
|
372
|
+
if (entry.phase !== phase || !matchesPattern(entry.pattern, method)) {
|
|
373
|
+
continue;
|
|
374
|
+
}
|
|
375
|
+
try {
|
|
376
|
+
if (phase === "before") {
|
|
377
|
+
entry.handler(frozen);
|
|
378
|
+
} else {
|
|
379
|
+
entry.handler(frozen, result);
|
|
380
|
+
}
|
|
381
|
+
} catch (error) {
|
|
382
|
+
console.error(
|
|
383
|
+
`[mcp-use] MCP event listener for "${entry.pattern}" (${phase}) threw:`,
|
|
384
|
+
error
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
function parseMcpPattern(raw) {
|
|
390
|
+
const pattern = raw.startsWith("mcp:") ? raw.slice(4) : raw;
|
|
391
|
+
if (pattern.endsWith(":complete")) {
|
|
392
|
+
return {
|
|
393
|
+
pattern: pattern.slice(0, -":complete".length),
|
|
394
|
+
phase: "complete"
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
return { pattern, phase: "before" };
|
|
398
|
+
}
|
|
399
|
+
function normalizeMcpMiddlewarePattern(raw) {
|
|
400
|
+
return raw.startsWith("mcp:") ? raw.slice(4) : raw;
|
|
401
|
+
}
|
|
402
|
+
|
|
232
403
|
// src/inspector-shell.ts
|
|
233
404
|
var INSPECTOR_TAG = "beta";
|
|
234
405
|
var DEFAULT_INSPECTOR_ASSETS_URL = `https://cdn.jsdelivr.net/npm/@mcp-use/inspector@${INSPECTOR_TAG}/dist/cdn/inspector.js`;
|
|
@@ -866,13 +1037,16 @@ function createViewAssetsHandler(basePath, views, options) {
|
|
|
866
1037
|
if (entry === void 0 || entry.kind !== "external") {
|
|
867
1038
|
return new Response("Not Found", { status: 404 });
|
|
868
1039
|
}
|
|
869
|
-
const [{ join }, { resolvePublicFilePath, servePublicFile }] = await Promise.all([import("path"), import("./public-route-
|
|
1040
|
+
const [{ join }, { resolvePublicFilePath, servePublicFile }] = await Promise.all([import("path"), import("./public-route-26FUVRO5.js")]);
|
|
870
1041
|
const viewRoot = join(projectRoot, VIEW_ASSETS_BUILD_ROOT, viewName);
|
|
871
1042
|
const diskPath = await resolvePublicFilePath(viewRoot, subpath);
|
|
872
1043
|
if (diskPath === null) {
|
|
873
1044
|
return new Response("Not Found", { status: 404 });
|
|
874
1045
|
}
|
|
875
|
-
return await servePublicFile(
|
|
1046
|
+
return await servePublicFile(
|
|
1047
|
+
diskPath,
|
|
1048
|
+
options?.deferCors === true ? { deferCors: true } : {}
|
|
1049
|
+
);
|
|
876
1050
|
};
|
|
877
1051
|
}
|
|
878
1052
|
function createViewPublicHandler(basePath, views, options) {
|
|
@@ -894,30 +1068,43 @@ function createViewPublicHandler(basePath, views, options) {
|
|
|
894
1068
|
if (subpath.length === 0) {
|
|
895
1069
|
return new Response("Not Found", { status: 404 });
|
|
896
1070
|
}
|
|
897
|
-
const [{ join }, { resolvePublicFilePath, servePublicFile }] = await Promise.all([import("path"), import("./public-route-
|
|
1071
|
+
const [{ join }, { resolvePublicFilePath, servePublicFile }] = await Promise.all([import("path"), import("./public-route-26FUVRO5.js")]);
|
|
898
1072
|
const publicRoot = join(projectRoot, subdir);
|
|
899
1073
|
const diskPath = await resolvePublicFilePath(publicRoot, subpath);
|
|
900
1074
|
if (diskPath === null) {
|
|
901
1075
|
return new Response("Not Found", { status: 404 });
|
|
902
1076
|
}
|
|
903
|
-
return await servePublicFile(
|
|
1077
|
+
return await servePublicFile(
|
|
1078
|
+
diskPath,
|
|
1079
|
+
options?.deferCors === true ? { deferCors: true } : {}
|
|
1080
|
+
);
|
|
904
1081
|
};
|
|
905
1082
|
}
|
|
906
1083
|
|
|
907
1084
|
// src/views/wire.ts
|
|
908
|
-
function buildToolUiMeta(viewName, visibility) {
|
|
909
|
-
if (viewName === void 0 && visibility === void 0) {
|
|
1085
|
+
function buildToolUiMeta(viewName, visibility, existingMetadata) {
|
|
1086
|
+
if (viewName === void 0 && visibility === void 0 && existingMetadata === void 0) {
|
|
910
1087
|
return void 0;
|
|
911
1088
|
}
|
|
912
|
-
const
|
|
913
|
-
const
|
|
1089
|
+
const meta = { ...existingMetadata };
|
|
1090
|
+
const existingUi = existingMetadata?.[UI_META_KEY];
|
|
1091
|
+
const existingUiIsObject = typeof existingUi === "object" && existingUi !== null && !Array.isArray(existingUi);
|
|
1092
|
+
const ui = existingUiIsObject ? { ...existingUi } : {};
|
|
914
1093
|
if (viewName !== void 0) {
|
|
915
1094
|
const resourceUri = viewResourceUri(viewName);
|
|
916
1095
|
ui["resourceUri"] = resourceUri;
|
|
917
1096
|
meta[UI_RESOURCE_URI_META_KEY] = resourceUri;
|
|
1097
|
+
} else {
|
|
1098
|
+
delete ui["resourceUri"];
|
|
1099
|
+
delete meta[UI_RESOURCE_URI_META_KEY];
|
|
918
1100
|
}
|
|
919
1101
|
if (visibility !== void 0) {
|
|
920
1102
|
ui["visibility"] = [visibility];
|
|
1103
|
+
} else {
|
|
1104
|
+
delete ui["visibility"];
|
|
1105
|
+
}
|
|
1106
|
+
if (viewName !== void 0 || visibility !== void 0 || existingUiIsObject) {
|
|
1107
|
+
meta[UI_META_KEY] = ui;
|
|
921
1108
|
}
|
|
922
1109
|
return meta;
|
|
923
1110
|
}
|
|
@@ -990,6 +1177,8 @@ var MCPServer = class _MCPServer {
|
|
|
990
1177
|
#oauthResourceConfigurationAbsent = false;
|
|
991
1178
|
/** Whether the mounted app validates Host headers (fixed at first mount). */
|
|
992
1179
|
#hostValidated = false;
|
|
1180
|
+
#mcpMiddlewares = [];
|
|
1181
|
+
#mcpEventListeners = [];
|
|
993
1182
|
/**
|
|
994
1183
|
* Create an MCP server from a parsed, bundled OpenAPI document.
|
|
995
1184
|
*
|
|
@@ -1172,7 +1361,72 @@ var MCPServer = class _MCPServer {
|
|
|
1172
1361
|
*/
|
|
1173
1362
|
getHandler(options = {}) {
|
|
1174
1363
|
const { fetch } = this.#ensureMounted("handler", void 0, options.bus);
|
|
1175
|
-
return fetch;
|
|
1364
|
+
return toFrameworkHandler(fetch);
|
|
1365
|
+
}
|
|
1366
|
+
/**
|
|
1367
|
+
* Node `(req, res) => void` handler for composing with an existing
|
|
1368
|
+
* `http.Server`. Uses the same internal `toNodeHandler` bridge as
|
|
1369
|
+
* {@link MCPServer.listen}; MCPServer users do not need to import
|
|
1370
|
+
* `mcp-use/node`.
|
|
1371
|
+
*
|
|
1372
|
+
* @example
|
|
1373
|
+
* ```ts
|
|
1374
|
+
* import { createServer } from "node:http";
|
|
1375
|
+
* const httpServer = createServer(await server.getNodeHandler());
|
|
1376
|
+
* httpServer.listen(3000);
|
|
1377
|
+
* ```
|
|
1378
|
+
*/
|
|
1379
|
+
async getNodeHandler() {
|
|
1380
|
+
const { fetch } = this.#ensureMounted("handler");
|
|
1381
|
+
const { toNodeHandler } = await import("./node-bridge.js");
|
|
1382
|
+
return toNodeHandler({ fetch });
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
* Register MCP operation middleware that intercepts JSON-RPC dispatch.
|
|
1386
|
+
*
|
|
1387
|
+
* Patterns use an `mcp:` prefix (for example `mcp:tools/call`, `mcp:*`).
|
|
1388
|
+
* Middleware runs in registration order; call `next()` to continue the chain.
|
|
1389
|
+
*
|
|
1390
|
+
* @example
|
|
1391
|
+
* ```ts
|
|
1392
|
+
* server.use("mcp:tools/call", async (ctx, next) => {
|
|
1393
|
+
* console.log(`Calling tool: ${ctx.params.name}`);
|
|
1394
|
+
* return next();
|
|
1395
|
+
* });
|
|
1396
|
+
* ```
|
|
1397
|
+
*/
|
|
1398
|
+
use(pattern, handler) {
|
|
1399
|
+
this.#assertNotStarted("middleware", pattern);
|
|
1400
|
+
this.#mcpMiddlewares.push({
|
|
1401
|
+
pattern: normalizeMcpMiddlewarePattern(pattern),
|
|
1402
|
+
handler
|
|
1403
|
+
});
|
|
1404
|
+
return this;
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Register a read-only MCP observer. Unlike {@link MCPServer.use}, listeners
|
|
1408
|
+
* cannot block, override, or mutate params. Throwing is logged and does not
|
|
1409
|
+
* fail the request.
|
|
1410
|
+
*
|
|
1411
|
+
* Append `:complete` to run after the handler (for example
|
|
1412
|
+
* `mcp:tools/call:complete`).
|
|
1413
|
+
*
|
|
1414
|
+
* @example
|
|
1415
|
+
* ```ts
|
|
1416
|
+
* server.on("mcp:tools/call", (ctx) => {
|
|
1417
|
+
* metrics.increment("tools.call", { tool: ctx.params.name });
|
|
1418
|
+
* });
|
|
1419
|
+
* ```
|
|
1420
|
+
*/
|
|
1421
|
+
on(pattern, handler) {
|
|
1422
|
+
this.#assertNotStarted("event listener", pattern);
|
|
1423
|
+
const { pattern: stripped, phase } = parseMcpPattern(pattern);
|
|
1424
|
+
this.#mcpEventListeners.push({
|
|
1425
|
+
pattern: stripped,
|
|
1426
|
+
phase,
|
|
1427
|
+
handler
|
|
1428
|
+
});
|
|
1429
|
+
return this;
|
|
1176
1430
|
}
|
|
1177
1431
|
/**
|
|
1178
1432
|
* Publish a tools-list change to v2 clients with active subscriptions.
|
|
@@ -1385,6 +1639,11 @@ var MCPServer = class _MCPServer {
|
|
|
1385
1639
|
jsonBodyMiddleware(),
|
|
1386
1640
|
requestLogger(this.#config.logging)
|
|
1387
1641
|
];
|
|
1642
|
+
const corsConfig = this.#config.cors;
|
|
1643
|
+
if (corsConfig !== void 0) {
|
|
1644
|
+
middlewares.unshift(corsFetchMiddleware(corsConfig));
|
|
1645
|
+
}
|
|
1646
|
+
const deferViewCors = isGlobalCorsEnabled(corsConfig);
|
|
1388
1647
|
if (hosts !== void 0) {
|
|
1389
1648
|
middlewares.unshift(hostValidationMiddleware(hosts));
|
|
1390
1649
|
middlewares.push(originValidationMiddleware(origins ?? hosts));
|
|
@@ -1445,7 +1704,8 @@ var MCPServer = class _MCPServer {
|
|
|
1445
1704
|
const routes = [];
|
|
1446
1705
|
const viewHandler = createViewPublicHandler(basePath, this.#views, {
|
|
1447
1706
|
dev: this.#viewsDevMode,
|
|
1448
|
-
projectRoot: this.#viewsProjectRoot
|
|
1707
|
+
projectRoot: this.#viewsProjectRoot,
|
|
1708
|
+
deferCors: deferViewCors
|
|
1449
1709
|
});
|
|
1450
1710
|
if (viewHandler !== void 0) {
|
|
1451
1711
|
routes.push({
|
|
@@ -1459,7 +1719,7 @@ var MCPServer = class _MCPServer {
|
|
|
1459
1719
|
const viewAssetsHandler = createViewAssetsHandler(
|
|
1460
1720
|
basePath,
|
|
1461
1721
|
this.#views,
|
|
1462
|
-
{ projectRoot: this.#viewsProjectRoot }
|
|
1722
|
+
{ projectRoot: this.#viewsProjectRoot, deferCors: deferViewCors }
|
|
1463
1723
|
);
|
|
1464
1724
|
if (viewAssetsHandler !== void 0) {
|
|
1465
1725
|
routes.push({
|
|
@@ -1600,11 +1860,78 @@ var MCPServer = class _MCPServer {
|
|
|
1600
1860
|
basePath
|
|
1601
1861
|
);
|
|
1602
1862
|
}
|
|
1863
|
+
this.#wrapListHandlers(server);
|
|
1603
1864
|
return server;
|
|
1604
1865
|
}
|
|
1866
|
+
#createMiddlewareContext(method, params, ctx) {
|
|
1867
|
+
return {
|
|
1868
|
+
method,
|
|
1869
|
+
params,
|
|
1870
|
+
...ctx.http?.authInfo !== void 0 && { auth: ctx.http.authInfo },
|
|
1871
|
+
state: /* @__PURE__ */ new Map()
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
#runMcpHook(method, ctx, innerFn) {
|
|
1875
|
+
return runMcpOperation(
|
|
1876
|
+
this.#mcpMiddlewares,
|
|
1877
|
+
this.#mcpEventListeners,
|
|
1878
|
+
method,
|
|
1879
|
+
ctx,
|
|
1880
|
+
innerFn
|
|
1881
|
+
);
|
|
1882
|
+
}
|
|
1883
|
+
/**
|
|
1884
|
+
* Wrap native SDK list handlers with the MCP middleware chain.
|
|
1885
|
+
*
|
|
1886
|
+
* ponytail: uses SDK-private `_requestHandlers`; pin compile-time test.
|
|
1887
|
+
*
|
|
1888
|
+
* @internal
|
|
1889
|
+
*/
|
|
1890
|
+
#wrapListHandlers(server) {
|
|
1891
|
+
const handlers = server.server._requestHandlers;
|
|
1892
|
+
if (handlers === void 0) {
|
|
1893
|
+
return;
|
|
1894
|
+
}
|
|
1895
|
+
const wrapListMethod = (method, resultKey) => {
|
|
1896
|
+
const original = handlers.get(method);
|
|
1897
|
+
if (original === void 0) {
|
|
1898
|
+
return;
|
|
1899
|
+
}
|
|
1900
|
+
if (original.__mcpListWrapped) {
|
|
1901
|
+
return;
|
|
1902
|
+
}
|
|
1903
|
+
const wrapped = async (request, extra) => {
|
|
1904
|
+
const authInfo = extra?.http?.authInfo;
|
|
1905
|
+
const mwCtx = {
|
|
1906
|
+
method,
|
|
1907
|
+
params: {},
|
|
1908
|
+
...authInfo !== void 0 && { auth: authInfo },
|
|
1909
|
+
state: /* @__PURE__ */ new Map()
|
|
1910
|
+
};
|
|
1911
|
+
const innerFn = async () => {
|
|
1912
|
+
const result = await original(request, extra);
|
|
1913
|
+
return result[resultKey] ?? result;
|
|
1914
|
+
};
|
|
1915
|
+
const filtered = await this.#runMcpHook(method, mwCtx, innerFn);
|
|
1916
|
+
if (Array.isArray(filtered)) {
|
|
1917
|
+
return { [resultKey]: filtered };
|
|
1918
|
+
}
|
|
1919
|
+
return filtered;
|
|
1920
|
+
};
|
|
1921
|
+
wrapped.__mcpListWrapped = true;
|
|
1922
|
+
handlers.set(method, wrapped);
|
|
1923
|
+
};
|
|
1924
|
+
wrapListMethod("tools/list", "tools");
|
|
1925
|
+
wrapListMethod("resources/list", "resources");
|
|
1926
|
+
wrapListMethod("prompts/list", "prompts");
|
|
1927
|
+
}
|
|
1605
1928
|
#registerTool(server, { definition, callback }) {
|
|
1606
1929
|
const view = definition.view;
|
|
1607
|
-
const
|
|
1930
|
+
const toolMeta = buildToolUiMeta(
|
|
1931
|
+
view?.name,
|
|
1932
|
+
definition.visibility,
|
|
1933
|
+
definition._meta
|
|
1934
|
+
);
|
|
1608
1935
|
const config = {
|
|
1609
1936
|
...definition.title !== void 0 && { title: definition.title },
|
|
1610
1937
|
...definition.description !== void 0 && {
|
|
@@ -1616,29 +1943,22 @@ var MCPServer = class _MCPServer {
|
|
|
1616
1943
|
...definition.outputSchema !== void 0 && {
|
|
1617
1944
|
outputSchema: definition.outputSchema
|
|
1618
1945
|
},
|
|
1619
|
-
...
|
|
1946
|
+
...toolMeta !== void 0 && { _meta: toolMeta }
|
|
1620
1947
|
};
|
|
1621
1948
|
const wireResultMeta = view !== void 0 ? buildToolResultUiMeta(view.name) : void 0;
|
|
1622
1949
|
const inputSchema = resolveToolInputSchema(definition);
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
{
|
|
1627
|
-
|
|
1628
|
-
const params = args;
|
|
1629
|
-
const result = await callback(params, this.#toRequestContext(ctx));
|
|
1630
|
-
if (isInputRequiredResult(result) || wireResultMeta === void 0 || result.isError === true) {
|
|
1631
|
-
return result;
|
|
1632
|
-
}
|
|
1633
|
-
return {
|
|
1634
|
-
...result,
|
|
1635
|
-
_meta: { ...result._meta, ...wireResultMeta }
|
|
1636
|
-
};
|
|
1637
|
-
}
|
|
1950
|
+
const invokeTool = async (args, ctx) => {
|
|
1951
|
+
const mwCtx = this.#createMiddlewareContext(
|
|
1952
|
+
"tools/call",
|
|
1953
|
+
{ name: definition.name, arguments: args },
|
|
1954
|
+
ctx
|
|
1638
1955
|
);
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
const result = await callback(
|
|
1956
|
+
const innerFn = async () => {
|
|
1957
|
+
const effectiveArgs = mwCtx.params.arguments ?? {};
|
|
1958
|
+
const result = await callback(
|
|
1959
|
+
effectiveArgs,
|
|
1960
|
+
this.#toRequestContext(ctx)
|
|
1961
|
+
);
|
|
1642
1962
|
if (isInputRequiredResult(result) || wireResultMeta === void 0 || result.isError === true) {
|
|
1643
1963
|
return result;
|
|
1644
1964
|
}
|
|
@@ -1646,7 +1966,21 @@ var MCPServer = class _MCPServer {
|
|
|
1646
1966
|
...result,
|
|
1647
1967
|
_meta: { ...result._meta, ...wireResultMeta }
|
|
1648
1968
|
};
|
|
1649
|
-
}
|
|
1969
|
+
};
|
|
1970
|
+
return await this.#runMcpHook("tools/call", mwCtx, innerFn);
|
|
1971
|
+
};
|
|
1972
|
+
if (inputSchema !== void 0) {
|
|
1973
|
+
server.registerTool(
|
|
1974
|
+
definition.name,
|
|
1975
|
+
{ ...config, inputSchema },
|
|
1976
|
+
async (args, ctx) => invokeTool(args, ctx)
|
|
1977
|
+
);
|
|
1978
|
+
} else {
|
|
1979
|
+
server.registerTool(
|
|
1980
|
+
definition.name,
|
|
1981
|
+
config,
|
|
1982
|
+
async (ctx) => invokeTool({}, ctx)
|
|
1983
|
+
);
|
|
1650
1984
|
}
|
|
1651
1985
|
}
|
|
1652
1986
|
#registerViewResource(server, viewName, entry, metaOptions, basePath) {
|
|
@@ -1701,9 +2035,27 @@ var MCPServer = class _MCPServer {
|
|
|
1701
2035
|
},
|
|
1702
2036
|
...definition.mimeType !== void 0 && {
|
|
1703
2037
|
mimeType: definition.mimeType
|
|
2038
|
+
},
|
|
2039
|
+
...definition.annotations !== void 0 && {
|
|
2040
|
+
annotations: definition.annotations
|
|
2041
|
+
},
|
|
2042
|
+
...definition._meta !== void 0 && {
|
|
2043
|
+
_meta: { ...definition._meta }
|
|
1704
2044
|
}
|
|
1705
2045
|
},
|
|
1706
|
-
async (uri, ctx) =>
|
|
2046
|
+
async (uri, ctx) => {
|
|
2047
|
+
const mwCtx = this.#createMiddlewareContext(
|
|
2048
|
+
"resources/read",
|
|
2049
|
+
{ uri: uri.href },
|
|
2050
|
+
ctx
|
|
2051
|
+
);
|
|
2052
|
+
const innerFn = async () => callback(uri, this.#toRequestContext(ctx));
|
|
2053
|
+
return await this.#runMcpHook(
|
|
2054
|
+
"resources/read",
|
|
2055
|
+
mwCtx,
|
|
2056
|
+
innerFn
|
|
2057
|
+
);
|
|
2058
|
+
}
|
|
1707
2059
|
);
|
|
1708
2060
|
}
|
|
1709
2061
|
#registerResourceTemplate(server, { definition, callback }) {
|
|
@@ -1720,13 +2072,31 @@ var MCPServer = class _MCPServer {
|
|
|
1720
2072
|
},
|
|
1721
2073
|
...definition.mimeType !== void 0 && {
|
|
1722
2074
|
mimeType: definition.mimeType
|
|
2075
|
+
},
|
|
2076
|
+
...definition.annotations !== void 0 && {
|
|
2077
|
+
annotations: definition.annotations
|
|
2078
|
+
},
|
|
2079
|
+
...definition._meta !== void 0 && {
|
|
2080
|
+
_meta: { ...definition._meta }
|
|
1723
2081
|
}
|
|
1724
2082
|
},
|
|
1725
|
-
async (uri, variables, ctx) =>
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
2083
|
+
async (uri, variables, ctx) => {
|
|
2084
|
+
const mwCtx = this.#createMiddlewareContext(
|
|
2085
|
+
"resources/read",
|
|
2086
|
+
{ uri: uri.href },
|
|
2087
|
+
ctx
|
|
2088
|
+
);
|
|
2089
|
+
const innerFn = async () => callback(
|
|
2090
|
+
uri,
|
|
2091
|
+
variables,
|
|
2092
|
+
this.#toRequestContext(ctx)
|
|
2093
|
+
);
|
|
2094
|
+
return await this.#runMcpHook(
|
|
2095
|
+
"resources/read",
|
|
2096
|
+
mwCtx,
|
|
2097
|
+
innerFn
|
|
2098
|
+
);
|
|
2099
|
+
}
|
|
1730
2100
|
);
|
|
1731
2101
|
}
|
|
1732
2102
|
#viewResourceFacts(viewConfig) {
|
|
@@ -1754,17 +2124,26 @@ var MCPServer = class _MCPServer {
|
|
|
1754
2124
|
description: definition.description
|
|
1755
2125
|
}
|
|
1756
2126
|
};
|
|
2127
|
+
const invokePrompt = async (args, ctx) => {
|
|
2128
|
+
const mwCtx = this.#createMiddlewareContext(
|
|
2129
|
+
"prompts/get",
|
|
2130
|
+
{ name: definition.name, arguments: args },
|
|
2131
|
+
ctx
|
|
2132
|
+
);
|
|
2133
|
+
const innerFn = async () => {
|
|
2134
|
+
const effectiveArgs = mwCtx.params.arguments ?? {};
|
|
2135
|
+
return callback(effectiveArgs, this.#toRequestContext(ctx));
|
|
2136
|
+
};
|
|
2137
|
+
return await this.#runMcpHook("prompts/get", mwCtx, innerFn);
|
|
2138
|
+
};
|
|
1757
2139
|
if (definition.schema !== void 0) {
|
|
1758
2140
|
server.registerPrompt(
|
|
1759
2141
|
definition.name,
|
|
1760
2142
|
{ ...config, argsSchema: definition.schema },
|
|
1761
|
-
async (args, ctx) =>
|
|
1762
|
-
const params = args;
|
|
1763
|
-
return callback(params, this.#toRequestContext(ctx));
|
|
1764
|
-
}
|
|
2143
|
+
async (args, ctx) => invokePrompt(args, ctx)
|
|
1765
2144
|
);
|
|
1766
2145
|
} else {
|
|
1767
|
-
const handler = async (ctx) =>
|
|
2146
|
+
const handler = async (ctx) => invokePrompt({}, ctx);
|
|
1768
2147
|
server.registerPrompt(
|
|
1769
2148
|
definition.name,
|
|
1770
2149
|
config,
|
|
@@ -1811,6 +2190,7 @@ export {
|
|
|
1811
2190
|
acceptedContent,
|
|
1812
2191
|
completable,
|
|
1813
2192
|
composeFetch,
|
|
2193
|
+
composeMiddleware,
|
|
1814
2194
|
createMcpMount,
|
|
1815
2195
|
createRequestStateCodec,
|
|
1816
2196
|
getRequestBag,
|
|
@@ -1821,10 +2201,12 @@ export {
|
|
|
1821
2201
|
jsonBodyMiddleware,
|
|
1822
2202
|
matchesPath,
|
|
1823
2203
|
matchesPathPrefix,
|
|
2204
|
+
matchesPattern,
|
|
1824
2205
|
originValidationMiddleware,
|
|
1825
2206
|
pathnameOf,
|
|
1826
2207
|
registerViews,
|
|
1827
2208
|
requestLogger,
|
|
1828
|
-
routeFetch
|
|
2209
|
+
routeFetch,
|
|
2210
|
+
toFrameworkHandler
|
|
1829
2211
|
};
|
|
1830
2212
|
//# sourceMappingURL=index.js.map
|