fastmcp 3.25.4 → 3.26.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1931 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// src/FastMCP.ts
2
+ var _indexjs = require('@modelcontextprotocol/sdk/server/index.js');
3
+ var _stdiojs = require('@modelcontextprotocol/sdk/server/stdio.js');
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+ var _typesjs = require('@modelcontextprotocol/sdk/types.js');
18
+ var _events = require('events');
19
+ var _promises = require('fs/promises');
20
+ var _fusejs = require('fuse.js'); var _fusejs2 = _interopRequireDefault(_fusejs);
21
+ var _mcpproxy = require('mcp-proxy');
22
+ var _promises3 = require('timers/promises');
23
+ var _undici = require('undici');
24
+ var _uritemplates = require('uri-templates'); var _uritemplates2 = _interopRequireDefault(_uritemplates);
25
+ var _xsschema = require('xsschema');
26
+ var _zod = require('zod');
27
+
28
+ // src/DiscoveryDocumentCache.ts
29
+ var DiscoveryDocumentCache = class {
30
+ get size() {
31
+ return this.#cache.size;
32
+ }
33
+ #cache = /* @__PURE__ */ new Map();
34
+ #inFlight = /* @__PURE__ */ new Map();
35
+ #ttl;
36
+ /**
37
+ * @param options - configuration options
38
+ * @param options.ttl - time-to-live in miliseconds
39
+ */
40
+ constructor(options = {}) {
41
+ this.#ttl = _nullishCoalesce(options.ttl, () => ( 36e5));
42
+ }
43
+ /**
44
+ * @param url - optional URL to clear. if omitted, clears all cached documents.
45
+ */
46
+ clear(url) {
47
+ if (url) {
48
+ this.#cache.delete(url);
49
+ } else {
50
+ this.#cache.clear();
51
+ }
52
+ }
53
+ /**
54
+ * fetches a discovery document from the given URL.
55
+ * uses cached value if available and not expired.
56
+ * coalesces concurrent requests for the same URL to prevent duplicate fetches.
57
+ *
58
+ * @param url - the discovery document URL (e.g., /.well-known/openid-configuration)
59
+ * @returns the discovery document as a JSON object
60
+ * @throws Error if the fetch fails or returns non-OK status
61
+ */
62
+ async get(url) {
63
+ const now = Date.now();
64
+ const cached = this.#cache.get(url);
65
+ if (cached && cached.expiresAt > now) {
66
+ return cached.data;
67
+ }
68
+ const inFlight = this.#inFlight.get(url);
69
+ if (inFlight) {
70
+ return inFlight;
71
+ }
72
+ const fetchPromise = this.#fetchAndCache(url);
73
+ this.#inFlight.set(url, fetchPromise);
74
+ try {
75
+ const data = await fetchPromise;
76
+ return data;
77
+ } finally {
78
+ this.#inFlight.delete(url);
79
+ }
80
+ }
81
+ /**
82
+ * @param url - the URL to check
83
+ * @returns true if the URL is cached and nott expired
84
+ */
85
+ has(url) {
86
+ const cached = this.#cache.get(url);
87
+ if (!cached) {
88
+ return false;
89
+ }
90
+ const now = Date.now();
91
+ if (cached.expiresAt <= now) {
92
+ this.#cache.delete(url);
93
+ return false;
94
+ }
95
+ return true;
96
+ }
97
+ async #fetchAndCache(url) {
98
+ const res = await fetch(url);
99
+ if (!res.ok) {
100
+ throw new Error(
101
+ `Failed to fetch discovery document from ${url}: ${res.status} ${res.statusText}`
102
+ );
103
+ }
104
+ const data = await res.json();
105
+ const expiresAt = Date.now() + this.#ttl;
106
+ this.#cache.set(url, {
107
+ data,
108
+ expiresAt
109
+ });
110
+ return data;
111
+ }
112
+ };
113
+
114
+ // src/FastMCP.ts
115
+ var imageContent = async (input) => {
116
+ let rawData;
117
+ try {
118
+ if ("url" in input) {
119
+ try {
120
+ const response = await _undici.fetch.call(void 0, input.url);
121
+ if (!response.ok) {
122
+ throw new Error(
123
+ `Server responded with status: ${response.status} - ${response.statusText}`
124
+ );
125
+ }
126
+ rawData = Buffer.from(await response.arrayBuffer());
127
+ } catch (error) {
128
+ throw new Error(
129
+ `Failed to fetch image from URL (${input.url}): ${error instanceof Error ? error.message : String(error)}`
130
+ );
131
+ }
132
+ } else if ("path" in input) {
133
+ try {
134
+ rawData = await _promises.readFile.call(void 0, input.path);
135
+ } catch (error) {
136
+ throw new Error(
137
+ `Failed to read image from path (${input.path}): ${error instanceof Error ? error.message : String(error)}`
138
+ );
139
+ }
140
+ } else if ("buffer" in input) {
141
+ rawData = input.buffer;
142
+ } else {
143
+ throw new Error(
144
+ "Invalid input: Provide a valid 'url', 'path', or 'buffer'"
145
+ );
146
+ }
147
+ const { fileTypeFromBuffer } = await Promise.resolve().then(() => _interopRequireWildcard(require("file-type")));
148
+ const mimeType = await fileTypeFromBuffer(rawData);
149
+ if (!mimeType || !mimeType.mime.startsWith("image/")) {
150
+ console.warn(
151
+ `Warning: Content may not be a valid image. Detected MIME: ${_optionalChain([mimeType, 'optionalAccess', _2 => _2.mime]) || "unknown"}`
152
+ );
153
+ }
154
+ const base64Data = rawData.toString("base64");
155
+ return {
156
+ data: base64Data,
157
+ mimeType: _nullishCoalesce(_optionalChain([mimeType, 'optionalAccess', _3 => _3.mime]), () => ( "image/png")),
158
+ type: "image"
159
+ };
160
+ } catch (error) {
161
+ if (error instanceof Error) {
162
+ throw error;
163
+ } else {
164
+ throw new Error(`Unexpected error processing image: ${String(error)}`);
165
+ }
166
+ }
167
+ };
168
+ var audioContent = async (input) => {
169
+ let rawData;
170
+ try {
171
+ if ("url" in input) {
172
+ try {
173
+ const response = await _undici.fetch.call(void 0, input.url);
174
+ if (!response.ok) {
175
+ throw new Error(
176
+ `Server responded with status: ${response.status} - ${response.statusText}`
177
+ );
178
+ }
179
+ rawData = Buffer.from(await response.arrayBuffer());
180
+ } catch (error) {
181
+ throw new Error(
182
+ `Failed to fetch audio from URL (${input.url}): ${error instanceof Error ? error.message : String(error)}`
183
+ );
184
+ }
185
+ } else if ("path" in input) {
186
+ try {
187
+ rawData = await _promises.readFile.call(void 0, input.path);
188
+ } catch (error) {
189
+ throw new Error(
190
+ `Failed to read audio from path (${input.path}): ${error instanceof Error ? error.message : String(error)}`
191
+ );
192
+ }
193
+ } else if ("buffer" in input) {
194
+ rawData = input.buffer;
195
+ } else {
196
+ throw new Error(
197
+ "Invalid input: Provide a valid 'url', 'path', or 'buffer'"
198
+ );
199
+ }
200
+ const { fileTypeFromBuffer } = await Promise.resolve().then(() => _interopRequireWildcard(require("file-type")));
201
+ const mimeType = await fileTypeFromBuffer(rawData);
202
+ if (!mimeType || !mimeType.mime.startsWith("audio/")) {
203
+ console.warn(
204
+ `Warning: Content may not be a valid audio file. Detected MIME: ${_optionalChain([mimeType, 'optionalAccess', _4 => _4.mime]) || "unknown"}`
205
+ );
206
+ }
207
+ const base64Data = rawData.toString("base64");
208
+ return {
209
+ data: base64Data,
210
+ mimeType: _nullishCoalesce(_optionalChain([mimeType, 'optionalAccess', _5 => _5.mime]), () => ( "audio/mpeg")),
211
+ type: "audio"
212
+ };
213
+ } catch (error) {
214
+ if (error instanceof Error) {
215
+ throw error;
216
+ } else {
217
+ throw new Error(`Unexpected error processing audio: ${String(error)}`);
218
+ }
219
+ }
220
+ };
221
+ var FastMCPError = class extends Error {
222
+ constructor(message) {
223
+ super(message);
224
+ this.name = new.target.name;
225
+ }
226
+ };
227
+ var UnexpectedStateError = class extends FastMCPError {
228
+
229
+ constructor(message, extras) {
230
+ super(message);
231
+ this.name = new.target.name;
232
+ this.extras = extras;
233
+ }
234
+ };
235
+ var UserError = class extends UnexpectedStateError {
236
+ };
237
+ var TextContentZodSchema = _zod.z.object({
238
+ /**
239
+ * The text content of the message.
240
+ */
241
+ text: _zod.z.string(),
242
+ type: _zod.z.literal("text")
243
+ }).strict();
244
+ var ImageContentZodSchema = _zod.z.object({
245
+ /**
246
+ * The base64-encoded image data.
247
+ */
248
+ data: _zod.z.string().base64(),
249
+ /**
250
+ * The MIME type of the image. Different providers may support different image types.
251
+ */
252
+ mimeType: _zod.z.string(),
253
+ type: _zod.z.literal("image")
254
+ }).strict();
255
+ var AudioContentZodSchema = _zod.z.object({
256
+ /**
257
+ * The base64-encoded audio data.
258
+ */
259
+ data: _zod.z.string().base64(),
260
+ mimeType: _zod.z.string(),
261
+ type: _zod.z.literal("audio")
262
+ }).strict();
263
+ var ResourceContentZodSchema = _zod.z.object({
264
+ resource: _zod.z.object({
265
+ blob: _zod.z.string().optional(),
266
+ mimeType: _zod.z.string().optional(),
267
+ text: _zod.z.string().optional(),
268
+ uri: _zod.z.string()
269
+ }),
270
+ type: _zod.z.literal("resource")
271
+ }).strict();
272
+ var ResourceLinkZodSchema = _zod.z.object({
273
+ description: _zod.z.string().optional(),
274
+ mimeType: _zod.z.string().optional(),
275
+ name: _zod.z.string(),
276
+ title: _zod.z.string().optional(),
277
+ type: _zod.z.literal("resource_link"),
278
+ uri: _zod.z.string()
279
+ });
280
+ var ContentZodSchema = _zod.z.discriminatedUnion("type", [
281
+ TextContentZodSchema,
282
+ ImageContentZodSchema,
283
+ AudioContentZodSchema,
284
+ ResourceContentZodSchema,
285
+ ResourceLinkZodSchema
286
+ ]);
287
+ var ContentResultZodSchema = _zod.z.object({
288
+ content: ContentZodSchema.array(),
289
+ isError: _zod.z.boolean().optional()
290
+ }).strict();
291
+ var CompletionZodSchema = _zod.z.object({
292
+ /**
293
+ * Indicates whether there are additional completion options beyond those provided in the current response, even if the exact total is unknown.
294
+ */
295
+ hasMore: _zod.z.optional(_zod.z.boolean()),
296
+ /**
297
+ * The total number of completion options available. This can exceed the number of values actually sent in the response.
298
+ */
299
+ total: _zod.z.optional(_zod.z.number().int()),
300
+ /**
301
+ * An array of completion values. Must not exceed 100 items.
302
+ */
303
+ values: _zod.z.array(_zod.z.string()).max(100)
304
+ });
305
+ var FastMCPSessionEventEmitterBase = _events.EventEmitter;
306
+ var ServerState = /* @__PURE__ */ ((ServerState2) => {
307
+ ServerState2["Error"] = "error";
308
+ ServerState2["Running"] = "running";
309
+ ServerState2["Stopped"] = "stopped";
310
+ return ServerState2;
311
+ })(ServerState || {});
312
+ var FastMCPSessionEventEmitter = class extends FastMCPSessionEventEmitterBase {
313
+ };
314
+ var FastMCPSession = class extends FastMCPSessionEventEmitter {
315
+ get clientCapabilities() {
316
+ return _nullishCoalesce(this.#clientCapabilities, () => ( null));
317
+ }
318
+ get isReady() {
319
+ return this.#connectionState === "ready";
320
+ }
321
+ get loggingLevel() {
322
+ return this.#loggingLevel;
323
+ }
324
+ get roots() {
325
+ return this.#roots;
326
+ }
327
+ get server() {
328
+ return this.#server;
329
+ }
330
+ get sessionId() {
331
+ return this.#sessionId;
332
+ }
333
+ set sessionId(value) {
334
+ this.#sessionId = value;
335
+ }
336
+ #auth;
337
+ #capabilities = {};
338
+ #clientCapabilities;
339
+ #connectionState = "connecting";
340
+ #logger;
341
+ #loggingLevel = "info";
342
+ #needsEventLoopFlush = false;
343
+ #pingConfig;
344
+ #pingInterval = null;
345
+ #prompts = [];
346
+ #resources = [];
347
+ #resourceTemplates = [];
348
+ #roots = [];
349
+ #rootsConfig;
350
+ #server;
351
+ /**
352
+ * Session ID from the Mcp-Session-Id header (HTTP transports only).
353
+ * Used to track per-session state across multiple requests.
354
+ */
355
+ #sessionId;
356
+ #utils;
357
+ constructor({
358
+ auth,
359
+ instructions,
360
+ logger,
361
+ name,
362
+ ping,
363
+ prompts,
364
+ resources,
365
+ resourcesTemplates,
366
+ roots,
367
+ sessionId,
368
+ tools,
369
+ transportType,
370
+ utils,
371
+ version
372
+ }) {
373
+ super();
374
+ this.#auth = auth;
375
+ this.#logger = logger;
376
+ this.#pingConfig = ping;
377
+ this.#rootsConfig = roots;
378
+ this.#sessionId = sessionId;
379
+ this.#needsEventLoopFlush = transportType === "httpStream";
380
+ if (tools.length) {
381
+ this.#capabilities.tools = {};
382
+ }
383
+ if (resources.length || resourcesTemplates.length) {
384
+ this.#capabilities.resources = {};
385
+ }
386
+ if (prompts.length) {
387
+ for (const prompt of prompts) {
388
+ this.addPrompt(prompt);
389
+ }
390
+ this.#capabilities.prompts = {};
391
+ }
392
+ this.#capabilities.logging = {};
393
+ this.#capabilities.completions = {};
394
+ this.#server = new (0, _indexjs.Server)(
395
+ { name, version },
396
+ { capabilities: this.#capabilities, instructions }
397
+ );
398
+ this.#utils = utils;
399
+ this.setupErrorHandling();
400
+ this.setupLoggingHandlers();
401
+ this.setupRootsHandlers();
402
+ this.setupCompleteHandlers();
403
+ if (tools.length) {
404
+ this.setupToolHandlers(tools);
405
+ }
406
+ if (resources.length || resourcesTemplates.length) {
407
+ for (const resource of resources) {
408
+ this.addResource(resource);
409
+ }
410
+ this.setupResourceHandlers(resources);
411
+ if (resourcesTemplates.length) {
412
+ for (const resourceTemplate of resourcesTemplates) {
413
+ this.addResourceTemplate(resourceTemplate);
414
+ }
415
+ this.setupResourceTemplateHandlers(resourcesTemplates);
416
+ }
417
+ }
418
+ if (prompts.length) {
419
+ this.setupPromptHandlers(prompts);
420
+ }
421
+ }
422
+ async close() {
423
+ this.#connectionState = "closed";
424
+ if (this.#pingInterval) {
425
+ clearInterval(this.#pingInterval);
426
+ }
427
+ try {
428
+ await this.#server.close();
429
+ } catch (error) {
430
+ this.#logger.error("[FastMCP error]", "could not close server", error);
431
+ }
432
+ }
433
+ async connect(transport) {
434
+ if (this.#server.transport) {
435
+ throw new UnexpectedStateError("Server is already connected");
436
+ }
437
+ this.#connectionState = "connecting";
438
+ try {
439
+ await this.#server.connect(transport);
440
+ if ("sessionId" in transport) {
441
+ const transportWithSessionId = transport;
442
+ if (typeof transportWithSessionId.sessionId === "string") {
443
+ this.#sessionId = transportWithSessionId.sessionId;
444
+ }
445
+ }
446
+ let attempt = 0;
447
+ const maxAttempts = 10;
448
+ const retryDelay = 100;
449
+ while (attempt++ < maxAttempts) {
450
+ const capabilities = this.#server.getClientCapabilities();
451
+ if (capabilities) {
452
+ this.#clientCapabilities = capabilities;
453
+ break;
454
+ }
455
+ await _promises3.setTimeout.call(void 0, retryDelay);
456
+ }
457
+ if (!this.#clientCapabilities) {
458
+ this.#logger.warn(
459
+ `[FastMCP warning] could not infer client capabilities after ${maxAttempts} attempts. Connection may be unstable.`
460
+ );
461
+ }
462
+ if (_optionalChain([this, 'access', _6 => _6.#rootsConfig, 'optionalAccess', _7 => _7.enabled]) !== false && _optionalChain([this, 'access', _8 => _8.#clientCapabilities, 'optionalAccess', _9 => _9.roots, 'optionalAccess', _10 => _10.listChanged]) && typeof this.#server.listRoots === "function") {
463
+ try {
464
+ const roots = await this.#server.listRoots();
465
+ this.#roots = _optionalChain([roots, 'optionalAccess', _11 => _11.roots]) || [];
466
+ } catch (e) {
467
+ if (e instanceof _typesjs.McpError && e.code === _typesjs.ErrorCode.MethodNotFound) {
468
+ this.#logger.debug(
469
+ "[FastMCP debug] listRoots method not supported by client"
470
+ );
471
+ } else {
472
+ this.#logger.error(
473
+ `[FastMCP error] received error listing roots.
474
+
475
+ ${e instanceof Error ? e.stack : JSON.stringify(e)}`
476
+ );
477
+ }
478
+ }
479
+ }
480
+ if (this.#clientCapabilities) {
481
+ const pingConfig = this.#getPingConfig(transport);
482
+ if (pingConfig.enabled) {
483
+ this.#pingInterval = setInterval(async () => {
484
+ try {
485
+ await this.#server.ping();
486
+ } catch (e2) {
487
+ const logLevel = pingConfig.logLevel;
488
+ if (logLevel === "debug") {
489
+ this.#logger.debug("[FastMCP debug] server ping failed");
490
+ } else if (logLevel === "warning") {
491
+ this.#logger.warn(
492
+ "[FastMCP warning] server is not responding to ping"
493
+ );
494
+ } else if (logLevel === "error") {
495
+ this.#logger.error(
496
+ "[FastMCP error] server is not responding to ping"
497
+ );
498
+ } else {
499
+ this.#logger.info("[FastMCP info] server ping failed");
500
+ }
501
+ }
502
+ }, pingConfig.intervalMs);
503
+ }
504
+ }
505
+ this.#connectionState = "ready";
506
+ this.emit("ready");
507
+ } catch (error) {
508
+ this.#connectionState = "error";
509
+ const errorEvent = {
510
+ error: error instanceof Error ? error : new Error(String(error))
511
+ };
512
+ this.emit("error", errorEvent);
513
+ throw error;
514
+ }
515
+ }
516
+ promptsListChanged(prompts) {
517
+ this.#prompts = [];
518
+ for (const prompt of prompts) {
519
+ this.addPrompt(prompt);
520
+ }
521
+ this.setupPromptHandlers(prompts);
522
+ this.triggerListChangedNotification("notifications/prompts/list_changed");
523
+ }
524
+ async requestSampling(message, options) {
525
+ return this.#server.createMessage(message, options);
526
+ }
527
+ resourcesListChanged(resources) {
528
+ this.#resources = [];
529
+ for (const resource of resources) {
530
+ this.addResource(resource);
531
+ }
532
+ this.setupResourceHandlers(resources);
533
+ this.triggerListChangedNotification("notifications/resources/list_changed");
534
+ }
535
+ resourceTemplatesListChanged(resourceTemplates) {
536
+ this.#resourceTemplates = [];
537
+ for (const resourceTemplate of resourceTemplates) {
538
+ this.addResourceTemplate(resourceTemplate);
539
+ }
540
+ this.setupResourceTemplateHandlers(resourceTemplates);
541
+ this.triggerListChangedNotification("notifications/resources/list_changed");
542
+ }
543
+ toolsListChanged(tools) {
544
+ const allowedTools = tools.filter(
545
+ (tool) => tool.canAccess ? tool.canAccess(this.#auth) : true
546
+ );
547
+ this.setupToolHandlers(allowedTools);
548
+ this.triggerListChangedNotification("notifications/tools/list_changed");
549
+ }
550
+ async triggerListChangedNotification(method) {
551
+ try {
552
+ await this.#server.notification({
553
+ method
554
+ });
555
+ } catch (error) {
556
+ this.#logger.error(
557
+ `[FastMCP error] failed to send ${method} notification.
558
+
559
+ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
560
+ );
561
+ }
562
+ }
563
+ waitForReady() {
564
+ if (this.isReady) {
565
+ return Promise.resolve();
566
+ }
567
+ if (this.#connectionState === "error" || this.#connectionState === "closed") {
568
+ return Promise.reject(
569
+ new Error(`Connection is in ${this.#connectionState} state`)
570
+ );
571
+ }
572
+ return new Promise((resolve, reject) => {
573
+ const timeout = setTimeout(() => {
574
+ reject(
575
+ new Error(
576
+ "Connection timeout: Session failed to become ready within 5 seconds"
577
+ )
578
+ );
579
+ }, 5e3);
580
+ this.once("ready", () => {
581
+ clearTimeout(timeout);
582
+ resolve();
583
+ });
584
+ this.once("error", (event) => {
585
+ clearTimeout(timeout);
586
+ reject(event.error);
587
+ });
588
+ });
589
+ }
590
+ #getPingConfig(transport) {
591
+ const pingConfig = this.#pingConfig || {};
592
+ let defaultEnabled = false;
593
+ if ("type" in transport) {
594
+ if (transport.type === "httpStream") {
595
+ defaultEnabled = true;
596
+ }
597
+ }
598
+ return {
599
+ enabled: pingConfig.enabled !== void 0 ? pingConfig.enabled : defaultEnabled,
600
+ intervalMs: pingConfig.intervalMs || 5e3,
601
+ logLevel: pingConfig.logLevel || "debug"
602
+ };
603
+ }
604
+ addPrompt(inputPrompt) {
605
+ const completers = {};
606
+ const enums = {};
607
+ const fuseInstances = {};
608
+ for (const argument of _nullishCoalesce(inputPrompt.arguments, () => ( []))) {
609
+ if (argument.complete) {
610
+ completers[argument.name] = argument.complete;
611
+ }
612
+ if (argument.enum) {
613
+ enums[argument.name] = argument.enum;
614
+ fuseInstances[argument.name] = new (0, _fusejs2.default)(argument.enum, {
615
+ includeScore: true,
616
+ threshold: 0.3
617
+ // More flexible matching!
618
+ });
619
+ }
620
+ }
621
+ const prompt = {
622
+ ...inputPrompt,
623
+ complete: async (name, value, auth) => {
624
+ if (completers[name]) {
625
+ return await completers[name](value, auth);
626
+ }
627
+ if (inputPrompt.complete) {
628
+ return await inputPrompt.complete(name, value, auth);
629
+ }
630
+ if (fuseInstances[name]) {
631
+ const result = fuseInstances[name].search(value);
632
+ return {
633
+ total: result.length,
634
+ values: result.map((item) => item.item)
635
+ };
636
+ }
637
+ return {
638
+ values: []
639
+ };
640
+ }
641
+ };
642
+ this.#prompts.push(prompt);
643
+ }
644
+ addResource(inputResource) {
645
+ this.#resources.push(inputResource);
646
+ }
647
+ addResourceTemplate(inputResourceTemplate) {
648
+ const completers = {};
649
+ for (const argument of _nullishCoalesce(inputResourceTemplate.arguments, () => ( []))) {
650
+ if (argument.complete) {
651
+ completers[argument.name] = argument.complete;
652
+ }
653
+ }
654
+ const resourceTemplate = {
655
+ ...inputResourceTemplate,
656
+ complete: async (name, value, auth) => {
657
+ if (completers[name]) {
658
+ return await completers[name](value, auth);
659
+ }
660
+ if (inputResourceTemplate.complete) {
661
+ return await inputResourceTemplate.complete(name, value, auth);
662
+ }
663
+ return {
664
+ values: []
665
+ };
666
+ }
667
+ };
668
+ this.#resourceTemplates.push(resourceTemplate);
669
+ }
670
+ setupCompleteHandlers() {
671
+ this.#server.setRequestHandler(_typesjs.CompleteRequestSchema, async (request) => {
672
+ if (request.params.ref.type === "ref/prompt") {
673
+ const ref = request.params.ref;
674
+ const prompt = "name" in ref && this.#prompts.find((prompt2) => prompt2.name === ref.name);
675
+ if (!prompt) {
676
+ throw new UnexpectedStateError("Unknown prompt", {
677
+ request
678
+ });
679
+ }
680
+ if (!prompt.complete) {
681
+ throw new UnexpectedStateError("Prompt does not support completion", {
682
+ request
683
+ });
684
+ }
685
+ const completion = CompletionZodSchema.parse(
686
+ await prompt.complete(
687
+ request.params.argument.name,
688
+ request.params.argument.value,
689
+ this.#auth
690
+ )
691
+ );
692
+ return {
693
+ completion
694
+ };
695
+ }
696
+ if (request.params.ref.type === "ref/resource") {
697
+ const ref = request.params.ref;
698
+ const resource = "uri" in ref && this.#resourceTemplates.find(
699
+ (resource2) => resource2.uriTemplate === ref.uri
700
+ );
701
+ if (!resource) {
702
+ throw new UnexpectedStateError("Unknown resource", {
703
+ request
704
+ });
705
+ }
706
+ if (!("uriTemplate" in resource)) {
707
+ throw new UnexpectedStateError("Unexpected resource");
708
+ }
709
+ if (!resource.complete) {
710
+ throw new UnexpectedStateError(
711
+ "Resource does not support completion",
712
+ {
713
+ request
714
+ }
715
+ );
716
+ }
717
+ const completion = CompletionZodSchema.parse(
718
+ await resource.complete(
719
+ request.params.argument.name,
720
+ request.params.argument.value,
721
+ this.#auth
722
+ )
723
+ );
724
+ return {
725
+ completion
726
+ };
727
+ }
728
+ throw new UnexpectedStateError("Unexpected completion request", {
729
+ request
730
+ });
731
+ });
732
+ }
733
+ setupErrorHandling() {
734
+ this.#server.onerror = (error) => {
735
+ this.#logger.error("[FastMCP error]", error);
736
+ };
737
+ }
738
+ setupLoggingHandlers() {
739
+ this.#server.setRequestHandler(_typesjs.SetLevelRequestSchema, (request) => {
740
+ this.#loggingLevel = request.params.level;
741
+ return {};
742
+ });
743
+ }
744
+ setupPromptHandlers(prompts) {
745
+ this.#server.setRequestHandler(_typesjs.ListPromptsRequestSchema, async () => {
746
+ return {
747
+ prompts: prompts.map((prompt) => {
748
+ return {
749
+ arguments: prompt.arguments,
750
+ complete: prompt.complete,
751
+ description: prompt.description,
752
+ name: prompt.name
753
+ };
754
+ })
755
+ };
756
+ });
757
+ this.#server.setRequestHandler(_typesjs.GetPromptRequestSchema, async (request) => {
758
+ const prompt = prompts.find(
759
+ (prompt2) => prompt2.name === request.params.name
760
+ );
761
+ if (!prompt) {
762
+ throw new (0, _typesjs.McpError)(
763
+ _typesjs.ErrorCode.MethodNotFound,
764
+ `Unknown prompt: ${request.params.name}`
765
+ );
766
+ }
767
+ const args = request.params.arguments;
768
+ for (const arg of _nullishCoalesce(prompt.arguments, () => ( []))) {
769
+ if (arg.required && !(args && arg.name in args)) {
770
+ throw new (0, _typesjs.McpError)(
771
+ _typesjs.ErrorCode.InvalidRequest,
772
+ `Prompt '${request.params.name}' requires argument '${arg.name}': ${arg.description || "No description provided"}`
773
+ );
774
+ }
775
+ }
776
+ let result;
777
+ try {
778
+ result = await prompt.load(
779
+ args,
780
+ this.#auth
781
+ );
782
+ } catch (error) {
783
+ const errorMessage = error instanceof Error ? error.message : String(error);
784
+ throw new (0, _typesjs.McpError)(
785
+ _typesjs.ErrorCode.InternalError,
786
+ `Failed to load prompt '${request.params.name}': ${errorMessage}`
787
+ );
788
+ }
789
+ if (typeof result === "string") {
790
+ return {
791
+ description: prompt.description,
792
+ messages: [
793
+ {
794
+ content: { text: result, type: "text" },
795
+ role: "user"
796
+ }
797
+ ]
798
+ };
799
+ } else {
800
+ return {
801
+ description: prompt.description,
802
+ messages: result.messages
803
+ };
804
+ }
805
+ });
806
+ }
807
+ setupResourceHandlers(resources) {
808
+ this.#server.setRequestHandler(_typesjs.ListResourcesRequestSchema, async () => {
809
+ return {
810
+ resources: resources.map((resource) => ({
811
+ description: resource.description,
812
+ mimeType: resource.mimeType,
813
+ name: resource.name,
814
+ uri: resource.uri
815
+ }))
816
+ };
817
+ });
818
+ this.#server.setRequestHandler(
819
+ _typesjs.ReadResourceRequestSchema,
820
+ async (request) => {
821
+ if ("uri" in request.params) {
822
+ const resource = resources.find(
823
+ (resource2) => "uri" in resource2 && resource2.uri === request.params.uri
824
+ );
825
+ if (!resource) {
826
+ for (const resourceTemplate of this.#resourceTemplates) {
827
+ const uriTemplate = _uritemplates2.default.call(void 0,
828
+ resourceTemplate.uriTemplate
829
+ );
830
+ const match = uriTemplate.fromUri(request.params.uri);
831
+ if (!match) {
832
+ continue;
833
+ }
834
+ const uri = uriTemplate.fill(match);
835
+ const result = await resourceTemplate.load(match, this.#auth);
836
+ const resources2 = Array.isArray(result) ? result : [result];
837
+ return {
838
+ contents: resources2.map((resource2) => ({
839
+ ...resource2,
840
+ description: resourceTemplate.description,
841
+ mimeType: _nullishCoalesce(resource2.mimeType, () => ( resourceTemplate.mimeType)),
842
+ name: resourceTemplate.name,
843
+ uri: _nullishCoalesce(resource2.uri, () => ( uri))
844
+ }))
845
+ };
846
+ }
847
+ throw new (0, _typesjs.McpError)(
848
+ _typesjs.ErrorCode.MethodNotFound,
849
+ `Resource not found: '${request.params.uri}'. Available resources: ${resources.map((r) => r.uri).join(", ") || "none"}`
850
+ );
851
+ }
852
+ if (!("uri" in resource)) {
853
+ throw new UnexpectedStateError("Resource does not support reading");
854
+ }
855
+ let maybeArrayResult;
856
+ try {
857
+ maybeArrayResult = await resource.load(this.#auth);
858
+ } catch (error) {
859
+ const errorMessage = error instanceof Error ? error.message : String(error);
860
+ throw new (0, _typesjs.McpError)(
861
+ _typesjs.ErrorCode.InternalError,
862
+ `Failed to load resource '${resource.name}' (${resource.uri}): ${errorMessage}`,
863
+ {
864
+ uri: resource.uri
865
+ }
866
+ );
867
+ }
868
+ const resourceResults = Array.isArray(maybeArrayResult) ? maybeArrayResult : [maybeArrayResult];
869
+ return {
870
+ contents: resourceResults.map((result) => ({
871
+ ...result,
872
+ mimeType: _nullishCoalesce(result.mimeType, () => ( resource.mimeType)),
873
+ name: resource.name,
874
+ uri: _nullishCoalesce(result.uri, () => ( resource.uri))
875
+ }))
876
+ };
877
+ }
878
+ throw new UnexpectedStateError("Unknown resource request", {
879
+ request
880
+ });
881
+ }
882
+ );
883
+ }
884
+ setupResourceTemplateHandlers(resourceTemplates) {
885
+ this.#server.setRequestHandler(
886
+ _typesjs.ListResourceTemplatesRequestSchema,
887
+ async () => {
888
+ return {
889
+ resourceTemplates: resourceTemplates.map((resourceTemplate) => ({
890
+ description: resourceTemplate.description,
891
+ mimeType: resourceTemplate.mimeType,
892
+ name: resourceTemplate.name,
893
+ uriTemplate: resourceTemplate.uriTemplate
894
+ }))
895
+ };
896
+ }
897
+ );
898
+ }
899
+ setupRootsHandlers() {
900
+ if (_optionalChain([this, 'access', _12 => _12.#rootsConfig, 'optionalAccess', _13 => _13.enabled]) === false) {
901
+ this.#logger.debug(
902
+ "[FastMCP debug] roots capability explicitly disabled via config"
903
+ );
904
+ return;
905
+ }
906
+ if (typeof this.#server.listRoots === "function") {
907
+ this.#server.setNotificationHandler(
908
+ _typesjs.RootsListChangedNotificationSchema,
909
+ () => {
910
+ this.#server.listRoots().then((roots) => {
911
+ this.#roots = roots.roots;
912
+ this.emit("rootsChanged", {
913
+ roots: roots.roots
914
+ });
915
+ }).catch((error) => {
916
+ if (error instanceof _typesjs.McpError && error.code === _typesjs.ErrorCode.MethodNotFound) {
917
+ this.#logger.debug(
918
+ "[FastMCP debug] listRoots method not supported by client"
919
+ );
920
+ } else {
921
+ this.#logger.error(
922
+ `[FastMCP error] received error listing roots.
923
+
924
+ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
925
+ );
926
+ }
927
+ });
928
+ }
929
+ );
930
+ } else {
931
+ this.#logger.debug(
932
+ "[FastMCP debug] roots capability not available, not setting up notification handler"
933
+ );
934
+ }
935
+ }
936
+ setupToolHandlers(tools) {
937
+ this.#server.setRequestHandler(_typesjs.ListToolsRequestSchema, async () => {
938
+ return {
939
+ tools: await Promise.all(
940
+ tools.map(async (tool) => {
941
+ return {
942
+ annotations: tool.annotations,
943
+ description: tool.description,
944
+ inputSchema: tool.parameters ? await _xsschema.toJsonSchema.call(void 0, tool.parameters) : {
945
+ additionalProperties: false,
946
+ properties: {},
947
+ type: "object"
948
+ },
949
+ // More complete schema for Cursor compatibility
950
+ name: tool.name
951
+ };
952
+ })
953
+ )
954
+ };
955
+ });
956
+ this.#server.setRequestHandler(_typesjs.CallToolRequestSchema, async (request) => {
957
+ const tool = tools.find((tool2) => tool2.name === request.params.name);
958
+ if (!tool) {
959
+ throw new (0, _typesjs.McpError)(
960
+ _typesjs.ErrorCode.MethodNotFound,
961
+ `Unknown tool: ${request.params.name}`
962
+ );
963
+ }
964
+ let args = void 0;
965
+ if (tool.parameters) {
966
+ const parsed = await tool.parameters["~standard"].validate(
967
+ request.params.arguments
968
+ );
969
+ if (parsed.issues) {
970
+ const friendlyErrors = _optionalChain([this, 'access', _14 => _14.#utils, 'optionalAccess', _15 => _15.formatInvalidParamsErrorMessage]) ? this.#utils.formatInvalidParamsErrorMessage(parsed.issues) : parsed.issues.map((issue) => {
971
+ const path = _optionalChain([issue, 'access', _16 => _16.path, 'optionalAccess', _17 => _17.join, 'call', _18 => _18(".")]) || "root";
972
+ return `${path}: ${issue.message}`;
973
+ }).join(", ");
974
+ throw new (0, _typesjs.McpError)(
975
+ _typesjs.ErrorCode.InvalidParams,
976
+ `Tool '${request.params.name}' parameter validation failed: ${friendlyErrors}. Please check the parameter types and values according to the tool's schema.`
977
+ );
978
+ }
979
+ args = parsed.value;
980
+ }
981
+ const progressToken = _optionalChain([request, 'access', _19 => _19.params, 'optionalAccess', _20 => _20._meta, 'optionalAccess', _21 => _21.progressToken]);
982
+ let result;
983
+ try {
984
+ const reportProgress = async (progress) => {
985
+ try {
986
+ await this.#server.notification({
987
+ method: "notifications/progress",
988
+ params: {
989
+ ...progress,
990
+ progressToken
991
+ }
992
+ });
993
+ if (this.#needsEventLoopFlush) {
994
+ await new Promise((resolve) => setImmediate(resolve));
995
+ }
996
+ } catch (progressError) {
997
+ this.#logger.warn(
998
+ `[FastMCP warning] Failed to report progress for tool '${request.params.name}':`,
999
+ progressError instanceof Error ? progressError.message : String(progressError)
1000
+ );
1001
+ }
1002
+ };
1003
+ const log = {
1004
+ debug: (message, context) => {
1005
+ this.#server.sendLoggingMessage({
1006
+ data: {
1007
+ context,
1008
+ message
1009
+ },
1010
+ level: "debug"
1011
+ });
1012
+ },
1013
+ error: (message, context) => {
1014
+ this.#server.sendLoggingMessage({
1015
+ data: {
1016
+ context,
1017
+ message
1018
+ },
1019
+ level: "error"
1020
+ });
1021
+ },
1022
+ info: (message, context) => {
1023
+ this.#server.sendLoggingMessage({
1024
+ data: {
1025
+ context,
1026
+ message
1027
+ },
1028
+ level: "info"
1029
+ });
1030
+ },
1031
+ warn: (message, context) => {
1032
+ this.#server.sendLoggingMessage({
1033
+ data: {
1034
+ context,
1035
+ message
1036
+ },
1037
+ level: "warning"
1038
+ });
1039
+ }
1040
+ };
1041
+ const streamContent = async (content) => {
1042
+ const contentArray = Array.isArray(content) ? content : [content];
1043
+ try {
1044
+ await this.#server.notification({
1045
+ method: "notifications/tool/streamContent",
1046
+ params: {
1047
+ content: contentArray,
1048
+ toolName: request.params.name
1049
+ }
1050
+ });
1051
+ if (this.#needsEventLoopFlush) {
1052
+ await new Promise((resolve) => setImmediate(resolve));
1053
+ }
1054
+ } catch (streamError) {
1055
+ this.#logger.warn(
1056
+ `[FastMCP warning] Failed to stream content for tool '${request.params.name}':`,
1057
+ streamError instanceof Error ? streamError.message : String(streamError)
1058
+ );
1059
+ }
1060
+ };
1061
+ const executeToolPromise = tool.execute(args, {
1062
+ client: {
1063
+ version: this.#server.getClientVersion()
1064
+ },
1065
+ log,
1066
+ reportProgress,
1067
+ requestId: typeof _optionalChain([request, 'access', _22 => _22.params, 'optionalAccess', _23 => _23._meta, 'optionalAccess', _24 => _24.requestId]) === "string" ? request.params._meta.requestId : void 0,
1068
+ session: this.#auth,
1069
+ sessionId: this.#sessionId,
1070
+ streamContent
1071
+ });
1072
+ const maybeStringResult = await (tool.timeoutMs ? Promise.race([
1073
+ executeToolPromise,
1074
+ new Promise((_, reject) => {
1075
+ const timeoutId = setTimeout(() => {
1076
+ reject(
1077
+ new UserError(
1078
+ `Tool '${request.params.name}' timed out after ${tool.timeoutMs}ms. Consider increasing timeoutMs or optimizing the tool implementation.`
1079
+ )
1080
+ );
1081
+ }, tool.timeoutMs);
1082
+ executeToolPromise.finally(() => clearTimeout(timeoutId));
1083
+ })
1084
+ ]) : executeToolPromise);
1085
+ await _promises3.setTimeout.call(void 0, 1);
1086
+ if (maybeStringResult === void 0 || maybeStringResult === null) {
1087
+ result = ContentResultZodSchema.parse({
1088
+ content: []
1089
+ });
1090
+ } else if (typeof maybeStringResult === "string") {
1091
+ result = ContentResultZodSchema.parse({
1092
+ content: [{ text: maybeStringResult, type: "text" }]
1093
+ });
1094
+ } else if ("type" in maybeStringResult) {
1095
+ result = ContentResultZodSchema.parse({
1096
+ content: [maybeStringResult]
1097
+ });
1098
+ } else {
1099
+ result = ContentResultZodSchema.parse(maybeStringResult);
1100
+ }
1101
+ } catch (error) {
1102
+ if (error instanceof UserError) {
1103
+ return {
1104
+ content: [{ text: error.message, type: "text" }],
1105
+ isError: true,
1106
+ ...error.extras ? { structuredContent: error.extras } : {}
1107
+ };
1108
+ }
1109
+ const errorMessage = error instanceof Error ? error.message : String(error);
1110
+ return {
1111
+ content: [
1112
+ {
1113
+ text: `Tool '${request.params.name}' execution failed: ${errorMessage}`,
1114
+ type: "text"
1115
+ }
1116
+ ],
1117
+ isError: true
1118
+ };
1119
+ }
1120
+ return result;
1121
+ });
1122
+ }
1123
+ };
1124
+ function camelToSnakeCase(str) {
1125
+ return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
1126
+ }
1127
+ function convertObjectToSnakeCase(obj) {
1128
+ const result = {};
1129
+ for (const [key, value] of Object.entries(obj)) {
1130
+ const snakeKey = camelToSnakeCase(key);
1131
+ result[snakeKey] = value;
1132
+ }
1133
+ return result;
1134
+ }
1135
+ function parseBasicAuthHeader(authHeader) {
1136
+ const basicMatch = _optionalChain([authHeader, 'optionalAccess', _25 => _25.match, 'call', _26 => _26(/^Basic\s+(.+)$/)]);
1137
+ if (!basicMatch) return null;
1138
+ try {
1139
+ const credentials = Buffer.from(basicMatch[1], "base64").toString("utf-8");
1140
+ const credMatch = credentials.match(/^([^:]+):(.*)$/);
1141
+ if (!credMatch) return null;
1142
+ return { clientId: credMatch[1], clientSecret: credMatch[2] };
1143
+ } catch (e3) {
1144
+ return null;
1145
+ }
1146
+ }
1147
+ var FastMCPEventEmitterBase = _events.EventEmitter;
1148
+ var FastMCPEventEmitter = class extends FastMCPEventEmitterBase {
1149
+ };
1150
+ var FastMCP = class extends FastMCPEventEmitter {
1151
+ constructor(options) {
1152
+ super();
1153
+ this.options = options;
1154
+ this.#options = options;
1155
+ this.#authenticate = options.authenticate;
1156
+ this.#logger = options.logger || console;
1157
+ }
1158
+ get serverState() {
1159
+ return this.#serverState;
1160
+ }
1161
+ get sessions() {
1162
+ return this.#sessions;
1163
+ }
1164
+ #authenticate;
1165
+ #httpStreamServer = null;
1166
+ #logger;
1167
+ #options;
1168
+ #prompts = [];
1169
+ #resources = [];
1170
+ #resourcesTemplates = [];
1171
+ #serverState = "stopped" /* Stopped */;
1172
+ #sessions = [];
1173
+ #tools = [];
1174
+ /**
1175
+ * Adds a prompt to the server.
1176
+ */
1177
+ addPrompt(prompt) {
1178
+ this.#prompts = this.#prompts.filter((p) => p.name !== prompt.name);
1179
+ this.#prompts.push(prompt);
1180
+ if (this.#serverState === "running" /* Running */) {
1181
+ this.#promptsListChanged(this.#prompts);
1182
+ }
1183
+ }
1184
+ /**
1185
+ * Adds prompts to the server.
1186
+ */
1187
+ addPrompts(prompts) {
1188
+ const newPromptNames = new Set(prompts.map((prompt) => prompt.name));
1189
+ this.#prompts = this.#prompts.filter((p) => !newPromptNames.has(p.name));
1190
+ this.#prompts.push(...prompts);
1191
+ if (this.#serverState === "running" /* Running */) {
1192
+ this.#promptsListChanged(this.#prompts);
1193
+ }
1194
+ }
1195
+ /**
1196
+ * Adds a resource to the server.
1197
+ */
1198
+ addResource(resource) {
1199
+ this.#resources = this.#resources.filter((r) => r.name !== resource.name);
1200
+ this.#resources.push(resource);
1201
+ if (this.#serverState === "running" /* Running */) {
1202
+ this.#resourcesListChanged(this.#resources);
1203
+ }
1204
+ }
1205
+ /**
1206
+ * Adds resources to the server.
1207
+ */
1208
+ addResources(resources) {
1209
+ const newResourceNames = new Set(
1210
+ resources.map((resource) => resource.name)
1211
+ );
1212
+ this.#resources = this.#resources.filter(
1213
+ (r) => !newResourceNames.has(r.name)
1214
+ );
1215
+ this.#resources.push(...resources);
1216
+ if (this.#serverState === "running" /* Running */) {
1217
+ this.#resourcesListChanged(this.#resources);
1218
+ }
1219
+ }
1220
+ /**
1221
+ * Adds a resource template to the server.
1222
+ */
1223
+ addResourceTemplate(resource) {
1224
+ this.#resourcesTemplates = this.#resourcesTemplates.filter(
1225
+ (t) => t.name !== resource.name
1226
+ );
1227
+ this.#resourcesTemplates.push(resource);
1228
+ if (this.#serverState === "running" /* Running */) {
1229
+ this.#resourceTemplatesListChanged(this.#resourcesTemplates);
1230
+ }
1231
+ }
1232
+ /**
1233
+ * Adds resource templates to the server.
1234
+ */
1235
+ addResourceTemplates(resources) {
1236
+ const newResourceTemplateNames = new Set(
1237
+ resources.map((resource) => resource.name)
1238
+ );
1239
+ this.#resourcesTemplates = this.#resourcesTemplates.filter(
1240
+ (t) => !newResourceTemplateNames.has(t.name)
1241
+ );
1242
+ this.#resourcesTemplates.push(...resources);
1243
+ if (this.#serverState === "running" /* Running */) {
1244
+ this.#resourceTemplatesListChanged(this.#resourcesTemplates);
1245
+ }
1246
+ }
1247
+ /**
1248
+ * Adds a tool to the server.
1249
+ */
1250
+ addTool(tool) {
1251
+ this.#tools = this.#tools.filter((t) => t.name !== tool.name);
1252
+ this.#tools.push(tool);
1253
+ if (this.#serverState === "running" /* Running */) {
1254
+ this.#toolsListChanged(this.#tools);
1255
+ }
1256
+ }
1257
+ /**
1258
+ * Adds tools to the server.
1259
+ */
1260
+ addTools(tools) {
1261
+ const newToolNames = new Set(tools.map((tool) => tool.name));
1262
+ this.#tools = this.#tools.filter((t) => !newToolNames.has(t.name));
1263
+ this.#tools.push(...tools);
1264
+ if (this.#serverState === "running" /* Running */) {
1265
+ this.#toolsListChanged(this.#tools);
1266
+ }
1267
+ }
1268
+ /**
1269
+ * Embeds a resource by URI, making it easy to include resources in tool responses.
1270
+ *
1271
+ * @param uri - The URI of the resource to embed
1272
+ * @returns Promise<ResourceContent> - The embedded resource content
1273
+ */
1274
+ async embedded(uri) {
1275
+ const directResource = this.#resources.find(
1276
+ (resource) => resource.uri === uri
1277
+ );
1278
+ if (directResource) {
1279
+ const result = await directResource.load();
1280
+ const results = Array.isArray(result) ? result : [result];
1281
+ const firstResult = results[0];
1282
+ const resourceData = {
1283
+ mimeType: directResource.mimeType,
1284
+ uri
1285
+ };
1286
+ if ("text" in firstResult) {
1287
+ resourceData.text = firstResult.text;
1288
+ }
1289
+ if ("blob" in firstResult) {
1290
+ resourceData.blob = firstResult.blob;
1291
+ }
1292
+ return resourceData;
1293
+ }
1294
+ for (const template of this.#resourcesTemplates) {
1295
+ const parsedTemplate = _uritemplates2.default.call(void 0, template.uriTemplate);
1296
+ const params = parsedTemplate.fromUri(uri);
1297
+ if (!params) {
1298
+ continue;
1299
+ }
1300
+ const result = await template.load(
1301
+ params
1302
+ );
1303
+ const resourceData = {
1304
+ mimeType: template.mimeType,
1305
+ uri
1306
+ };
1307
+ if ("text" in result) {
1308
+ resourceData.text = result.text;
1309
+ }
1310
+ if ("blob" in result) {
1311
+ resourceData.blob = result.blob;
1312
+ }
1313
+ return resourceData;
1314
+ }
1315
+ throw new UnexpectedStateError(`Resource not found: ${uri}`, { uri });
1316
+ }
1317
+ /**
1318
+ * Removes a prompt from the server.
1319
+ */
1320
+ removePrompt(name) {
1321
+ this.#prompts = this.#prompts.filter((p) => p.name !== name);
1322
+ if (this.#serverState === "running" /* Running */) {
1323
+ this.#promptsListChanged(this.#prompts);
1324
+ }
1325
+ }
1326
+ /**
1327
+ * Removes prompts from the server.
1328
+ */
1329
+ removePrompts(names) {
1330
+ for (const name of names) {
1331
+ this.#prompts = this.#prompts.filter((p) => p.name !== name);
1332
+ }
1333
+ if (this.#serverState === "running" /* Running */) {
1334
+ this.#promptsListChanged(this.#prompts);
1335
+ }
1336
+ }
1337
+ /**
1338
+ * Removes a resource from the server.
1339
+ */
1340
+ removeResource(name) {
1341
+ this.#resources = this.#resources.filter((r) => r.name !== name);
1342
+ if (this.#serverState === "running" /* Running */) {
1343
+ this.#resourcesListChanged(this.#resources);
1344
+ }
1345
+ }
1346
+ /**
1347
+ * Removes resources from the server.
1348
+ */
1349
+ removeResources(names) {
1350
+ for (const name of names) {
1351
+ this.#resources = this.#resources.filter((r) => r.name !== name);
1352
+ }
1353
+ if (this.#serverState === "running" /* Running */) {
1354
+ this.#resourcesListChanged(this.#resources);
1355
+ }
1356
+ }
1357
+ /**
1358
+ * Removes a resource template from the server.
1359
+ */
1360
+ removeResourceTemplate(name) {
1361
+ this.#resourcesTemplates = this.#resourcesTemplates.filter(
1362
+ (t) => t.name !== name
1363
+ );
1364
+ if (this.#serverState === "running" /* Running */) {
1365
+ this.#resourceTemplatesListChanged(this.#resourcesTemplates);
1366
+ }
1367
+ }
1368
+ /**
1369
+ * Removes resource templates from the server.
1370
+ */
1371
+ removeResourceTemplates(names) {
1372
+ for (const name of names) {
1373
+ this.#resourcesTemplates = this.#resourcesTemplates.filter(
1374
+ (t) => t.name !== name
1375
+ );
1376
+ }
1377
+ if (this.#serverState === "running" /* Running */) {
1378
+ this.#resourceTemplatesListChanged(this.#resourcesTemplates);
1379
+ }
1380
+ }
1381
+ /**
1382
+ * Removes a tool from the server.
1383
+ */
1384
+ removeTool(name) {
1385
+ this.#tools = this.#tools.filter((t) => t.name !== name);
1386
+ if (this.#serverState === "running" /* Running */) {
1387
+ this.#toolsListChanged(this.#tools);
1388
+ }
1389
+ }
1390
+ /**
1391
+ * Removes tools from the server.
1392
+ */
1393
+ removeTools(names) {
1394
+ for (const name of names) {
1395
+ this.#tools = this.#tools.filter((t) => t.name !== name);
1396
+ }
1397
+ if (this.#serverState === "running" /* Running */) {
1398
+ this.#toolsListChanged(this.#tools);
1399
+ }
1400
+ }
1401
+ /**
1402
+ * Starts the server.
1403
+ */
1404
+ async start(options) {
1405
+ const config = this.#parseRuntimeConfig(options);
1406
+ if (config.transportType === "stdio") {
1407
+ const transport = new (0, _stdiojs.StdioServerTransport)();
1408
+ let auth;
1409
+ if (this.#authenticate) {
1410
+ try {
1411
+ auth = await this.#authenticate(
1412
+ void 0
1413
+ );
1414
+ } catch (error) {
1415
+ this.#logger.error(
1416
+ "[FastMCP error] Authentication failed for stdio transport:",
1417
+ error instanceof Error ? error.message : String(error)
1418
+ );
1419
+ }
1420
+ }
1421
+ const session = new FastMCPSession({
1422
+ auth,
1423
+ instructions: this.#options.instructions,
1424
+ logger: this.#logger,
1425
+ name: this.#options.name,
1426
+ ping: this.#options.ping,
1427
+ prompts: this.#prompts,
1428
+ resources: this.#resources,
1429
+ resourcesTemplates: this.#resourcesTemplates,
1430
+ roots: this.#options.roots,
1431
+ tools: this.#tools,
1432
+ transportType: "stdio",
1433
+ utils: this.#options.utils,
1434
+ version: this.#options.version
1435
+ });
1436
+ await session.connect(transport);
1437
+ this.#sessions.push(session);
1438
+ session.once("error", () => {
1439
+ this.#removeSession(session);
1440
+ });
1441
+ if (transport.onclose) {
1442
+ const originalOnClose = transport.onclose;
1443
+ transport.onclose = () => {
1444
+ this.#removeSession(session);
1445
+ if (originalOnClose) {
1446
+ originalOnClose();
1447
+ }
1448
+ };
1449
+ } else {
1450
+ transport.onclose = () => {
1451
+ this.#removeSession(session);
1452
+ };
1453
+ }
1454
+ this.emit("connect", {
1455
+ session
1456
+ });
1457
+ this.#serverState = "running" /* Running */;
1458
+ } else if (config.transportType === "httpStream") {
1459
+ const httpConfig = config.httpStream;
1460
+ if (httpConfig.stateless) {
1461
+ this.#logger.info(
1462
+ `[FastMCP info] Starting server in stateless mode on HTTP Stream at http://${httpConfig.host}:${httpConfig.port}${httpConfig.endpoint}`
1463
+ );
1464
+ this.#httpStreamServer = await _mcpproxy.startHTTPServer.call(void 0, {
1465
+ ...this.#authenticate ? { authenticate: this.#authenticate } : {},
1466
+ createServer: async (request) => {
1467
+ let auth;
1468
+ if (this.#authenticate) {
1469
+ auth = await this.#authenticate(request);
1470
+ if (auth === void 0 || auth === null) {
1471
+ throw new Error("Authentication required");
1472
+ }
1473
+ }
1474
+ const sessionId = Array.isArray(request.headers["mcp-session-id"]) ? request.headers["mcp-session-id"][0] : request.headers["mcp-session-id"];
1475
+ return this.#createSession(auth, sessionId);
1476
+ },
1477
+ enableJsonResponse: httpConfig.enableJsonResponse,
1478
+ eventStore: httpConfig.eventStore,
1479
+ host: httpConfig.host,
1480
+ ..._optionalChain([this, 'access', _27 => _27.#options, 'access', _28 => _28.oauth, 'optionalAccess', _29 => _29.enabled]) && _optionalChain([this, 'access', _30 => _30.#options, 'access', _31 => _31.oauth, 'access', _32 => _32.protectedResource, 'optionalAccess', _33 => _33.resource]) ? {
1481
+ oauth: {
1482
+ protectedResource: {
1483
+ resource: this.#options.oauth.protectedResource.resource
1484
+ }
1485
+ }
1486
+ } : {},
1487
+ // In stateless mode, we don't track sessions
1488
+ onClose: async () => {
1489
+ },
1490
+ onConnect: async () => {
1491
+ this.#logger.debug(
1492
+ `[FastMCP debug] Stateless HTTP Stream request handled`
1493
+ );
1494
+ },
1495
+ onUnhandledRequest: async (req, res) => {
1496
+ await this.#handleUnhandledRequest(
1497
+ req,
1498
+ res,
1499
+ true,
1500
+ httpConfig.host,
1501
+ httpConfig.endpoint
1502
+ );
1503
+ },
1504
+ port: httpConfig.port,
1505
+ stateless: true,
1506
+ streamEndpoint: httpConfig.endpoint
1507
+ });
1508
+ } else {
1509
+ this.#httpStreamServer = await _mcpproxy.startHTTPServer.call(void 0, {
1510
+ ...this.#authenticate ? { authenticate: this.#authenticate } : {},
1511
+ createServer: async (request) => {
1512
+ let auth;
1513
+ if (this.#authenticate) {
1514
+ auth = await this.#authenticate(request);
1515
+ }
1516
+ const sessionId = Array.isArray(request.headers["mcp-session-id"]) ? request.headers["mcp-session-id"][0] : request.headers["mcp-session-id"];
1517
+ return this.#createSession(auth, sessionId);
1518
+ },
1519
+ enableJsonResponse: httpConfig.enableJsonResponse,
1520
+ eventStore: httpConfig.eventStore,
1521
+ host: httpConfig.host,
1522
+ ..._optionalChain([this, 'access', _34 => _34.#options, 'access', _35 => _35.oauth, 'optionalAccess', _36 => _36.enabled]) && _optionalChain([this, 'access', _37 => _37.#options, 'access', _38 => _38.oauth, 'access', _39 => _39.protectedResource, 'optionalAccess', _40 => _40.resource]) ? {
1523
+ oauth: {
1524
+ protectedResource: {
1525
+ resource: this.#options.oauth.protectedResource.resource
1526
+ }
1527
+ }
1528
+ } : {},
1529
+ onClose: async (session) => {
1530
+ const sessionIndex = this.#sessions.indexOf(session);
1531
+ if (sessionIndex !== -1) this.#sessions.splice(sessionIndex, 1);
1532
+ this.emit("disconnect", {
1533
+ session
1534
+ });
1535
+ },
1536
+ onConnect: async (session) => {
1537
+ this.#sessions.push(session);
1538
+ this.#logger.info(`[FastMCP info] HTTP Stream session established`);
1539
+ this.emit("connect", {
1540
+ session
1541
+ });
1542
+ },
1543
+ onUnhandledRequest: async (req, res) => {
1544
+ await this.#handleUnhandledRequest(
1545
+ req,
1546
+ res,
1547
+ false,
1548
+ httpConfig.host,
1549
+ httpConfig.endpoint
1550
+ );
1551
+ },
1552
+ port: httpConfig.port,
1553
+ stateless: httpConfig.stateless,
1554
+ streamEndpoint: httpConfig.endpoint
1555
+ });
1556
+ this.#logger.info(
1557
+ `[FastMCP info] server is running on HTTP Stream at http://${httpConfig.host}:${httpConfig.port}${httpConfig.endpoint}`
1558
+ );
1559
+ }
1560
+ this.#serverState = "running" /* Running */;
1561
+ } else {
1562
+ throw new Error("Invalid transport type");
1563
+ }
1564
+ }
1565
+ /**
1566
+ * Stops the server.
1567
+ */
1568
+ async stop() {
1569
+ if (this.#httpStreamServer) {
1570
+ await this.#httpStreamServer.close();
1571
+ }
1572
+ this.#serverState = "stopped" /* Stopped */;
1573
+ }
1574
+ /**
1575
+ * Creates a new FastMCPSession instance with the current configuration.
1576
+ * Used both for regular sessions and stateless requests.
1577
+ */
1578
+ #createSession(auth, sessionId) {
1579
+ if (auth && typeof auth === "object" && "authenticated" in auth && !auth.authenticated) {
1580
+ const errorMessage = "error" in auth && typeof auth.error === "string" ? auth.error : "Authentication failed";
1581
+ throw new Error(errorMessage);
1582
+ }
1583
+ const allowedTools = auth ? this.#tools.filter(
1584
+ (tool) => tool.canAccess ? tool.canAccess(auth) : true
1585
+ ) : this.#tools;
1586
+ return new FastMCPSession({
1587
+ auth,
1588
+ instructions: this.#options.instructions,
1589
+ logger: this.#logger,
1590
+ name: this.#options.name,
1591
+ ping: this.#options.ping,
1592
+ prompts: this.#prompts,
1593
+ resources: this.#resources,
1594
+ resourcesTemplates: this.#resourcesTemplates,
1595
+ roots: this.#options.roots,
1596
+ sessionId,
1597
+ tools: allowedTools,
1598
+ transportType: "httpStream",
1599
+ utils: this.#options.utils,
1600
+ version: this.#options.version
1601
+ });
1602
+ }
1603
+ /**
1604
+ * Handles unhandled HTTP requests with health, readiness, and OAuth endpoints
1605
+ */
1606
+ #handleUnhandledRequest = async (req, res, isStateless = false, host, streamEndpoint) => {
1607
+ const healthConfig = _nullishCoalesce(this.#options.health, () => ( {}));
1608
+ const enabled = healthConfig.enabled === void 0 ? true : healthConfig.enabled;
1609
+ if (enabled) {
1610
+ const path = _nullishCoalesce(healthConfig.path, () => ( "/health"));
1611
+ const url = new URL(req.url || "", `http://${host}`);
1612
+ try {
1613
+ if (req.method === "GET" && url.pathname === path) {
1614
+ res.writeHead(_nullishCoalesce(healthConfig.status, () => ( 200)), {
1615
+ "Content-Type": "text/plain"
1616
+ }).end(_nullishCoalesce(healthConfig.message, () => ( "\u2713 Ok")));
1617
+ return;
1618
+ }
1619
+ if (req.method === "GET" && url.pathname === "/ready") {
1620
+ if (isStateless) {
1621
+ const response = {
1622
+ mode: "stateless",
1623
+ ready: 1,
1624
+ status: "ready",
1625
+ total: 1
1626
+ };
1627
+ res.writeHead(200, {
1628
+ "Content-Type": "application/json"
1629
+ }).end(JSON.stringify(response));
1630
+ } else {
1631
+ const readySessions = this.#sessions.filter(
1632
+ (s) => s.isReady
1633
+ ).length;
1634
+ const totalSessions = this.#sessions.length;
1635
+ const allReady = readySessions === totalSessions && totalSessions > 0;
1636
+ const response = {
1637
+ ready: readySessions,
1638
+ status: allReady ? "ready" : totalSessions === 0 ? "no_sessions" : "initializing",
1639
+ total: totalSessions
1640
+ };
1641
+ res.writeHead(allReady ? 200 : 503, {
1642
+ "Content-Type": "application/json"
1643
+ }).end(JSON.stringify(response));
1644
+ }
1645
+ return;
1646
+ }
1647
+ } catch (error) {
1648
+ this.#logger.error("[FastMCP error] health endpoint error", error);
1649
+ }
1650
+ }
1651
+ const oauthConfig = this.#options.oauth;
1652
+ if (_optionalChain([oauthConfig, 'optionalAccess', _41 => _41.enabled]) && req.method === "GET") {
1653
+ const url = new URL(req.url || "", `http://${host}`);
1654
+ if (url.pathname === "/.well-known/oauth-authorization-server" && oauthConfig.authorizationServer) {
1655
+ const metadata = convertObjectToSnakeCase(
1656
+ oauthConfig.authorizationServer
1657
+ );
1658
+ res.writeHead(200, {
1659
+ "Content-Type": "application/json"
1660
+ }).end(JSON.stringify(metadata));
1661
+ return;
1662
+ }
1663
+ if (oauthConfig.protectedResource) {
1664
+ const wellKnownBase = "/.well-known/oauth-protected-resource";
1665
+ let shouldServeMetadata = false;
1666
+ if (streamEndpoint && url.pathname === `${wellKnownBase}${streamEndpoint}`) {
1667
+ shouldServeMetadata = true;
1668
+ } else if (url.pathname === wellKnownBase) {
1669
+ shouldServeMetadata = true;
1670
+ }
1671
+ if (shouldServeMetadata) {
1672
+ const metadata = convertObjectToSnakeCase(
1673
+ oauthConfig.protectedResource
1674
+ );
1675
+ res.writeHead(200, {
1676
+ "Content-Type": "application/json"
1677
+ }).end(JSON.stringify(metadata));
1678
+ return;
1679
+ }
1680
+ }
1681
+ }
1682
+ const oauthProxy = _optionalChain([oauthConfig, 'optionalAccess', _42 => _42.proxy]);
1683
+ if (oauthProxy && _optionalChain([oauthConfig, 'optionalAccess', _43 => _43.enabled])) {
1684
+ const url = new URL(req.url || "", `http://${host}`);
1685
+ try {
1686
+ if (req.method === "POST" && url.pathname === "/oauth/register") {
1687
+ let body = "";
1688
+ req.on("data", (chunk) => body += chunk);
1689
+ req.on("end", async () => {
1690
+ try {
1691
+ const request = JSON.parse(body);
1692
+ const response = await oauthProxy.registerClient(request);
1693
+ res.writeHead(201, { "Content-Type": "application/json" }).end(JSON.stringify(response));
1694
+ } catch (error) {
1695
+ const statusCode = error.statusCode || 400;
1696
+ res.writeHead(statusCode, { "Content-Type": "application/json" }).end(
1697
+ JSON.stringify(
1698
+ _optionalChain([error, 'access', _44 => _44.toJSON, 'optionalCall', _45 => _45()]) || {
1699
+ error: "invalid_request"
1700
+ }
1701
+ )
1702
+ );
1703
+ }
1704
+ });
1705
+ return;
1706
+ }
1707
+ if (req.method === "GET" && url.pathname === "/oauth/authorize") {
1708
+ try {
1709
+ const params = Object.fromEntries(url.searchParams.entries());
1710
+ const response = await oauthProxy.authorize(
1711
+ params
1712
+ );
1713
+ const location = response.headers.get("Location");
1714
+ if (location) {
1715
+ res.writeHead(response.status, { Location: location }).end();
1716
+ } else {
1717
+ const html = await response.text();
1718
+ res.writeHead(response.status, { "Content-Type": "text/html" }).end(html);
1719
+ }
1720
+ } catch (error) {
1721
+ res.writeHead(400, { "Content-Type": "application/json" }).end(
1722
+ JSON.stringify(
1723
+ _optionalChain([error, 'access', _46 => _46.toJSON, 'optionalCall', _47 => _47()]) || {
1724
+ error: "invalid_request"
1725
+ }
1726
+ )
1727
+ );
1728
+ }
1729
+ return;
1730
+ }
1731
+ if (req.method === "GET" && url.pathname === "/oauth/callback") {
1732
+ try {
1733
+ const mockRequest = new Request(`http://${host}${req.url}`);
1734
+ const response = await oauthProxy.handleCallback(mockRequest);
1735
+ const location = response.headers.get("Location");
1736
+ if (location) {
1737
+ res.writeHead(response.status, { Location: location }).end();
1738
+ } else {
1739
+ const text = await response.text();
1740
+ res.writeHead(response.status).end(text);
1741
+ }
1742
+ } catch (error) {
1743
+ res.writeHead(400, { "Content-Type": "application/json" }).end(
1744
+ JSON.stringify(
1745
+ _optionalChain([error, 'access', _48 => _48.toJSON, 'optionalCall', _49 => _49()]) || {
1746
+ error: "server_error"
1747
+ }
1748
+ )
1749
+ );
1750
+ }
1751
+ return;
1752
+ }
1753
+ if (req.method === "POST" && url.pathname === "/oauth/consent") {
1754
+ let body = "";
1755
+ req.on("data", (chunk) => body += chunk);
1756
+ req.on("end", async () => {
1757
+ try {
1758
+ const mockRequest = new Request(`http://${host}/oauth/consent`, {
1759
+ body,
1760
+ headers: {
1761
+ "Content-Type": "application/x-www-form-urlencoded"
1762
+ },
1763
+ method: "POST"
1764
+ });
1765
+ const response = await oauthProxy.handleConsent(mockRequest);
1766
+ const location = response.headers.get("Location");
1767
+ if (location) {
1768
+ res.writeHead(response.status, { Location: location }).end();
1769
+ } else {
1770
+ const text = await response.text();
1771
+ res.writeHead(response.status).end(text);
1772
+ }
1773
+ } catch (error) {
1774
+ res.writeHead(400, { "Content-Type": "application/json" }).end(
1775
+ JSON.stringify(
1776
+ _optionalChain([error, 'access', _50 => _50.toJSON, 'optionalCall', _51 => _51()]) || {
1777
+ error: "server_error"
1778
+ }
1779
+ )
1780
+ );
1781
+ }
1782
+ });
1783
+ return;
1784
+ }
1785
+ if (req.method === "POST" && url.pathname === "/oauth/token") {
1786
+ let body = "";
1787
+ req.on("data", (chunk) => body += chunk);
1788
+ req.on("end", async () => {
1789
+ try {
1790
+ const params = new URLSearchParams(body);
1791
+ const grantType = params.get("grant_type");
1792
+ const basicAuth = parseBasicAuthHeader(req.headers.authorization);
1793
+ const clientId = _optionalChain([basicAuth, 'optionalAccess', _52 => _52.clientId]) || params.get("client_id") || "";
1794
+ const clientSecret = _nullishCoalesce(_nullishCoalesce(_optionalChain([basicAuth, 'optionalAccess', _53 => _53.clientSecret]), () => ( params.get("client_secret"))), () => ( void 0));
1795
+ let response;
1796
+ if (grantType === "authorization_code") {
1797
+ response = await oauthProxy.exchangeAuthorizationCode({
1798
+ client_id: clientId,
1799
+ client_secret: clientSecret,
1800
+ code: params.get("code") || "",
1801
+ code_verifier: params.get("code_verifier") || void 0,
1802
+ grant_type: "authorization_code",
1803
+ redirect_uri: params.get("redirect_uri") || ""
1804
+ });
1805
+ } else if (grantType === "refresh_token") {
1806
+ response = await oauthProxy.exchangeRefreshToken({
1807
+ client_id: clientId,
1808
+ client_secret: clientSecret,
1809
+ grant_type: "refresh_token",
1810
+ refresh_token: params.get("refresh_token") || "",
1811
+ scope: params.get("scope") || void 0
1812
+ });
1813
+ } else {
1814
+ throw {
1815
+ statusCode: 400,
1816
+ toJSON: () => ({ error: "unsupported_grant_type" })
1817
+ };
1818
+ }
1819
+ res.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify(response));
1820
+ } catch (error) {
1821
+ const statusCode = error.statusCode || 400;
1822
+ res.writeHead(statusCode, { "Content-Type": "application/json" }).end(
1823
+ JSON.stringify(
1824
+ _optionalChain([error, 'access', _54 => _54.toJSON, 'optionalCall', _55 => _55()]) || {
1825
+ error: "invalid_request"
1826
+ }
1827
+ )
1828
+ );
1829
+ }
1830
+ });
1831
+ return;
1832
+ }
1833
+ } catch (error) {
1834
+ this.#logger.error("[FastMCP error] OAuth Proxy endpoint error", error);
1835
+ res.writeHead(500).end();
1836
+ return;
1837
+ }
1838
+ }
1839
+ res.writeHead(404).end();
1840
+ };
1841
+ #parseRuntimeConfig(overrides) {
1842
+ const args = process.argv.slice(2);
1843
+ const getArg = (name) => {
1844
+ const index = args.findIndex((arg) => arg === `--${name}`);
1845
+ return index !== -1 && index + 1 < args.length ? args[index + 1] : void 0;
1846
+ };
1847
+ const transportArg = getArg("transport");
1848
+ const portArg = getArg("port");
1849
+ const endpointArg = getArg("endpoint");
1850
+ const statelessArg = getArg("stateless");
1851
+ const hostArg = getArg("host");
1852
+ const envTransport = process.env.FASTMCP_TRANSPORT;
1853
+ const envPort = process.env.FASTMCP_PORT;
1854
+ const envEndpoint = process.env.FASTMCP_ENDPOINT;
1855
+ const envStateless = process.env.FASTMCP_STATELESS;
1856
+ const envHost = process.env.FASTMCP_HOST;
1857
+ const transportType = _optionalChain([overrides, 'optionalAccess', _56 => _56.transportType]) || (transportArg === "http-stream" ? "httpStream" : transportArg) || envTransport || "stdio";
1858
+ if (transportType === "httpStream") {
1859
+ const port = parseInt(
1860
+ _optionalChain([overrides, 'optionalAccess', _57 => _57.httpStream, 'optionalAccess', _58 => _58.port, 'optionalAccess', _59 => _59.toString, 'call', _60 => _60()]) || portArg || envPort || "8080"
1861
+ );
1862
+ const host = _optionalChain([overrides, 'optionalAccess', _61 => _61.httpStream, 'optionalAccess', _62 => _62.host]) || hostArg || envHost || "localhost";
1863
+ const endpoint = _optionalChain([overrides, 'optionalAccess', _63 => _63.httpStream, 'optionalAccess', _64 => _64.endpoint]) || endpointArg || envEndpoint || "/mcp";
1864
+ const enableJsonResponse = _optionalChain([overrides, 'optionalAccess', _65 => _65.httpStream, 'optionalAccess', _66 => _66.enableJsonResponse]) || false;
1865
+ const stateless = _optionalChain([overrides, 'optionalAccess', _67 => _67.httpStream, 'optionalAccess', _68 => _68.stateless]) || statelessArg === "true" || envStateless === "true" || false;
1866
+ return {
1867
+ httpStream: {
1868
+ enableJsonResponse,
1869
+ endpoint,
1870
+ host,
1871
+ port,
1872
+ stateless
1873
+ },
1874
+ transportType: "httpStream"
1875
+ };
1876
+ }
1877
+ return { transportType: "stdio" };
1878
+ }
1879
+ /**
1880
+ * Notifies all sessions that the prompts list has changed.
1881
+ */
1882
+ #promptsListChanged(prompts) {
1883
+ for (const session of this.#sessions) {
1884
+ session.promptsListChanged(prompts);
1885
+ }
1886
+ }
1887
+ #removeSession(session) {
1888
+ const sessionIndex = this.#sessions.indexOf(session);
1889
+ if (sessionIndex !== -1) {
1890
+ this.#sessions.splice(sessionIndex, 1);
1891
+ this.emit("disconnect", {
1892
+ session
1893
+ });
1894
+ }
1895
+ }
1896
+ /**
1897
+ * Notifies all sessions that the resources list has changed.
1898
+ */
1899
+ #resourcesListChanged(resources) {
1900
+ for (const session of this.#sessions) {
1901
+ session.resourcesListChanged(resources);
1902
+ }
1903
+ }
1904
+ /**
1905
+ * Notifies all sessions that the resource templates list has changed.
1906
+ */
1907
+ #resourceTemplatesListChanged(templates) {
1908
+ for (const session of this.#sessions) {
1909
+ session.resourceTemplatesListChanged(templates);
1910
+ }
1911
+ }
1912
+ /**
1913
+ * Notifies all sessions that the tools list has changed.
1914
+ */
1915
+ #toolsListChanged(tools) {
1916
+ for (const session of this.#sessions) {
1917
+ session.toolsListChanged(tools);
1918
+ }
1919
+ }
1920
+ };
1921
+
1922
+
1923
+
1924
+
1925
+
1926
+
1927
+
1928
+
1929
+
1930
+ exports.DiscoveryDocumentCache = DiscoveryDocumentCache; exports.FastMCP = FastMCP; exports.FastMCPSession = FastMCPSession; exports.ServerState = ServerState; exports.UnexpectedStateError = UnexpectedStateError; exports.UserError = UserError; exports.audioContent = audioContent; exports.imageContent = imageContent;
1931
+ //# sourceMappingURL=FastMCP.cjs.map