mcp-use 2.0.0-beta.4 → 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.
Files changed (60) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{chunk-AQ2ZZM2P.js → chunk-DQ7LE4ZA.js} +57 -13
  3. package/dist/chunk-DQ7LE4ZA.js.map +1 -0
  4. package/dist/{chunk-SFI2T6TE.js → chunk-PMPGMSYA.js} +8 -1
  5. package/dist/chunk-PMPGMSYA.js.map +1 -0
  6. package/dist/cli/build.d.ts.map +1 -1
  7. package/dist/cli/dev.d.ts.map +1 -1
  8. package/dist/cli/tools-declaration.d.ts +22 -0
  9. package/dist/cli/tools-declaration.d.ts.map +1 -0
  10. package/dist/commands/build.js +5 -1
  11. package/dist/commands/build.js.map +1 -1
  12. package/dist/commands/dev.js +5 -1
  13. package/dist/commands/dev.js.map +1 -1
  14. package/dist/config.d.ts +41 -0
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/fetch-app.d.ts +17 -0
  17. package/dist/fetch-app.d.ts.map +1 -1
  18. package/dist/index.d.ts +14 -4
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +451 -57
  21. package/dist/index.js.map +1 -1
  22. package/dist/inspector-shell.d.ts +6 -0
  23. package/dist/inspector-shell.d.ts.map +1 -1
  24. package/dist/middleware/cors.d.ts +11 -0
  25. package/dist/middleware/cors.d.ts.map +1 -0
  26. package/dist/middleware/mcp-middleware.d.ts +135 -0
  27. package/dist/middleware/mcp-middleware.d.ts.map +1 -0
  28. package/dist/mount-mcp.d.ts +0 -4
  29. package/dist/mount-mcp.d.ts.map +1 -1
  30. package/dist/oauth/index.js +1 -1
  31. package/dist/{public-route-7IK5D7V7.js → public-route-26FUVRO5.js} +5 -3
  32. package/dist/public-route-26FUVRO5.js.map +1 -0
  33. package/dist/react/hooks/use-files.d.ts +25 -0
  34. package/dist/react/hooks/use-files.d.ts.map +1 -0
  35. package/dist/react/index.d.ts +2 -0
  36. package/dist/react/index.d.ts.map +1 -1
  37. package/dist/react/index.js +66 -2
  38. package/dist/react/index.js.map +1 -1
  39. package/dist/react/runtime/view-runtime.d.ts +23 -0
  40. package/dist/react/runtime/view-runtime.d.ts.map +1 -1
  41. package/dist/react/types/file-types.d.ts +16 -0
  42. package/dist/react/types/file-types.d.ts.map +1 -0
  43. package/dist/react/types/register.d.ts +1 -1
  44. package/dist/react/types/register.d.ts.map +1 -1
  45. package/dist/resources.d.ts +22 -1
  46. package/dist/resources.d.ts.map +1 -1
  47. package/dist/server.d.ts +49 -1
  48. package/dist/server.d.ts.map +1 -1
  49. package/dist/tools.d.ts +12 -1
  50. package/dist/tools.d.ts.map +1 -1
  51. package/dist/views/public-route.d.ts +7 -3
  52. package/dist/views/public-route.d.ts.map +1 -1
  53. package/dist/views/routes.d.ts +2 -0
  54. package/dist/views/routes.d.ts.map +1 -1
  55. package/dist/views/wire.d.ts +7 -3
  56. package/dist/views/wire.d.ts.map +1 -1
  57. package/package.json +2 -2
  58. package/dist/chunk-AQ2ZZM2P.js.map +0 -1
  59. package/dist/chunk-SFI2T6TE.js.map +0 -1
  60. 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
