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.
package/README.md CHANGED
@@ -1286,6 +1286,11 @@ after `logging/setLevel` with `error`, `log.debug` and `log.info` reach nobody.
1286
1286
  Until a client asks, every level is sent. The level in force is readable as
1287
1287
  [`session.loggingLevel`](#logginglevel).
1288
1288
 
1289
+ Each message travels on the stream of the request that logged it, so logging
1290
+ works in `stateless` mode too. With `httpStream.enableJsonResponse`, which
1291
+ answers each request with a single JSON body, messages logged while a request
1292
+ runs are dropped.
1293
+
1289
1294
  #### Errors
1290
1295
 
1291
1296
  The errors that are meant to be shown to the user should be thrown as `UserError` instances:
package/dist/FastMCP.cjs CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
 
13
13
 
14
- var _chunkMI6R72UAcjs = require('./chunk-MI6R72UA.cjs');
14
+ var _chunkTBMRFQ6Mcjs = require('./chunk-TBMRFQ6M.cjs');
15
15
 
16
16
 
17
17
 
@@ -25,7 +25,7 @@ var _chunkMI6R72UAcjs = require('./chunk-MI6R72UA.cjs');
25
25
 
26
26
 
27
27
  var _chunkC7TBI7A5cjs = require('./chunk-C7TBI7A5.cjs');
28
- require('./chunk-O22SYZMC.cjs');
28
+ require('./chunk-MPFPOZ2H.cjs');
29
29
 
30
30
 
31
31
 
@@ -50,5 +50,5 @@ require('./chunk-O22SYZMC.cjs');
50
50
 
51
51
 
52
52
 
53
- exports.AuthProvider = _chunkC7TBI7A5cjs.AuthProvider; exports.AzureProvider = _chunkC7TBI7A5cjs.AzureProvider; exports.DiscoveryDocumentCache = _chunkMI6R72UAcjs.DiscoveryDocumentCache; exports.FastMCP = _chunkMI6R72UAcjs.FastMCP; exports.FastMCPError = _chunkMI6R72UAcjs.FastMCPError; exports.FastMCPSession = _chunkMI6R72UAcjs.FastMCPSession; exports.GitHubProvider = _chunkC7TBI7A5cjs.GitHubProvider; exports.GoogleProvider = _chunkC7TBI7A5cjs.GoogleProvider; exports.MEDIA_FETCH_TIMEOUT_MS = _chunkMI6R72UAcjs.MEDIA_FETCH_TIMEOUT_MS; exports.OAuthProvider = _chunkC7TBI7A5cjs.OAuthProvider; exports.ServerState = _chunkMI6R72UAcjs.ServerState; exports.SessionError = _chunkMI6R72UAcjs.SessionError; exports.UnexpectedStateError = _chunkMI6R72UAcjs.UnexpectedStateError; exports.UserError = _chunkMI6R72UAcjs.UserError; exports.audioContent = _chunkMI6R72UAcjs.audioContent; exports.getAuthSession = _chunkC7TBI7A5cjs.getAuthSession; exports.imageContent = _chunkMI6R72UAcjs.imageContent; exports.jsonSchemaAdapter = _chunkMI6R72UAcjs.jsonSchemaAdapter; exports.requireAll = _chunkC7TBI7A5cjs.requireAll; exports.requireAny = _chunkC7TBI7A5cjs.requireAny; exports.requireAuth = _chunkC7TBI7A5cjs.requireAuth; exports.requireRole = _chunkC7TBI7A5cjs.requireRole; exports.requireScopes = _chunkC7TBI7A5cjs.requireScopes;
53
+ exports.AuthProvider = _chunkC7TBI7A5cjs.AuthProvider; exports.AzureProvider = _chunkC7TBI7A5cjs.AzureProvider; exports.DiscoveryDocumentCache = _chunkTBMRFQ6Mcjs.DiscoveryDocumentCache; exports.FastMCP = _chunkTBMRFQ6Mcjs.FastMCP; exports.FastMCPError = _chunkTBMRFQ6Mcjs.FastMCPError; exports.FastMCPSession = _chunkTBMRFQ6Mcjs.FastMCPSession; exports.GitHubProvider = _chunkC7TBI7A5cjs.GitHubProvider; exports.GoogleProvider = _chunkC7TBI7A5cjs.GoogleProvider; exports.MEDIA_FETCH_TIMEOUT_MS = _chunkTBMRFQ6Mcjs.MEDIA_FETCH_TIMEOUT_MS; exports.OAuthProvider = _chunkC7TBI7A5cjs.OAuthProvider; exports.ServerState = _chunkTBMRFQ6Mcjs.ServerState; exports.SessionError = _chunkTBMRFQ6Mcjs.SessionError; exports.UnexpectedStateError = _chunkTBMRFQ6Mcjs.UnexpectedStateError; exports.UserError = _chunkTBMRFQ6Mcjs.UserError; exports.audioContent = _chunkTBMRFQ6Mcjs.audioContent; exports.getAuthSession = _chunkC7TBI7A5cjs.getAuthSession; exports.imageContent = _chunkTBMRFQ6Mcjs.imageContent; exports.jsonSchemaAdapter = _chunkTBMRFQ6Mcjs.jsonSchemaAdapter; exports.requireAll = _chunkC7TBI7A5cjs.requireAll; exports.requireAny = _chunkC7TBI7A5cjs.requireAny; exports.requireAuth = _chunkC7TBI7A5cjs.requireAuth; exports.requireRole = _chunkC7TBI7A5cjs.requireRole; exports.requireScopes = _chunkC7TBI7A5cjs.requireScopes;
54
54
  //# sourceMappingURL=FastMCP.cjs.map
@@ -925,7 +925,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
925
925
  */
926
926
  get sessionId(): string | undefined;
927
927
  set sessionId(value: string | undefined);
928
- constructor({ auth, authRequired, hasTools, icons, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, title, tools, transportType, utils, version, websiteUrl, }: {
928
+ constructor({ auth, authRequired, enableJsonResponse, hasTools, icons, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, title, tools, transportType, utils, version, websiteUrl, }: {
929
929
  auth?: T;
930
930
  /**
931
931
  * Whether the server authenticates its sessions (`authenticate` is
@@ -933,6 +933,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
933
933
  * gated by `canAccess` (see `toolsVisibleTo`).
934
934
  */
935
935
  authRequired?: boolean;
936
+ enableJsonResponse?: boolean;
936
937
  /**
937
938
  * Whether the server has any tools at all, including ones this session's
938
939
  * `canAccess` filtering removed from `tools`. Defaults to `tools.length > 0`.
package/dist/FastMCP.d.ts CHANGED
@@ -925,7 +925,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
925
925
  */
926
926
  get sessionId(): string | undefined;
927
927
  set sessionId(value: string | undefined);
928
- constructor({ auth, authRequired, hasTools, icons, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, title, tools, transportType, utils, version, websiteUrl, }: {
928
+ constructor({ auth, authRequired, enableJsonResponse, hasTools, icons, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, title, tools, transportType, utils, version, websiteUrl, }: {
929
929
  auth?: T;
930
930
  /**
931
931
  * Whether the server authenticates its sessions (`authenticate` is
@@ -933,6 +933,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
933
933
  * gated by `canAccess` (see `toolsVisibleTo`).
934
934
  */
935
935
  authRequired?: boolean;
936
+ enableJsonResponse?: boolean;
936
937
  /**
937
938
  * Whether the server has any tools at all, including ones this session's
938
939
  * `canAccess` filtering removed from `tools`. Defaults to `tools.length > 0`.
package/dist/FastMCP.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  audioContent,
12
12
  imageContent,
13
13
  jsonSchemaAdapter
14
- } from "./chunk-OUD755CE.js";
14
+ } from "./chunk-7WNI6AGD.js";
15
15
  import {
16
16
  AuthProvider,
17
17
  AzureProvider,
@@ -25,7 +25,7 @@ import {
25
25
  requireRole,
26
26
  requireScopes
27
27
  } from "./chunk-CA2EPNZF.js";
28
- import "./chunk-UMDUIBFW.js";
28
+ import "./chunk-YZ5QEHBX.js";
29
29
  export {
30
30
  AuthProvider,
31
31
  AzureProvider,
@@ -2,8 +2,9 @@ import {
2
2
  cancelResponseBody
3
3
  } from "./chunk-CA2EPNZF.js";
4
4
  import {
5
- strictInputSchema
6
- } from "./chunk-UMDUIBFW.js";
5
+ strictInputSchema,
6
+ zodInputSchema
7
+ } from "./chunk-YZ5QEHBX.js";
7
8
 
8
9
  // src/FastMCP.ts
9
10
  import { Server } from "@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 import("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" : fileType?.mime;
283
+ if (!mimeType || !mimeType.startsWith("image/")) {
272
284
  console.warn(
273
- `Warning: Content may not be a valid image. Detected MIME: ${mimeType?.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: mimeType?.mime ?? "image/png",
291
+ mimeType: 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 (detected?.startsWith("audio/")) {
312
+ return detected;
313
+ }
314
+ const declaredMime = declared?.split(";", 1)[0].trim().toLowerCase();
315
+ if (declaredMime?.startsWith("audio/")) {
316
+ return declaredMime;
317
+ }
318
+ return (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 = 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 import("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(detected?.mime, declaredMimeType);
366
+ if (!mimeType || !mimeType.startsWith("audio/")) {
334
367
  console.warn(
335
- `Warning: Content may not be a valid audio file. Detected MIME: ${mimeType?.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: mimeType?.mime ?? "audio/mpeg",
374
+ mimeType: mimeType ?? "audio/mpeg",
342
375
  type: "audio"
343
376
  };
344
377
  } catch (error) {
@@ -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 = 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,31 +903,31 @@ ${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(),
911
+ elicit: this.#createElicit(requestId),
912
+ log: this.#createLog(sendNotification),
852
913
  requestId: typeof meta?.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
  }
@@ -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
 
@@ -1258,54 +1320,61 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1258
1320
  prompts: cachedPromptsList
1259
1321
  };
1260
1322
  });
1261
- this.#server.setRequestHandler(GetPromptRequestSchema, async (request) => {
1262
- const prompt = this.#prompts.get(request.params.name);
1263
- if (!prompt) {
1264
- throw new McpError(
1265
- ErrorCode.InvalidParams,
1266
- `Unknown prompt: ${request.params.name}`
1267
- );
1268
- }
1269
- const args = request.params.arguments;
1270
- for (const arg of prompt.arguments ?? []) {
1271
- if (arg.required && !(args && Object.hasOwn(args, arg.name))) {
1323
+ this.#server.setRequestHandler(
1324
+ GetPromptRequestSchema,
1325
+ async (request, extra) => {
1326
+ const prompt = this.#prompts.get(request.params.name);
1327
+ if (!prompt) {
1272
1328
  throw new McpError(
1273
1329
  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 prompt.arguments ?? []) {
1335
+ if (arg.required && !(args && Object.hasOwn(args, arg.name))) {
1336
+ throw new McpError(
1337
+ 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
+ args ?? {},
1346
+ this.#auth,
1347
+ this.#createLoadContext(
1348
+ request.params?._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 McpError(
1356
+ 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
- args ?? {},
1282
- this.#auth,
1283
- this.#createLoadContext(request.params?._meta)
1284
- );
1285
- } catch (error) {
1286
- const errorMessage = error instanceof Error ? error.message : String(error);
1287
- throw new McpError(
1288
- 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
  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(request.params?._meta)
1417
+ this.#createLoadContext(
1418
+ request.params?._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(request.params?._meta)
1447
+ this.#createLoadContext(
1448
+ request.params?._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);
@@ -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(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 ? strictInputSchema(await toJsonSchema(tool.parameters)) : {
1565
+ inputSchema: tool.parameters ? strictInputSchema(
1566
+ tool.parameters["~standard"].vendor === "zod" && "_zod" in tool.parameters ? zodInputSchema(tool.parameters, "draft-7") : await toJsonSchema(tool.parameters)
1567
+ ) : {
1488
1568
  additionalProperties: false,
1489
1569
  properties: {},
1490
1570
  type: "object"
@@ -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,7 +1673,7 @@ ${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
1679
  requestId: typeof request.params?._meta?.requestId === "string" ? request.params._meta.requestId : void 0,
@@ -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,
@@ -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,
@@ -3156,4 +3247,4 @@ export {
3156
3247
  FastMCPSession,
3157
3248
  FastMCP
3158
3249
  };
3159
- //# sourceMappingURL=chunk-OUD755CE.js.map
3250
+ //# sourceMappingURL=chunk-7WNI6AGD.js.map