fastmcp 4.23.5 → 4.23.7

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.
@@ -3,7 +3,8 @@
3
3
  var _chunkC7TBI7A5cjs = require('./chunk-C7TBI7A5.cjs');
4
4
 
5
5
 
6
- var _chunkO22SYZMCcjs = require('./chunk-O22SYZMC.cjs');
6
+
7
+ var _chunkMPFPOZ2Hcjs = require('./chunk-MPFPOZ2H.cjs');
7
8
 
8
9
  // src/FastMCP.ts
9
10
  var _indexjs = require('@modelcontextprotocol/sdk/server/index.js');
@@ -225,6 +226,16 @@ function unwrapDefault(value) {
225
226
 
226
227
  // src/FastMCP.ts
227
228
  var MEDIA_FETCH_TIMEOUT_MS = 3e4;
229
+ var isSvg = (buffer) => {
230
+ let text = buffer.toString("utf8").trimStart();
231
+ const preamble = /^(?:<\?[\s\S]*?\?>|<!--[\s\S]*?-->|<!DOCTYPE\s[^[>]*(?:\[[\s\S]*?\]\s*)?>)/;
232
+ let match = preamble.exec(text);
233
+ while (match) {
234
+ text = text.slice(match[0].length).trimStart();
235
+ match = preamble.exec(text);
236
+ }
237
+ return /^<svg(?:\s|\/?>)/.test(text);
238
+ };
228
239
  var imageContent = async (input) => {
229
240
  let rawData;
230
241
  try {
@@ -267,16 +278,17 @@ var imageContent = async (input) => {
267
278
  );
268
279
  }
269
280
  const { fileTypeFromBuffer } = await Promise.resolve().then(() => _interopRequireWildcard(require("file-type")));
270
- const mimeType = await fileTypeFromBuffer(rawData);
271
- if (!mimeType || !mimeType.mime.startsWith("image/")) {
281
+ const fileType = await fileTypeFromBuffer(rawData);
282
+ const mimeType = (!fileType || fileType.mime === "application/xml") && isSvg(rawData) ? "image/svg+xml" : _optionalChain([fileType, 'optionalAccess', _4 => _4.mime]);
283
+ if (!mimeType || !mimeType.startsWith("image/")) {
272
284
  console.warn(
273
- `Warning: Content may not be a valid image. Detected MIME: ${_optionalChain([mimeType, 'optionalAccess', _4 => _4.mime]) || "unknown"}`
285
+ `Warning: Content may not be a valid image. Detected MIME: ${mimeType || "unknown"}`
274
286
  );
275
287
  }
276
288
  const base64Data = rawData.toString("base64");
277
289
  return {
278
290
  data: base64Data,
279
- mimeType: _nullishCoalesce(_optionalChain([mimeType, 'optionalAccess', _5 => _5.mime]), () => ( "image/png")),
291
+ mimeType: _nullishCoalesce(mimeType, () => ( "image/png")),
280
292
  type: "image"
281
293
  };
282
294
  } catch (error) {
@@ -287,8 +299,27 @@ var imageContent = async (input) => {
287
299
  }
288
300
  }
289
301
  };
302
+ var AUDIO_CONTAINER_TYPES = /* @__PURE__ */ new Map([
303
+ ["video/3gpp", "audio/3gpp"],
304
+ ["video/3gpp2", "audio/3gpp2"],
305
+ ["video/matroska", "audio/matroska"],
306
+ ["video/mp4", "audio/mp4"],
307
+ ["video/ogg", "audio/ogg"],
308
+ ["video/webm", "audio/webm"]
309
+ ]);
310
+ var resolveAudioMimeType = (detected, declared) => {
311
+ if (_optionalChain([detected, 'optionalAccess', _5 => _5.startsWith, 'call', _6 => _6("audio/")])) {
312
+ return detected;
313
+ }
314
+ const declaredMime = _optionalChain([declared, 'optionalAccess', _7 => _7.split, 'call', _8 => _8(";", 1), 'access', _9 => _9[0], 'access', _10 => _10.trim, 'call', _11 => _11(), 'access', _12 => _12.toLowerCase, 'call', _13 => _13()]);
315
+ if (_optionalChain([declaredMime, 'optionalAccess', _14 => _14.startsWith, 'call', _15 => _15("audio/")])) {
316
+ return declaredMime;
317
+ }
318
+ return _nullishCoalesce((detected && AUDIO_CONTAINER_TYPES.get(detected)), () => ( detected));
319
+ };
290
320
  var audioContent = async (input) => {
291
321
  let rawData;
322
+ let declaredMimeType = null;
292
323
  try {
293
324
  if ("url" in input) {
294
325
  const timeoutMs = _nullishCoalesce(input.timeoutMs, () => ( MEDIA_FETCH_TIMEOUT_MS));
@@ -302,6 +333,7 @@ var audioContent = async (input) => {
302
333
  `Server responded with status: ${response.status} - ${response.statusText}`
303
334
  );
304
335
  }
336
+ declaredMimeType = response.headers.get("content-type");
305
337
  rawData = Buffer.from(await response.arrayBuffer());
306
338
  } catch (error) {
307
339
  if (error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError")) {
@@ -329,16 +361,17 @@ var audioContent = async (input) => {
329
361
  );
330
362
  }
331
363
  const { fileTypeFromBuffer } = await Promise.resolve().then(() => _interopRequireWildcard(require("file-type")));
332
- const mimeType = await fileTypeFromBuffer(rawData);
333
- if (!mimeType || !mimeType.mime.startsWith("audio/")) {
364
+ const detected = await fileTypeFromBuffer(rawData);
365
+ const mimeType = resolveAudioMimeType(_optionalChain([detected, 'optionalAccess', _16 => _16.mime]), declaredMimeType);
366
+ if (!mimeType || !mimeType.startsWith("audio/")) {
334
367
  console.warn(
335
- `Warning: Content may not be a valid audio file. Detected MIME: ${_optionalChain([mimeType, 'optionalAccess', _6 => _6.mime]) || "unknown"}`
368
+ `Warning: Content may not be a valid audio file. Detected MIME: ${mimeType || "unknown"}`
336
369
  );
337
370
  }
338
371
  const base64Data = rawData.toString("base64");
339
372
  return {
340
373
  data: base64Data,
341
- mimeType: _nullishCoalesce(_optionalChain([mimeType, 'optionalAccess', _7 => _7.mime]), () => ( "audio/mpeg")),
374
+ mimeType: _nullishCoalesce(mimeType, () => ( "audio/mpeg")),
342
375
  type: "audio"
343
376
  };
344
377
  } catch (error) {
@@ -369,7 +402,7 @@ var UserError = class extends UnexpectedStateError {
369
402
  };
370
403
  function assertStandardSchema(toolName, schemaName, schema) {
371
404
  const standard = schema["~standard"];
372
- if (typeof _optionalChain([standard, 'optionalAccess', _8 => _8.validate]) === "function") {
405
+ if (typeof _optionalChain([standard, 'optionalAccess', _17 => _17.validate]) === "function") {
373
406
  return;
374
407
  }
375
408
  throw new UserError(
@@ -486,7 +519,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
486
519
  */
487
520
  get sessionId() {
488
521
  if (this.#sessionId === void 0) {
489
- const transportSessionId = _optionalChain([this, 'access', _9 => _9.#server, 'access', _10 => _10.transport, 'optionalAccess', _11 => _11.sessionId]);
522
+ const transportSessionId = _optionalChain([this, 'access', _18 => _18.#server, 'access', _19 => _19.transport, 'optionalAccess', _20 => _20.sessionId]);
490
523
  if (typeof transportSessionId === "string") {
491
524
  this.#sessionId = transportSessionId;
492
525
  }
@@ -510,6 +543,8 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
510
543
  #capabilities = {};
511
544
  #clientCapabilities;
512
545
  #connectionState = "connecting";
546
+ // Caller-supplied transports leave the response mode unspecified.
547
+ #enableJsonResponse;
513
548
  #logger;
514
549
  /**
515
550
  * The minimum level the client asked for with `logging/setLevel`, or
@@ -545,6 +580,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
545
580
  * to interested clients only.
546
581
  */
547
582
  #subscriptions = /* @__PURE__ */ new Set();
583
+ #tools;
548
584
  #transportType;
549
585
  /**
550
586
  * Capabilities this session has already warned about in `#canRefresh`, so a
@@ -553,9 +589,11 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
553
589
  */
554
590
  #unnegotiatedWarnings = /* @__PURE__ */ new Set();
555
591
  #utils;
592
+ #visibleTools = [];
556
593
  constructor({
557
594
  auth,
558
595
  authRequired = false,
596
+ enableJsonResponse,
559
597
  hasTools,
560
598
  icons,
561
599
  instructions,
@@ -580,6 +618,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
580
618
  super();
581
619
  this.#auth = auth;
582
620
  this.#authRequired = authRequired;
621
+ this.#enableJsonResponse = enableJsonResponse;
583
622
  this.#logger = logger;
584
623
  this.#onToolCall = onToolCall;
585
624
  this.#pingConfig = ping;
@@ -587,6 +626,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
587
626
  this.#sessionId = sessionId;
588
627
  this.#stateless = stateless;
589
628
  this.#streamKeepaliveConfig = streamKeepalive;
629
+ this.#tools = tools;
590
630
  this.#transportType = transportType;
591
631
  this.#needsEventLoopFlush = transportType === "httpStream";
592
632
  const supportsTools = _nullishCoalesce(hasTools, () => ( tools.length > 0));
@@ -620,7 +660,9 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
620
660
  this.setupRootsHandlers();
621
661
  this.setupCompleteHandlers();
622
662
  if (supportsTools) {
623
- this.setupToolHandlers(tools);
663
+ this.setupToolHandlers(
664
+ toolsVisibleTo(tools, this.#auth, this.#authRequired)
665
+ );
624
666
  }
625
667
  if (resources.length || resourcesTemplates.length) {
626
668
  for (const resource of resources) {
@@ -741,6 +783,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
741
783
  if (!this.#canRefresh("tools")) {
742
784
  return;
743
785
  }
786
+ this.#tools = tools;
744
787
  this.setupToolHandlers(
745
788
  toolsVisibleTo(tools, this.#auth, this.#authRequired)
746
789
  );
@@ -765,6 +808,11 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
765
808
  */
766
809
  updateAuth(auth) {
767
810
  this.#auth = auth;
811
+ const tools = toolsVisibleTo(this.#tools, auth, this.#authRequired);
812
+ if (tools.length !== this.#visibleTools.length || tools.some((tool, index) => tool !== this.#visibleTools[index])) {
813
+ this.setupToolHandlers(tools);
814
+ this.triggerListChangedNotification("notifications/tools/list_changed");
815
+ }
768
816
  }
769
817
  waitForReady() {
770
818
  if (this.isReady) {
@@ -832,6 +880,19 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
832
880
  }
833
881
  return false;
834
882
  }
883
+ /**
884
+ * When `start()` streams responses, an elicitation goes out on its request's
885
+ * own SSE stream, as the SDK's `extra.sendRequest` does, so it reaches a
886
+ * client that never opened the optional standalone GET stream. A JSON
887
+ * response cannot carry it, and a transport passed to `connect()` does not
888
+ * say which mode it uses, so those keep the session's standalone stream.
889
+ */
890
+ #createElicit(requestId) {
891
+ return (params, options) => this.#server.elicitInput(
892
+ params,
893
+ this.#enableJsonResponse === false ? { ...options, relatedRequestId: requestId } : options
894
+ );
895
+ }
835
896
  /**
836
897
  * Builds the context object passed as the third argument to
837
898
  * `resource.load` / `resourceTemplate.load` / `prompt.load`.
@@ -842,37 +903,37 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
842
903
  * are tied to a tool call's progress token / streaming notification,
843
904
  * which resource and prompt reads do not have.
844
905
  */
845
- #createLoadContext(meta) {
906
+ #createLoadContext(meta, sendNotification, requestId) {
846
907
  return {
847
908
  client: {
848
909
  version: this.#server.getClientVersion()
849
910
  },
850
- elicit: (params, options) => this.#server.elicitInput(params, options),
851
- log: this.#createLog(),
852
- requestId: typeof _optionalChain([meta, 'optionalAccess', _12 => _12.requestId]) === "string" ? meta.requestId : void 0,
911
+ elicit: this.#createElicit(requestId),
912
+ log: this.#createLog(sendNotification),
913
+ requestId: typeof _optionalChain([meta, 'optionalAccess', _21 => _21.requestId]) === "string" ? meta.requestId : void 0,
853
914
  session: this.#auth,
854
915
  sessionId: this.sessionId
855
916
  };
856
917
  }
857
- #createLog() {
918
+ #createLog(sendNotification) {
858
919
  return {
859
920
  debug: (message, context) => {
860
- this.#sendLog("debug", message, context);
921
+ this.#sendLog(sendNotification, "debug", message, context);
861
922
  },
862
923
  error: (message, context) => {
863
- this.#sendLog("error", message, context);
924
+ this.#sendLog(sendNotification, "error", message, context);
864
925
  },
865
926
  info: (message, context) => {
866
- this.#sendLog("info", message, context);
927
+ this.#sendLog(sendNotification, "info", message, context);
867
928
  },
868
929
  warn: (message, context) => {
869
- this.#sendLog("warning", message, context);
930
+ this.#sendLog(sendNotification, "warning", message, context);
870
931
  }
871
932
  };
872
933
  }
873
934
  #formatSchemaIssues(issues) {
874
- return _optionalChain([this, 'access', _13 => _13.#utils, 'optionalAccess', _14 => _14.formatInvalidParamsErrorMessage]) ? this.#utils.formatInvalidParamsErrorMessage(issues) : issues.map((issue) => {
875
- const path = _optionalChain([issue, 'access', _15 => _15.path, 'optionalAccess', _16 => _16.join, 'call', _17 => _17(".")]) || "root";
935
+ return _optionalChain([this, 'access', _22 => _22.#utils, 'optionalAccess', _23 => _23.formatInvalidParamsErrorMessage]) ? this.#utils.formatInvalidParamsErrorMessage(issues) : issues.map((issue) => {
936
+ const path = _optionalChain([issue, 'access', _24 => _24.path, 'optionalAccess', _25 => _25.join, 'call', _26 => _26(".")]) || "root";
876
937
  return `${path}: ${issue.message}`;
877
938
  }).join(", ");
878
939
  }
@@ -894,7 +955,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
894
955
  * is bounded and retried, and the result is announced with `rootsChanged`.
895
956
  */
896
957
  async #loadRoots(streamableHttp) {
897
- if (_optionalChain([this, 'access', _18 => _18.#rootsConfig, 'optionalAccess', _19 => _19.enabled]) === false || !_optionalChain([this, 'access', _20 => _20.#clientCapabilities, 'optionalAccess', _21 => _21.roots, 'optionalAccess', _22 => _22.listChanged]) || typeof this.#server.listRoots !== "function") {
958
+ if (_optionalChain([this, 'access', _27 => _27.#rootsConfig, 'optionalAccess', _28 => _28.enabled]) === false || !_optionalChain([this, 'access', _29 => _29.#clientCapabilities, 'optionalAccess', _30 => _30.roots, 'optionalAccess', _31 => _31.listChanged]) || typeof this.#server.listRoots !== "function") {
898
959
  return;
899
960
  }
900
961
  const maxAttempts = streamableHttp ? 5 : 1;
@@ -904,7 +965,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
904
965
  void 0,
905
966
  streamableHttp ? { timeout: 1e3 } : void 0
906
967
  );
907
- this.#roots = _optionalChain([roots, 'optionalAccess', _23 => _23.roots]) || [];
968
+ this.#roots = _optionalChain([roots, 'optionalAccess', _32 => _32.roots]) || [];
908
969
  if (streamableHttp) {
909
970
  this.emit("rootsChanged", { roots: this.#roots });
910
971
  }
@@ -932,22 +993,23 @@ ${e instanceof Error ? e.stack : JSON.stringify(e)}`
932
993
  }
933
994
  }
934
995
  /**
935
- * `sendLoggingMessage` rejects once the client has hung up, and these four
996
+ * Sending rejects once the client has hung up, and these four
936
997
  * callers are synchronous, so the rejection has nowhere to go. Swallow it the
937
998
  * way every other notification sender in this class does, or a client that
938
999
  * disconnects mid-tool takes the server process down with it.
939
1000
  */
940
- #sendLog(level, message, context) {
1001
+ #sendLog(sendNotification, level, message, context) {
941
1002
  if (this.#loggingLevel && LOGGING_LEVEL_SEVERITY[level] < LOGGING_LEVEL_SEVERITY[this.#loggingLevel]) {
942
1003
  return;
943
1004
  }
944
- this.#server.sendLoggingMessage({
1005
+ const params = {
945
1006
  data: {
946
1007
  context,
947
1008
  message
948
1009
  },
949
1010
  level
950
- }).catch((error) => {
1011
+ };
1012
+ sendNotification({ method: "notifications/message", params }).catch(() => this.#server.sendLoggingMessage(params)).catch((error) => {
951
1013
  this.#logger.error(
952
1014
  `[FastMCP error] failed to send ${level} log notification.
953
1015
 
@@ -1041,7 +1103,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1041
1103
  */
1042
1104
  #startStreamKeepalive(extra, toolName) {
1043
1105
  const config = this.#streamKeepaliveConfig;
1044
- if (!_optionalChain([config, 'optionalAccess', _24 => _24.enabled])) {
1106
+ if (!_optionalChain([config, 'optionalAccess', _33 => _33.enabled])) {
1045
1107
  return () => {
1046
1108
  };
1047
1109
  }
@@ -1061,9 +1123,9 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1061
1123
  );
1062
1124
  });
1063
1125
  }, intervalMs);
1064
- _optionalChain([timer, 'access', _25 => _25.unref, 'optionalCall', _26 => _26()]);
1126
+ _optionalChain([timer, 'access', _34 => _34.unref, 'optionalCall', _35 => _35()]);
1065
1127
  const stop = () => clearInterval(timer);
1066
- _optionalChain([extra, 'access', _27 => _27.signal, 'optionalAccess', _28 => _28.addEventListener, 'call', _29 => _29("abort", stop, { once: true })]);
1128
+ _optionalChain([extra, 'access', _36 => _36.signal, 'optionalAccess', _37 => _37.addEventListener, 'call', _38 => _38("abort", stop, { once: true })]);
1067
1129
  return stop;
1068
1130
  }
1069
1131
  async #validateStructuredContent(tool, value, toolName) {
@@ -1258,54 +1320,61 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1258
1320
  prompts: cachedPromptsList
1259
1321
  };
1260
1322
  });
1261
- this.#server.setRequestHandler(_typesjs.GetPromptRequestSchema, async (request) => {
1262
- const prompt = this.#prompts.get(request.params.name);
1263
- if (!prompt) {
1264
- throw new (0, _typesjs.McpError)(
1265
- _typesjs.ErrorCode.InvalidParams,
1266
- `Unknown prompt: ${request.params.name}`
1267
- );
1268
- }
1269
- const args = request.params.arguments;
1270
- for (const arg of _nullishCoalesce(prompt.arguments, () => ( []))) {
1271
- if (arg.required && !(args && Object.hasOwn(args, arg.name))) {
1323
+ this.#server.setRequestHandler(
1324
+ _typesjs.GetPromptRequestSchema,
1325
+ async (request, extra) => {
1326
+ const prompt = this.#prompts.get(request.params.name);
1327
+ if (!prompt) {
1272
1328
  throw new (0, _typesjs.McpError)(
1273
1329
  _typesjs.ErrorCode.InvalidParams,
1274
- `Prompt '${request.params.name}' requires argument '${arg.name}': ${arg.description || "No description provided"}`
1330
+ `Unknown prompt: ${request.params.name}`
1275
1331
  );
1276
1332
  }
1333
+ const args = request.params.arguments;
1334
+ for (const arg of _nullishCoalesce(prompt.arguments, () => ( []))) {
1335
+ if (arg.required && !(args && Object.hasOwn(args, arg.name))) {
1336
+ throw new (0, _typesjs.McpError)(
1337
+ _typesjs.ErrorCode.InvalidParams,
1338
+ `Prompt '${request.params.name}' requires argument '${arg.name}': ${arg.description || "No description provided"}`
1339
+ );
1340
+ }
1341
+ }
1342
+ let result;
1343
+ try {
1344
+ result = await prompt.load(
1345
+ _nullishCoalesce(args, () => ( {})),
1346
+ this.#auth,
1347
+ this.#createLoadContext(
1348
+ _optionalChain([request, 'access', _39 => _39.params, 'optionalAccess', _40 => _40._meta]),
1349
+ extra.sendNotification,
1350
+ extra.requestId
1351
+ )
1352
+ );
1353
+ } catch (error) {
1354
+ const errorMessage = error instanceof Error ? error.message : String(error);
1355
+ throw new (0, _typesjs.McpError)(
1356
+ _typesjs.ErrorCode.InternalError,
1357
+ `Failed to load prompt '${request.params.name}': ${errorMessage}`
1358
+ );
1359
+ }
1360
+ if (typeof result === "string") {
1361
+ return {
1362
+ description: prompt.description,
1363
+ messages: [
1364
+ {
1365
+ content: { text: result, type: "text" },
1366
+ role: "user"
1367
+ }
1368
+ ]
1369
+ };
1370
+ } else {
1371
+ return {
1372
+ description: prompt.description,
1373
+ messages: result.messages
1374
+ };
1375
+ }
1277
1376
  }
1278
- let result;
1279
- try {
1280
- result = await prompt.load(
1281
- _nullishCoalesce(args, () => ( {})),
1282
- this.#auth,
1283
- this.#createLoadContext(_optionalChain([request, 'access', _30 => _30.params, 'optionalAccess', _31 => _31._meta]))
1284
- );
1285
- } catch (error) {
1286
- const errorMessage = error instanceof Error ? error.message : String(error);
1287
- throw new (0, _typesjs.McpError)(
1288
- _typesjs.ErrorCode.InternalError,
1289
- `Failed to load prompt '${request.params.name}': ${errorMessage}`
1290
- );
1291
- }
1292
- if (typeof result === "string") {
1293
- return {
1294
- description: prompt.description,
1295
- messages: [
1296
- {
1297
- content: { text: result, type: "text" },
1298
- role: "user"
1299
- }
1300
- ]
1301
- };
1302
- } else {
1303
- return {
1304
- description: prompt.description,
1305
- messages: result.messages
1306
- };
1307
- }
1308
- });
1377
+ );
1309
1378
  }
1310
1379
  setupResourceHandlers() {
1311
1380
  let cachedResourcesList = null;
@@ -1329,7 +1398,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1329
1398
  });
1330
1399
  this.#server.setRequestHandler(
1331
1400
  _typesjs.ReadResourceRequestSchema,
1332
- async (request) => {
1401
+ async (request, extra) => {
1333
1402
  if ("uri" in request.params) {
1334
1403
  const resource = this.#resources.get(request.params.uri);
1335
1404
  if (!resource) {
@@ -1345,7 +1414,11 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1345
1414
  const result = await resourceTemplate.load(
1346
1415
  match,
1347
1416
  this.#auth,
1348
- this.#createLoadContext(_optionalChain([request, 'access', _32 => _32.params, 'optionalAccess', _33 => _33._meta]))
1417
+ this.#createLoadContext(
1418
+ _optionalChain([request, 'access', _41 => _41.params, 'optionalAccess', _42 => _42._meta]),
1419
+ extra.sendNotification,
1420
+ extra.requestId
1421
+ )
1349
1422
  );
1350
1423
  const resources = Array.isArray(result) ? result : [result];
1351
1424
  return {
@@ -1371,7 +1444,11 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1371
1444
  try {
1372
1445
  maybeArrayResult = await resource.load(
1373
1446
  this.#auth,
1374
- this.#createLoadContext(_optionalChain([request, 'access', _34 => _34.params, 'optionalAccess', _35 => _35._meta]))
1447
+ this.#createLoadContext(
1448
+ _optionalChain([request, 'access', _43 => _43.params, 'optionalAccess', _44 => _44._meta]),
1449
+ extra.sendNotification,
1450
+ extra.requestId
1451
+ )
1375
1452
  );
1376
1453
  } catch (error) {
1377
1454
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -1434,7 +1511,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1434
1511
  );
1435
1512
  }
1436
1513
  setupRootsHandlers() {
1437
- if (_optionalChain([this, 'access', _36 => _36.#rootsConfig, 'optionalAccess', _37 => _37.enabled]) === false) {
1514
+ if (_optionalChain([this, 'access', _45 => _45.#rootsConfig, 'optionalAccess', _46 => _46.enabled]) === false) {
1438
1515
  this.#logger.debug(
1439
1516
  "[FastMCP debug] roots capability explicitly disabled via config"
1440
1517
  );
@@ -1471,6 +1548,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1471
1548
  }
1472
1549
  }
1473
1550
  setupToolHandlers(tools) {
1551
+ this.#visibleTools = tools;
1474
1552
  const toolsMap = new Map(tools.map((tool) => [tool.name, tool]));
1475
1553
  let cachedToolsList = null;
1476
1554
  this.#server.setRequestHandler(_typesjs.ListToolsRequestSchema, async () => {
@@ -1484,7 +1562,9 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1484
1562
  return {
1485
1563
  annotations: tool.annotations,
1486
1564
  description: tool.description,
1487
- inputSchema: tool.parameters ? _chunkO22SYZMCcjs.strictInputSchema.call(void 0, await _xsschema.toJsonSchema.call(void 0, tool.parameters)) : {
1565
+ inputSchema: tool.parameters ? _chunkMPFPOZ2Hcjs.strictInputSchema.call(void 0,
1566
+ tool.parameters["~standard"].vendor === "zod" && "_zod" in tool.parameters ? _chunkMPFPOZ2Hcjs.zodInputSchema.call(void 0, tool.parameters, "draft-7") : await _xsschema.toJsonSchema.call(void 0, tool.parameters)
1567
+ ) : {
1488
1568
  additionalProperties: false,
1489
1569
  properties: {},
1490
1570
  type: "object"
@@ -1528,7 +1608,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1528
1608
  }
1529
1609
  args = parsed.value;
1530
1610
  }
1531
- const progressToken = _optionalChain([request, 'access', _38 => _38.params, 'optionalAccess', _39 => _39._meta, 'optionalAccess', _40 => _40.progressToken]);
1611
+ const progressToken = _optionalChain([request, 'access', _47 => _47.params, 'optionalAccess', _48 => _48._meta, 'optionalAccess', _49 => _49.progressToken]);
1532
1612
  let result;
1533
1613
  try {
1534
1614
  const reportProgress = async (progress) => {
@@ -1553,7 +1633,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1553
1633
  );
1554
1634
  }
1555
1635
  };
1556
- const log = this.#createLog();
1636
+ const log = this.#createLog(extra.sendNotification);
1557
1637
  const streamContent = async (content) => {
1558
1638
  const contentArray = Array.isArray(content) ? content : [content];
1559
1639
  try {
@@ -1593,10 +1673,10 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1593
1673
  client: {
1594
1674
  version: this.#server.getClientVersion()
1595
1675
  },
1596
- elicit: (params, options) => this.#server.elicitInput(params, options),
1676
+ elicit: this.#createElicit(extra.requestId),
1597
1677
  log,
1598
1678
  reportProgress,
1599
- requestId: typeof _optionalChain([request, 'access', _41 => _41.params, 'optionalAccess', _42 => _42._meta, 'optionalAccess', _43 => _43.requestId]) === "string" ? request.params._meta.requestId : void 0,
1679
+ requestId: typeof _optionalChain([request, 'access', _50 => _50.params, 'optionalAccess', _51 => _51._meta, 'optionalAccess', _52 => _52.requestId]) === "string" ? request.params._meta.requestId : void 0,
1600
1680
  session: this.#auth,
1601
1681
  sessionId: this.sessionId,
1602
1682
  signal,
@@ -1738,7 +1818,7 @@ function normalizePath(path) {
1738
1818
  return path.startsWith("/") ? path : `/${path}`;
1739
1819
  }
1740
1820
  function parseBasicAuthHeader(authHeader) {
1741
- const basicMatch = _optionalChain([authHeader, 'optionalAccess', _44 => _44.match, 'call', _45 => _45(/^Basic\s+(.+)$/)]);
1821
+ const basicMatch = _optionalChain([authHeader, 'optionalAccess', _53 => _53.match, 'call', _54 => _54(/^Basic\s+(.+)$/)]);
1742
1822
  if (!basicMatch) return null;
1743
1823
  try {
1744
1824
  const credentials = Buffer.from(basicMatch[1], "base64").toString("utf-8");
@@ -2217,7 +2297,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2217
2297
  roots: this.#options.roots,
2218
2298
  streamKeepalive: this.#options.streamKeepalive,
2219
2299
  title: this.#options.title,
2220
- tools: toolsVisibleTo(this.#tools, auth, authRequired),
2300
+ tools: this.#tools,
2221
2301
  transportType: "stdio",
2222
2302
  utils: this.#options.utils,
2223
2303
  version: this.#options.version,
@@ -2273,7 +2353,12 @@ var FastMCP = class extends FastMCPEventEmitter {
2273
2353
  auth = this.#requireAuthenticated(await authenticate(request));
2274
2354
  }
2275
2355
  const sessionId = Array.isArray(request.headers["mcp-session-id"]) ? request.headers["mcp-session-id"][0] : request.headers["mcp-session-id"];
2276
- return this.#createSession(auth, sessionId, true);
2356
+ return this.#createSession(
2357
+ auth,
2358
+ sessionId,
2359
+ true,
2360
+ httpConfig.enableJsonResponse
2361
+ );
2277
2362
  },
2278
2363
  enableJsonResponse: httpConfig.enableJsonResponse,
2279
2364
  eventStore: httpConfig.eventStore,
@@ -2315,7 +2400,12 @@ var FastMCP = class extends FastMCPEventEmitter {
2315
2400
  auth = this.#requireAuthenticated(await authenticate(request));
2316
2401
  }
2317
2402
  const sessionId = Array.isArray(request.headers["mcp-session-id"]) ? request.headers["mcp-session-id"][0] : request.headers["mcp-session-id"];
2318
- return this.#createSession(auth, sessionId);
2403
+ return this.#createSession(
2404
+ auth,
2405
+ sessionId,
2406
+ false,
2407
+ httpConfig.enableJsonResponse
2408
+ );
2319
2409
  },
2320
2410
  enableJsonResponse: httpConfig.enableJsonResponse,
2321
2411
  eventStore: httpConfig.eventStore,
@@ -2384,9 +2474,9 @@ var FastMCP = class extends FastMCPEventEmitter {
2384
2474
  const originalOnClose = transport.onclose;
2385
2475
  transport.onclose = () => {
2386
2476
  closed = true;
2387
- _optionalChain([onClose, 'optionalCall', _46 => _46()]);
2477
+ _optionalChain([onClose, 'optionalCall', _55 => _55()]);
2388
2478
  this.#removeSession(session);
2389
- _optionalChain([originalOnClose, 'optionalCall', _47 => _47()]);
2479
+ _optionalChain([originalOnClose, 'optionalCall', _56 => _56()]);
2390
2480
  };
2391
2481
  await session.connect(transport);
2392
2482
  if (closed) {
@@ -2404,7 +2494,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2404
2494
  * Creates a new FastMCPSession instance with the current configuration.
2405
2495
  * Used both for regular sessions and stateless requests.
2406
2496
  */
2407
- #createSession(auth, sessionId, stateless = false) {
2497
+ #createSession(auth, sessionId, stateless = false, enableJsonResponse) {
2408
2498
  if (auth && typeof auth === "object" && "authenticated" in auth && !auth.authenticated) {
2409
2499
  const errorMessage = "error" in auth && typeof auth.error === "string" ? auth.error : "Authentication failed";
2410
2500
  throw this.#createUnauthorizedResponse(errorMessage);
@@ -2413,6 +2503,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2413
2503
  return new FastMCPSession({
2414
2504
  auth,
2415
2505
  authRequired,
2506
+ enableJsonResponse,
2416
2507
  hasTools: this.#tools.length > 0,
2417
2508
  icons: this.#options.icons,
2418
2509
  instructions: this.#options.instructions,
@@ -2428,7 +2519,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2428
2519
  stateless,
2429
2520
  streamKeepalive: this.#options.streamKeepalive,
2430
2521
  title: this.#options.title,
2431
- tools: toolsVisibleTo(this.#tools, auth, authRequired),
2522
+ tools: this.#tools,
2432
2523
  transportType: "httpStream",
2433
2524
  utils: this.#options.utils,
2434
2525
  version: this.#options.version,
@@ -2450,7 +2541,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2450
2541
  */
2451
2542
  #createUnauthorizedResponse(message) {
2452
2543
  const oauth = this.#options.oauth;
2453
- const resource = _optionalChain([oauth, 'optionalAccess', _48 => _48.enabled]) ? _optionalChain([oauth, 'access', _49 => _49.protectedResource, 'optionalAccess', _50 => _50.resource]) : void 0;
2544
+ const resource = _optionalChain([oauth, 'optionalAccess', _57 => _57.enabled]) ? _optionalChain([oauth, 'access', _58 => _58.protectedResource, 'optionalAccess', _59 => _59.resource]) : void 0;
2454
2545
  const wwwAuthenticateParts = [
2455
2546
  'error="invalid_token"',
2456
2547
  `error_description="${message.replace(/"/g, '\\"')}"`
@@ -2589,7 +2680,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2589
2680
  }
2590
2681
  }
2591
2682
  const oauthConfig = this.#options.oauth;
2592
- if (_optionalChain([oauthConfig, 'optionalAccess', _51 => _51.enabled]) && req.method === "GET") {
2683
+ if (_optionalChain([oauthConfig, 'optionalAccess', _60 => _60.enabled]) && req.method === "GET") {
2593
2684
  const url2 = new URL(req.url || "", `http://${host}`);
2594
2685
  const authorizationServerMetadataPath = joinPaths(
2595
2686
  "",
@@ -2623,8 +2714,8 @@ var FastMCP = class extends FastMCPEventEmitter {
2623
2714
  }
2624
2715
  }
2625
2716
  }
2626
- const oauthProxy = _optionalChain([oauthConfig, 'optionalAccess', _52 => _52.proxy]);
2627
- if (oauthProxy && _optionalChain([oauthConfig, 'optionalAccess', _53 => _53.enabled])) {
2717
+ const oauthProxy = _optionalChain([oauthConfig, 'optionalAccess', _61 => _61.proxy]);
2718
+ if (oauthProxy && _optionalChain([oauthConfig, 'optionalAccess', _62 => _62.enabled])) {
2628
2719
  const url2 = new URL(req.url || "", `http://${host}`);
2629
2720
  const oauthPath = basePathRelativePath;
2630
2721
  try {
@@ -2677,7 +2768,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2677
2768
  const statusCode = error.statusCode || 400;
2678
2769
  res.writeHead(statusCode, OAUTH_CREDENTIAL_RESPONSE_HEADERS).end(
2679
2770
  JSON.stringify(
2680
- _optionalChain([error, 'access', _54 => _54.toJSON, 'optionalCall', _55 => _55()]) || {
2771
+ _optionalChain([error, 'access', _63 => _63.toJSON, 'optionalCall', _64 => _64()]) || {
2681
2772
  error: "invalid_request"
2682
2773
  }
2683
2774
  )
@@ -2704,7 +2795,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2704
2795
  } catch (error) {
2705
2796
  res.writeHead(400, { "Content-Type": "application/json" }).end(
2706
2797
  JSON.stringify(
2707
- _optionalChain([error, 'access', _56 => _56.toJSON, 'optionalCall', _57 => _57()]) || {
2798
+ _optionalChain([error, 'access', _65 => _65.toJSON, 'optionalCall', _66 => _66()]) || {
2708
2799
  error: "invalid_request"
2709
2800
  }
2710
2801
  )
@@ -2726,7 +2817,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2726
2817
  } catch (error) {
2727
2818
  res.writeHead(400, { "Content-Type": "application/json" }).end(
2728
2819
  JSON.stringify(
2729
- _optionalChain([error, 'access', _58 => _58.toJSON, 'optionalCall', _59 => _59()]) || {
2820
+ _optionalChain([error, 'access', _67 => _67.toJSON, 'optionalCall', _68 => _68()]) || {
2730
2821
  error: "server_error"
2731
2822
  }
2732
2823
  )
@@ -2795,7 +2886,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2795
2886
  } catch (error) {
2796
2887
  res.writeHead(400, { "Content-Type": "application/json" }).end(
2797
2888
  JSON.stringify(
2798
- _optionalChain([error, 'access', _60 => _60.toJSON, 'optionalCall', _61 => _61()]) || {
2889
+ _optionalChain([error, 'access', _69 => _69.toJSON, 'optionalCall', _70 => _70()]) || {
2799
2890
  error: "server_error"
2800
2891
  }
2801
2892
  )
@@ -2853,8 +2944,8 @@ var FastMCP = class extends FastMCPEventEmitter {
2853
2944
  const basicAuth = parseBasicAuthHeader(
2854
2945
  req.headers.authorization
2855
2946
  );
2856
- const clientId = _optionalChain([basicAuth, 'optionalAccess', _62 => _62.clientId]) || params.get("client_id") || "";
2857
- const clientSecret = _nullishCoalesce(_nullishCoalesce(_optionalChain([basicAuth, 'optionalAccess', _63 => _63.clientSecret]), () => ( params.get("client_secret"))), () => ( void 0));
2947
+ const clientId = _optionalChain([basicAuth, 'optionalAccess', _71 => _71.clientId]) || params.get("client_id") || "";
2948
+ const clientSecret = _nullishCoalesce(_nullishCoalesce(_optionalChain([basicAuth, 'optionalAccess', _72 => _72.clientSecret]), () => ( params.get("client_secret"))), () => ( void 0));
2858
2949
  let response;
2859
2950
  if (grantType === "authorization_code") {
2860
2951
  response = await oauthProxy.exchangeAuthorizationCode({
@@ -2884,7 +2975,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2884
2975
  const statusCode = error.statusCode || 400;
2885
2976
  res.writeHead(statusCode, OAUTH_CREDENTIAL_RESPONSE_HEADERS).end(
2886
2977
  JSON.stringify(
2887
- _optionalChain([error, 'access', _64 => _64.toJSON, 'optionalCall', _65 => _65()]) || {
2978
+ _optionalChain([error, 'access', _73 => _73.toJSON, 'optionalCall', _74 => _74()]) || {
2888
2979
  error: "invalid_request"
2889
2980
  }
2890
2981
  )
@@ -2910,7 +3001,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2910
3001
  * regardless (RFC 7235), so no config is needed just to get the header.
2911
3002
  */
2912
3003
  #httpStreamOAuthConfig() {
2913
- const resource = _optionalChain([this, 'access', _66 => _66.#options, 'access', _67 => _67.oauth, 'optionalAccess', _68 => _68.enabled]) ? _optionalChain([this, 'access', _69 => _69.#options, 'access', _70 => _70.oauth, 'access', _71 => _71.protectedResource, 'optionalAccess', _72 => _72.resource]) : void 0;
3004
+ const resource = _optionalChain([this, 'access', _75 => _75.#options, 'access', _76 => _76.oauth, 'optionalAccess', _77 => _77.enabled]) ? _optionalChain([this, 'access', _78 => _78.#options, 'access', _79 => _79.oauth, 'access', _80 => _80.protectedResource, 'optionalAccess', _81 => _81.resource]) : void 0;
2914
3005
  if (!resource) {
2915
3006
  return {};
2916
3007
  }
@@ -3018,24 +3109,24 @@ var FastMCP = class extends FastMCPEventEmitter {
3018
3109
  const envBasePath = process.env.FASTMCP_BASE_PATH;
3019
3110
  const envStateless = process.env.FASTMCP_STATELESS;
3020
3111
  const envHost = process.env.FASTMCP_HOST;
3021
- const transportType = _optionalChain([overrides, 'optionalAccess', _73 => _73.transportType]) || parseTransportSetting(transportArg, "--transport") || parseTransportSetting(envTransport, "FASTMCP_TRANSPORT") || "stdio";
3112
+ const transportType = _optionalChain([overrides, 'optionalAccess', _82 => _82.transportType]) || parseTransportSetting(transportArg, "--transport") || parseTransportSetting(envTransport, "FASTMCP_TRANSPORT") || "stdio";
3022
3113
  if (transportType === "httpStream") {
3023
3114
  const port = parseInt(
3024
- _optionalChain([overrides, 'optionalAccess', _74 => _74.httpStream, 'optionalAccess', _75 => _75.port, 'optionalAccess', _76 => _76.toString, 'call', _77 => _77()]) || portArg || envPort || "8080"
3115
+ _optionalChain([overrides, 'optionalAccess', _83 => _83.httpStream, 'optionalAccess', _84 => _84.port, 'optionalAccess', _85 => _85.toString, 'call', _86 => _86()]) || portArg || envPort || "8080"
3025
3116
  );
3026
- const host = _optionalChain([overrides, 'optionalAccess', _78 => _78.httpStream, 'optionalAccess', _79 => _79.host]) || hostArg || envHost || "localhost";
3027
- const endpoint = _optionalChain([overrides, 'optionalAccess', _80 => _80.httpStream, 'optionalAccess', _81 => _81.endpoint]) || endpointArg || envEndpoint || "/mcp";
3117
+ const host = _optionalChain([overrides, 'optionalAccess', _87 => _87.httpStream, 'optionalAccess', _88 => _88.host]) || hostArg || envHost || "localhost";
3118
+ const endpoint = _optionalChain([overrides, 'optionalAccess', _89 => _89.httpStream, 'optionalAccess', _90 => _90.endpoint]) || endpointArg || envEndpoint || "/mcp";
3028
3119
  const basePath = normalizeBasePath(
3029
- _optionalChain([overrides, 'optionalAccess', _82 => _82.httpStream, 'optionalAccess', _83 => _83.basePath]) || basePathArg || envBasePath
3120
+ _optionalChain([overrides, 'optionalAccess', _91 => _91.httpStream, 'optionalAccess', _92 => _92.basePath]) || basePathArg || envBasePath
3030
3121
  );
3031
- const enableJsonResponse = _optionalChain([overrides, 'optionalAccess', _84 => _84.httpStream, 'optionalAccess', _85 => _85.enableJsonResponse]) || false;
3032
- const stateless = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([overrides, 'optionalAccess', _86 => _86.httpStream, 'optionalAccess', _87 => _87.stateless]), () => ( // A bare `--stateless` means `--stateless true`.
3122
+ const enableJsonResponse = _optionalChain([overrides, 'optionalAccess', _93 => _93.httpStream, 'optionalAccess', _94 => _94.enableJsonResponse]) || false;
3123
+ const stateless = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([overrides, 'optionalAccess', _95 => _95.httpStream, 'optionalAccess', _96 => _96.stateless]), () => ( // A bare `--stateless` means `--stateless true`.
3033
3124
  (statelessArg === "" ? true : parseBooleanSetting(statelessArg, "--stateless")))), () => ( parseBooleanSetting(envStateless, "FASTMCP_STATELESS"))), () => ( false));
3034
- const cors = _optionalChain([overrides, 'optionalAccess', _88 => _88.httpStream, 'optionalAccess', _89 => _89.cors]);
3035
- const eventStore = _optionalChain([overrides, 'optionalAccess', _90 => _90.httpStream, 'optionalAccess', _91 => _91.eventStore]);
3036
- const sslCa = _optionalChain([overrides, 'optionalAccess', _92 => _92.httpStream, 'optionalAccess', _93 => _93.sslCa]);
3037
- const sslCert = _optionalChain([overrides, 'optionalAccess', _94 => _94.httpStream, 'optionalAccess', _95 => _95.sslCert]);
3038
- const sslKey = _optionalChain([overrides, 'optionalAccess', _96 => _96.httpStream, 'optionalAccess', _97 => _97.sslKey]);
3125
+ const cors = _optionalChain([overrides, 'optionalAccess', _97 => _97.httpStream, 'optionalAccess', _98 => _98.cors]);
3126
+ const eventStore = _optionalChain([overrides, 'optionalAccess', _99 => _99.httpStream, 'optionalAccess', _100 => _100.eventStore]);
3127
+ const sslCa = _optionalChain([overrides, 'optionalAccess', _101 => _101.httpStream, 'optionalAccess', _102 => _102.sslCa]);
3128
+ const sslCert = _optionalChain([overrides, 'optionalAccess', _103 => _103.httpStream, 'optionalAccess', _104 => _104.sslCert]);
3129
+ const sslKey = _optionalChain([overrides, 'optionalAccess', _105 => _105.httpStream, 'optionalAccess', _106 => _106.sslKey]);
3039
3130
  return {
3040
3131
  httpStream: {
3041
3132
  basePath,
@@ -3127,7 +3218,7 @@ var FastMCP = class extends FastMCPEventEmitter {
3127
3218
  */
3128
3219
  #useEndpointAsResource(endpoint) {
3129
3220
  const oauth = this.#options.oauth;
3130
- if (this.#providerResourceBase === void 0 || !_optionalChain([oauth, 'optionalAccess', _98 => _98.protectedResource]))
3221
+ if (this.#providerResourceBase === void 0 || !_optionalChain([oauth, 'optionalAccess', _107 => _107.protectedResource]))
3131
3222
  return;
3132
3223
  this.#options = {
3133
3224
  ...this.#options,
@@ -3156,4 +3247,4 @@ var FastMCP = class extends FastMCPEventEmitter {
3156
3247
 
3157
3248
 
3158
3249
  exports.DiscoveryDocumentCache = DiscoveryDocumentCache; exports.jsonSchemaAdapter = jsonSchemaAdapter; exports.MEDIA_FETCH_TIMEOUT_MS = MEDIA_FETCH_TIMEOUT_MS; exports.imageContent = imageContent; exports.audioContent = audioContent; exports.FastMCPError = FastMCPError; exports.SessionError = SessionError; exports.UnexpectedStateError = UnexpectedStateError; exports.UserError = UserError; exports.ServerState = ServerState; exports.FastMCPSession = FastMCPSession; exports.FastMCP = FastMCP;
3159
- //# sourceMappingURL=chunk-MI6R72UA.cjs.map
3250
+ //# sourceMappingURL=chunk-TBMRFQ6M.cjs.map