- } from "./chunk-SFI2T6TE.js";
21
+ routeFetch,
22
+ toFrameworkHandler
23
+ } from "./chunk-PMPGMSYA.js";
23
24
  import {
24
25
  getOAuthProviderOptions,
25
26
  resolveConfiguredOAuthResource,
@@ -229,12 +230,198 @@ 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`;
235
406
  function inspectorStylesUrl(assetsUrl) {
236
407
  return assetsUrl.replace(/\.js(?=$|[?#])/, ".css");
237
408
  }
409
+ function isDefaultJsdelivrInspectorUrl(url) {
410
+ return url.startsWith("https://cdn.jsdelivr.net/npm/@mcp-use/inspector@");
411
+ }
412
+ function withInspectorCacheBust(assetsUrl) {
413
+ if (!isDefaultJsdelivrInspectorUrl(assetsUrl)) return assetsUrl;
414
+ const sep = assetsUrl.includes("?") ? "&" : "?";
415
+ return `${assetsUrl}${sep}cb=${crypto.randomUUID()}`;
416
+ }
417
+ function matchesInspectorShellPath(pathname, basePath) {
418
+ const prefix = `${basePath}/inspector`;
419
+ if (pathname !== prefix && !pathname.startsWith(`${prefix}/`)) {
420
+ return false;
421
+ }
422
+ const suffix = pathname.slice(prefix.length);
423
+ return suffix !== "/api" && !suffix.startsWith("/api/");
424
+ }
238
425
  function escapeHtml(value) {
239
426
  return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
240
427
  }
@@ -245,7 +432,8 @@ function renderInspectorShell(options) {
245
432
  const { serverName, basePath, assetsUrl, manufactChatUrl } = options;
246
433
  const serializedBasePath = serializeForInlineScript(basePath);
247
434
  const serializedManufactChatUrl = manufactChatUrl ? serializeForInlineScript(manufactChatUrl) : null;
248
- const bundleUrl = assetsUrl ?? DEFAULT_INSPECTOR_ASSETS_URL;
435
+ const rawUrl = assetsUrl ?? DEFAULT_INSPECTOR_ASSETS_URL;
436
+ const bundleUrl = withInspectorCacheBust(rawUrl);
249
437
  const scriptSrc = escapeHtml(bundleUrl);
250
438
  const stylesHref = escapeHtml(inspectorStylesUrl(bundleUrl));
251
439
  return `<!doctype html>
@@ -311,22 +499,21 @@ function createInspectorHandler(inspector, options) {
311
499
  const { assetsUrl: configAssetsUrl, manufactChatUrl: configManufactChatUrl } = inspector ?? {};
312
500
  const assetsUrl = configAssetsUrl ?? process.env["MCP_USE_INSPECTOR_ASSETS_URL"] ?? void 0;
313
501
  const manufactChatUrl = configManufactChatUrl ?? process.env["MANUFACT_CHAT_URL"] ?? void 0;
314
- const html = renderInspectorShell({
502
+ const shellOptions = {
315
503
  serverName: options.serverName,
316
504
  basePath: options.basePath,
317
505
  assetsUrl,
318
506
  manufactChatUrl
319
- });
320
- const path = `${options.basePath}/inspector`;
321
- const slashPath = `${path}/`;
507
+ };
322
508
  return async (request) => {
323
509
  if (request.method !== "GET" && request.method !== "HEAD") {
324
510
  return new Response("Method Not Allowed", { status: 405 });
325
511
  }
326
512
  const pathname = new URL(request.url).pathname;
327
- if (pathname !== path && pathname !== slashPath) {
513
+ if (!matchesInspectorShellPath(pathname, options.basePath)) {
328
514
  return new Response("Not Found", { status: 404 });
329
515
  }
516
+ const html = renderInspectorShell(shellOptions);
330
517
  return new Response(request.method === "HEAD" ? null : html, {
331
518
  status: 200,
332
519
  headers: { "content-type": "text/html; charset=utf-8" }
@@ -716,9 +903,6 @@ function createMcpMount(factory, options = {}) {
716
903
  };
717
904
  return { handler, fetch };
718
905
  }
719
- function mountMcp(factory, options = {}) {
720
- return createMcpMount(factory, options);
721
- }
722
906
 
723
907
  // src/tools.ts
724
908
  function resolveToolInputSchema(definition) {
@@ -853,13 +1037,16 @@ function createViewAssetsHandler(basePath, views, options) {
853
1037
  if (entry === void 0 || entry.kind !== "external") {
854
1038
  return new Response("Not Found", { status: 404 });
855
1039
  }
856
- const [{ join }, { resolvePublicFilePath, servePublicFile }] = await Promise.all([import("path"), import("./public-route-7IK5D7V7.js")]);
1040
+ const [{ join }, { resolvePublicFilePath, servePublicFile }] = await Promise.all([import("path"), import("./public-route-26FUVRO5.js")]);
857
1041
  const viewRoot = join(projectRoot, VIEW_ASSETS_BUILD_ROOT, viewName);
858
1042
  const diskPath = await resolvePublicFilePath(viewRoot, subpath);
859
1043
  if (diskPath === null) {
860
1044
  return new Response("Not Found", { status: 404 });
861
1045
  }
862
- return await servePublicFile(diskPath);
1046
+ return await servePublicFile(
1047
+ diskPath,
1048
+ options?.deferCors === true ? { deferCors: true } : {}
1049
+ );
863
1050
  };
864
1051
  }
865
1052
  function createViewPublicHandler(basePath, views, options) {
@@ -881,30 +1068,43 @@ function createViewPublicHandler(basePath, views, options) {
881
1068
  if (subpath.length === 0) {
882
1069
  return new Response("Not Found", { status: 404 });
883
1070
  }
884
- const [{ join }, { resolvePublicFilePath, servePublicFile }] = await Promise.all([import("path"), import("./public-route-7IK5D7V7.js")]);
1071
+ const [{ join }, { resolvePublicFilePath, servePublicFile }] = await Promise.all([import("path"), import("./public-route-26FUVRO5.js")]);
885
1072
  const publicRoot = join(projectRoot, subdir);
886
1073
  const diskPath = await resolvePublicFilePath(publicRoot, subpath);
887
1074
  if (diskPath === null) {
888
1075
  return new Response("Not Found", { status: 404 });
889
1076
  }
890
- return await servePublicFile(diskPath);
1077
+ return await servePublicFile(
1078
+ diskPath,
1079
+ options?.deferCors === true ? { deferCors: true } : {}
1080
+ );
891
1081
  };
892
1082
  }
893
1083
 
894
1084
  // src/views/wire.ts
895
- function buildToolUiMeta(viewName, visibility) {
896
- if (viewName === void 0 && visibility === void 0) {
1085
+ function buildToolUiMeta(viewName, visibility, existingMetadata) {
1086
+ if (viewName === void 0 && visibility === void 0 && existingMetadata === void 0) {
897
1087
  return void 0;
898
1088
  }
899
- const ui = {};
900
- const meta = { [UI_META_KEY]: ui };
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 } : {};
901
1093
  if (viewName !== void 0) {
902
1094
  const resourceUri = viewResourceUri(viewName);
903
1095
  ui["resourceUri"] = resourceUri;
904
1096
  meta[UI_RESOURCE_URI_META_KEY] = resourceUri;
1097
+ } else {
1098
+ delete ui["resourceUri"];
1099
+ delete meta[UI_RESOURCE_URI_META_KEY];
905
1100
  }
906
1101
  if (visibility !== void 0) {
907
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;
908
1108
  }
909
1109
  return meta;
910
1110
  }
@@ -977,6 +1177,8 @@ var MCPServer = class _MCPServer {
977
1177
  #oauthResourceConfigurationAbsent = false;
978
1178
  /** Whether the mounted app validates Host headers (fixed at first mount). */
979
1179
  #hostValidated = false;
1180
+ #mcpMiddlewares = [];
1181
+ #mcpEventListeners = [];
980
1182
  /**
981
1183
  * Create an MCP server from a parsed, bundled OpenAPI document.
982
1184
  *
@@ -1159,7 +1361,72 @@ var MCPServer = class _MCPServer {
1159
1361
  */
1160
1362
  getHandler(options = {}) {
1161
1363
  const { fetch } = this.#ensureMounted("handler", void 0, options.bus);
1162
- 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;
1163
1430
  }
1164
1431
  /**
1165
1432
  * Publish a tools-list change to v2 clients with active subscriptions.
@@ -1372,6 +1639,11 @@ var MCPServer = class _MCPServer {
1372
1639
  jsonBodyMiddleware(),
1373
1640
  requestLogger(this.#config.logging)
1374
1641
  ];
1642
+ const corsConfig = this.#config.cors;
1643
+ if (corsConfig !== void 0) {
1644
+ middlewares.unshift(corsFetchMiddleware(corsConfig));
1645
+ }
1646
+ const deferViewCors = isGlobalCorsEnabled(corsConfig);
1375
1647
  if (hosts !== void 0) {
1376
1648
  middlewares.unshift(hostValidationMiddleware(hosts));
1377
1649
  middlewares.push(originValidationMiddleware(origins ?? hosts));
@@ -1432,7 +1704,8 @@ var MCPServer = class _MCPServer {
1432
1704
  const routes = [];
1433
1705
  const viewHandler = createViewPublicHandler(basePath, this.#views, {
1434
1706
  dev: this.#viewsDevMode,
1435
- projectRoot: this.#viewsProjectRoot
1707
+ projectRoot: this.#viewsProjectRoot,
1708
+ deferCors: deferViewCors
1436
1709
  });
1437
1710
  if (viewHandler !== void 0) {
1438
1711
  routes.push({
@@ -1446,7 +1719,7 @@ var MCPServer = class _MCPServer {
1446
1719
  const viewAssetsHandler = createViewAssetsHandler(
1447
1720
  basePath,
1448
1721
  this.#views,
1449
- { projectRoot: this.#viewsProjectRoot }
1722
+ { projectRoot: this.#viewsProjectRoot, deferCors: deferViewCors }
1450
1723
  );
1451
1724
  if (viewAssetsHandler !== void 0) {
1452
1725
  routes.push({
@@ -1468,7 +1741,7 @@ var MCPServer = class _MCPServer {
1468
1741
  return false;
1469
1742
  }
1470
1743
  const pathname = new URL(request.url).pathname;
1471
- return pathname === `${basePath}/inspector` || pathname === `${basePath}/inspector/`;
1744
+ return matchesInspectorShellPath(pathname, basePath);
1472
1745
  },
1473
1746
  handler: inspectorHandler
1474
1747
  });
@@ -1587,11 +1860,78 @@ var MCPServer = class _MCPServer {
1587
1860
  basePath
1588
1861
  );
1589
1862
  }
1863
+ this.#wrapListHandlers(server);
1590
1864
  return server;
1591
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
+ }
1592
1928
  #registerTool(server, { definition, callback }) {
1593
1929
  const view = definition.view;
1594
- const toolUiMeta = buildToolUiMeta(view?.name, definition.visibility);
1930
+ const toolMeta = buildToolUiMeta(
1931
+ view?.name,
1932
+ definition.visibility,
1933
+ definition._meta
1934
+ );
1595
1935
  const config = {
1596
1936
  ...definition.title !== void 0 && { title: definition.title },
1597
1937
  ...definition.description !== void 0 && {
@@ -1603,29 +1943,22 @@ var MCPServer = class _MCPServer {
1603
1943
  ...definition.outputSchema !== void 0 && {
1604
1944
  outputSchema: definition.outputSchema
1605
1945
  },
1606
- ...toolUiMeta !== void 0 && { _meta: toolUiMeta }
1946
+ ...toolMeta !== void 0 && { _meta: toolMeta }
1607
1947
  };
1608
1948
  const wireResultMeta = view !== void 0 ? buildToolResultUiMeta(view.name) : void 0;
1609
1949
  const inputSchema = resolveToolInputSchema(definition);
1610
- if (inputSchema !== void 0) {
1611
- server.registerTool(
1612
- definition.name,
1613
- { ...config, inputSchema },
1614
- async (args, ctx) => {
1615
- const params = args;
1616
- const result = await callback(params, this.#toRequestContext(ctx));
1617
- if (isInputRequiredResult(result) || wireResultMeta === void 0 || result.isError === true) {
1618
- return result;
1619
- }
1620
- return {
1621
- ...result,
1622
- _meta: { ...result._meta, ...wireResultMeta }
1623
- };
1624
- }
1950
+ const invokeTool = async (args, ctx) => {
1951
+ const mwCtx = this.#createMiddlewareContext(
1952
+ "tools/call",
1953
+ { name: definition.name, arguments: args },
1954
+ ctx
1625
1955
  );
1626
- } else {
1627
- server.registerTool(definition.name, config, async (ctx) => {
1628
- const result = await callback({}, this.#toRequestContext(ctx));
1956
+ const innerFn = async () => {
1957
+ const effectiveArgs = mwCtx.params.arguments ?? {};
1958
+ const result = await callback(
1959
+ effectiveArgs,
1960
+ this.#toRequestContext(ctx)
1961
+ );
1629
1962
  if (isInputRequiredResult(result) || wireResultMeta === void 0 || result.isError === true) {
1630
1963
  return result;
1631
1964
  }
@@ -1633,7 +1966,21 @@ var MCPServer = class _MCPServer {
1633
1966
  ...result,
1634
1967
  _meta: { ...result._meta, ...wireResultMeta }
1635
1968
  };
1636
- });
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
+ );
1637
1984
  }
1638
1985
  }
1639
1986
  #registerViewResource(server, viewName, entry, metaOptions, basePath) {
@@ -1688,9 +2035,27 @@ var MCPServer = class _MCPServer {
1688
2035
  },
1689
2036
  ...definition.mimeType !== void 0 && {
1690
2037
  mimeType: definition.mimeType
2038
+ },
2039
+ ...definition.annotations !== void 0 && {
2040
+ annotations: definition.annotations
2041
+ },
2042
+ ...definition._meta !== void 0 && {
2043
+ _meta: { ...definition._meta }
1691
2044
  }
1692
2045
  },
1693
- async (uri, ctx) => callback(uri, this.#toRequestContext(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
+ }
1694
2059
  );
1695
2060
  }
1696
2061
  #registerResourceTemplate(server, { definition, callback }) {
@@ -1707,13 +2072,31 @@ var MCPServer = class _MCPServer {
1707
2072
  },
1708
2073
  ...definition.mimeType !== void 0 && {
1709
2074
  mimeType: definition.mimeType
2075
+ },
2076
+ ...definition.annotations !== void 0 && {
2077
+ annotations: definition.annotations
2078
+ },
2079
+ ...definition._meta !== void 0 && {
2080
+ _meta: { ...definition._meta }
1710
2081
  }
1711
2082
  },
1712
- async (uri, variables, ctx) => callback(
1713
- uri,
1714
- variables,
1715
- this.#toRequestContext(ctx)
1716
- )
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
+ }
1717
2100
  );
1718
2101
  }
1719
2102
  #viewResourceFacts(viewConfig) {
@@ -1741,17 +2124,26 @@ var MCPServer = class _MCPServer {
1741
2124
  description: definition.description
1742
2125
  }
1743
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
+ };
1744
2139
  if (definition.schema !== void 0) {
1745
2140
  server.registerPrompt(
1746
2141
  definition.name,
1747
2142
  { ...config, argsSchema: definition.schema },
1748
- async (args, ctx) => {
1749
- const params = args;
1750
- return callback(params, this.#toRequestContext(ctx));
1751
- }
2143
+ async (args, ctx) => invokePrompt(args, ctx)
1752
2144
  );
1753
2145
  } else {
1754
- const handler = async (ctx) => callback({}, this.#toRequestContext(ctx));
2146
+ const handler = async (ctx) => invokePrompt({}, ctx);
1755
2147
  server.registerPrompt(
1756
2148
  definition.name,
1757
2149
  config,
@@ -1798,6 +2190,7 @@ export {
1798
2190
  acceptedContent,
1799
2191
  completable,
1800
2192
  composeFetch,
2193
+ composeMiddleware,
1801
2194
  createMcpMount,
1802
2195
  createRequestStateCodec,
1803
2196
  getRequestBag,
@@ -1808,11 +2201,12 @@ export {
1808
2201
  jsonBodyMiddleware,
1809
2202
  matchesPath,
1810
2203
  matchesPathPrefix,
1811
- mountMcp,
2204
+ matchesPattern,
1812
2205
  originValidationMiddleware,
1813
2206
  pathnameOf,
1814
2207
  registerViews,
1815
2208
  requestLogger,
1816
- routeFetch
2209
+ routeFetch,
2210
+ toFrameworkHandler
1817
2211
  };
1818
2212
  //# sourceMappingURL=index.js.map