fastmcp 4.7.2 → 4.8.1
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 +20 -0
- package/dist/FastMCP.cjs +2 -2
- package/dist/FastMCP.d.cts +20 -0
- package/dist/FastMCP.d.ts +20 -0
- package/dist/FastMCP.js +1 -1
- package/dist/{chunk-KAGSBU3Z.js → chunk-2PFUZL7I.js} +74 -4
- package/dist/chunk-2PFUZL7I.js.map +1 -0
- package/dist/{chunk-553XY3CA.cjs → chunk-MJCWKCHZ.cjs} +73 -3
- package/dist/chunk-MJCWKCHZ.cjs.map +1 -0
- package/dist/examples/custom-routes.cjs +2 -2
- package/dist/examples/custom-routes.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-553XY3CA.cjs.map +0 -1
- package/dist/chunk-KAGSBU3Z.js.map +0 -1
package/README.md
CHANGED
|
@@ -1406,6 +1406,26 @@ server.addResource({
|
|
|
1406
1406
|
});
|
|
1407
1407
|
```
|
|
1408
1408
|
|
|
1409
|
+
#### Subscribing to resource updates
|
|
1410
|
+
|
|
1411
|
+
Clients can subscribe to a resource with the MCP [`resources/subscribe`](https://modelcontextprotocol.io/specification/2025-06-18/server/resources#subscriptions) method to be notified whenever its contents change. FastMCP advertises the `subscribe` capability automatically for any server that exposes resources, tracks each client's subscriptions, and lets you emit an update with `sendResourceUpdated`:
|
|
1412
|
+
|
|
1413
|
+
```ts
|
|
1414
|
+
server.addResource({
|
|
1415
|
+
uri: "file:///logs/app.log",
|
|
1416
|
+
name: "Application Logs",
|
|
1417
|
+
mimeType: "text/plain",
|
|
1418
|
+
async load() {
|
|
1419
|
+
return { text: await readLogFile() };
|
|
1420
|
+
},
|
|
1421
|
+
});
|
|
1422
|
+
|
|
1423
|
+
// Whenever the underlying data changes, notify subscribed clients:
|
|
1424
|
+
await server.sendResourceUpdated("file:///logs/app.log");
|
|
1425
|
+
```
|
|
1426
|
+
|
|
1427
|
+
`sendResourceUpdated` only notifies clients that have subscribed to the given URI, so it is safe to call whenever your data changes. FastMCP also advertises the `listChanged` capability for resources and prompts and emits `notifications/resources/list_changed` / `notifications/prompts/list_changed` automatically when you add or remove resources, resource templates, or prompts at runtime.
|
|
1428
|
+
|
|
1409
1429
|
### Resource templates
|
|
1410
1430
|
|
|
1411
1431
|
You can also define resource templates:
|
package/dist/FastMCP.cjs
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _chunkMJCWKCHZcjs = require('./chunk-MJCWKCHZ.cjs');
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
@@ -41,5 +41,5 @@ var _chunkIX3HKAX4cjs = require('./chunk-IX3HKAX4.cjs');
|
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
|
|
44
|
-
exports.AuthProvider = _chunkIX3HKAX4cjs.AuthProvider; exports.AzureProvider = _chunkIX3HKAX4cjs.AzureProvider; exports.DiscoveryDocumentCache =
|
|
44
|
+
exports.AuthProvider = _chunkIX3HKAX4cjs.AuthProvider; exports.AzureProvider = _chunkIX3HKAX4cjs.AzureProvider; exports.DiscoveryDocumentCache = _chunkMJCWKCHZcjs.DiscoveryDocumentCache; exports.FastMCP = _chunkMJCWKCHZcjs.FastMCP; exports.FastMCPSession = _chunkMJCWKCHZcjs.FastMCPSession; exports.GitHubProvider = _chunkIX3HKAX4cjs.GitHubProvider; exports.GoogleProvider = _chunkIX3HKAX4cjs.GoogleProvider; exports.OAuthProvider = _chunkIX3HKAX4cjs.OAuthProvider; exports.ServerState = _chunkMJCWKCHZcjs.ServerState; exports.UnexpectedStateError = _chunkMJCWKCHZcjs.UnexpectedStateError; exports.UserError = _chunkMJCWKCHZcjs.UserError; exports.audioContent = _chunkMJCWKCHZcjs.audioContent; exports.getAuthSession = _chunkIX3HKAX4cjs.getAuthSession; exports.imageContent = _chunkMJCWKCHZcjs.imageContent; exports.requireAll = _chunkIX3HKAX4cjs.requireAll; exports.requireAny = _chunkIX3HKAX4cjs.requireAny; exports.requireAuth = _chunkIX3HKAX4cjs.requireAuth; exports.requireRole = _chunkIX3HKAX4cjs.requireRole; exports.requireScopes = _chunkIX3HKAX4cjs.requireScopes;
|
|
45
45
|
//# sourceMappingURL=FastMCP.cjs.map
|
package/dist/FastMCP.d.cts
CHANGED
|
@@ -750,6 +750,14 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
|
|
|
750
750
|
requestSampling(message: z.infer<typeof CreateMessageRequestSchema>["params"], options?: RequestOptions): Promise<SamplingResponse>;
|
|
751
751
|
resourcesListChanged(resources: Resource<T>[]): void;
|
|
752
752
|
resourceTemplatesListChanged(resourceTemplates: ResourceTemplate<T>[]): void;
|
|
753
|
+
/**
|
|
754
|
+
* Notifies the connected client that the contents of a resource have changed.
|
|
755
|
+
*
|
|
756
|
+
* The `notifications/resources/updated` notification is only sent when the
|
|
757
|
+
* client has subscribed to the URI via `resources/subscribe`; otherwise this
|
|
758
|
+
* is a no-op.
|
|
759
|
+
*/
|
|
760
|
+
sendResourceUpdated(uri: string): Promise<void>;
|
|
753
761
|
toolsListChanged(tools: Tool<T>[]): void;
|
|
754
762
|
triggerListChangedNotification(method: string): Promise<void>;
|
|
755
763
|
/**
|
|
@@ -766,6 +774,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
|
|
|
766
774
|
private setupLoggingHandlers;
|
|
767
775
|
private setupPromptHandlers;
|
|
768
776
|
private setupResourceHandlers;
|
|
777
|
+
private setupResourceSubscriptionHandlers;
|
|
769
778
|
private setupResourceTemplateHandlers;
|
|
770
779
|
private setupRootsHandlers;
|
|
771
780
|
private setupToolHandlers;
|
|
@@ -874,6 +883,17 @@ declare class FastMCP<T extends FastMCPSessionAuth = FastMCPSessionAuth> extends
|
|
|
874
883
|
* Removes tools from the server.
|
|
875
884
|
*/
|
|
876
885
|
removeTools(names: string[]): void;
|
|
886
|
+
/**
|
|
887
|
+
* Notifies subscribed clients that a resource's contents have changed.
|
|
888
|
+
*
|
|
889
|
+
* Sends a `notifications/resources/updated` notification to every connected
|
|
890
|
+
* session that has subscribed to `uri` via `resources/subscribe`. Sessions
|
|
891
|
+
* that have not subscribed to the URI are skipped, so it is safe to call this
|
|
892
|
+
* whenever the underlying data changes.
|
|
893
|
+
*
|
|
894
|
+
* @param uri - The URI of the resource whose contents changed.
|
|
895
|
+
*/
|
|
896
|
+
sendResourceUpdated(uri: string): Promise<void>;
|
|
877
897
|
/**
|
|
878
898
|
* Starts the server.
|
|
879
899
|
*/
|
package/dist/FastMCP.d.ts
CHANGED
|
@@ -750,6 +750,14 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
|
|
|
750
750
|
requestSampling(message: z.infer<typeof CreateMessageRequestSchema>["params"], options?: RequestOptions): Promise<SamplingResponse>;
|
|
751
751
|
resourcesListChanged(resources: Resource<T>[]): void;
|
|
752
752
|
resourceTemplatesListChanged(resourceTemplates: ResourceTemplate<T>[]): void;
|
|
753
|
+
/**
|
|
754
|
+
* Notifies the connected client that the contents of a resource have changed.
|
|
755
|
+
*
|
|
756
|
+
* The `notifications/resources/updated` notification is only sent when the
|
|
757
|
+
* client has subscribed to the URI via `resources/subscribe`; otherwise this
|
|
758
|
+
* is a no-op.
|
|
759
|
+
*/
|
|
760
|
+
sendResourceUpdated(uri: string): Promise<void>;
|
|
753
761
|
toolsListChanged(tools: Tool<T>[]): void;
|
|
754
762
|
triggerListChangedNotification(method: string): Promise<void>;
|
|
755
763
|
/**
|
|
@@ -766,6 +774,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
|
|
|
766
774
|
private setupLoggingHandlers;
|
|
767
775
|
private setupPromptHandlers;
|
|
768
776
|
private setupResourceHandlers;
|
|
777
|
+
private setupResourceSubscriptionHandlers;
|
|
769
778
|
private setupResourceTemplateHandlers;
|
|
770
779
|
private setupRootsHandlers;
|
|
771
780
|
private setupToolHandlers;
|
|
@@ -874,6 +883,17 @@ declare class FastMCP<T extends FastMCPSessionAuth = FastMCPSessionAuth> extends
|
|
|
874
883
|
* Removes tools from the server.
|
|
875
884
|
*/
|
|
876
885
|
removeTools(names: string[]): void;
|
|
886
|
+
/**
|
|
887
|
+
* Notifies subscribed clients that a resource's contents have changed.
|
|
888
|
+
*
|
|
889
|
+
* Sends a `notifications/resources/updated` notification to every connected
|
|
890
|
+
* session that has subscribed to `uri` via `resources/subscribe`. Sessions
|
|
891
|
+
* that have not subscribed to the URI are skipped, so it is safe to call this
|
|
892
|
+
* whenever the underlying data changes.
|
|
893
|
+
*
|
|
894
|
+
* @param uri - The URI of the resource whose contents changed.
|
|
895
|
+
*/
|
|
896
|
+
sendResourceUpdated(uri: string): Promise<void>;
|
|
877
897
|
/**
|
|
878
898
|
* Starts the server.
|
|
879
899
|
*/
|
package/dist/FastMCP.js
CHANGED
|
@@ -13,7 +13,9 @@ import {
|
|
|
13
13
|
McpError,
|
|
14
14
|
ReadResourceRequestSchema,
|
|
15
15
|
RootsListChangedNotificationSchema,
|
|
16
|
-
SetLevelRequestSchema
|
|
16
|
+
SetLevelRequestSchema,
|
|
17
|
+
SubscribeRequestSchema,
|
|
18
|
+
UnsubscribeRequestSchema
|
|
17
19
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
18
20
|
import { EventEmitter } from "events";
|
|
19
21
|
import { readFile } from "fs/promises";
|
|
@@ -357,6 +359,12 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
357
359
|
* Used to track per-session state across multiple requests.
|
|
358
360
|
*/
|
|
359
361
|
#sessionId;
|
|
362
|
+
/**
|
|
363
|
+
* Resource URIs the connected client has subscribed to via
|
|
364
|
+
* `resources/subscribe`. Used to scope `notifications/resources/updated`
|
|
365
|
+
* to interested clients only.
|
|
366
|
+
*/
|
|
367
|
+
#subscriptions = /* @__PURE__ */ new Set();
|
|
360
368
|
#utils;
|
|
361
369
|
constructor({
|
|
362
370
|
auth,
|
|
@@ -387,13 +395,13 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
387
395
|
this.#capabilities.tools = {};
|
|
388
396
|
}
|
|
389
397
|
if (resources.length || resourcesTemplates.length) {
|
|
390
|
-
this.#capabilities.resources = {};
|
|
398
|
+
this.#capabilities.resources = { listChanged: true, subscribe: true };
|
|
391
399
|
}
|
|
392
400
|
if (prompts.length) {
|
|
393
401
|
for (const prompt of prompts) {
|
|
394
402
|
this.addPrompt(prompt);
|
|
395
403
|
}
|
|
396
|
-
this.#capabilities.prompts = {};
|
|
404
|
+
this.#capabilities.prompts = { listChanged: true };
|
|
397
405
|
}
|
|
398
406
|
this.#capabilities.logging = {};
|
|
399
407
|
this.#capabilities.completions = {};
|
|
@@ -414,6 +422,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
414
422
|
this.addResource(resource);
|
|
415
423
|
}
|
|
416
424
|
this.setupResourceHandlers();
|
|
425
|
+
this.setupResourceSubscriptionHandlers();
|
|
417
426
|
if (resourcesTemplates.length) {
|
|
418
427
|
for (const resourceTemplate of resourcesTemplates) {
|
|
419
428
|
this.addResourceTemplate(resourceTemplate);
|
|
@@ -549,6 +558,27 @@ ${e instanceof Error ? e.stack : JSON.stringify(e)}`
|
|
|
549
558
|
this.setupResourceTemplateHandlers();
|
|
550
559
|
this.triggerListChangedNotification("notifications/resources/list_changed");
|
|
551
560
|
}
|
|
561
|
+
/**
|
|
562
|
+
* Notifies the connected client that the contents of a resource have changed.
|
|
563
|
+
*
|
|
564
|
+
* The `notifications/resources/updated` notification is only sent when the
|
|
565
|
+
* client has subscribed to the URI via `resources/subscribe`; otherwise this
|
|
566
|
+
* is a no-op.
|
|
567
|
+
*/
|
|
568
|
+
async sendResourceUpdated(uri) {
|
|
569
|
+
if (!this.#subscriptions.has(uri)) {
|
|
570
|
+
return;
|
|
571
|
+
}
|
|
572
|
+
try {
|
|
573
|
+
await this.#server.sendResourceUpdated({ uri });
|
|
574
|
+
} catch (error) {
|
|
575
|
+
this.#logger.error(
|
|
576
|
+
`[FastMCP error] failed to send resources/updated notification for '${uri}'.
|
|
577
|
+
|
|
578
|
+
${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
579
|
+
);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
552
582
|
toolsListChanged(tools) {
|
|
553
583
|
const allowedTools = tools.filter(
|
|
554
584
|
(tool) => tool.canAccess ? tool.canAccess(this.#auth) : true
|
|
@@ -997,6 +1027,16 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
997
1027
|
}
|
|
998
1028
|
);
|
|
999
1029
|
}
|
|
1030
|
+
setupResourceSubscriptionHandlers() {
|
|
1031
|
+
this.#server.setRequestHandler(SubscribeRequestSchema, (request) => {
|
|
1032
|
+
this.#subscriptions.add(request.params.uri);
|
|
1033
|
+
return {};
|
|
1034
|
+
});
|
|
1035
|
+
this.#server.setRequestHandler(UnsubscribeRequestSchema, (request) => {
|
|
1036
|
+
this.#subscriptions.delete(request.params.uri);
|
|
1037
|
+
return {};
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1000
1040
|
setupResourceTemplateHandlers() {
|
|
1001
1041
|
let cachedResourceTemplatesList = null;
|
|
1002
1042
|
this.#server.setRequestHandler(
|
|
@@ -1599,6 +1639,21 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
1599
1639
|
this.#toolsListChanged(this.#tools);
|
|
1600
1640
|
}
|
|
1601
1641
|
}
|
|
1642
|
+
/**
|
|
1643
|
+
* Notifies subscribed clients that a resource's contents have changed.
|
|
1644
|
+
*
|
|
1645
|
+
* Sends a `notifications/resources/updated` notification to every connected
|
|
1646
|
+
* session that has subscribed to `uri` via `resources/subscribe`. Sessions
|
|
1647
|
+
* that have not subscribed to the URI are skipped, so it is safe to call this
|
|
1648
|
+
* whenever the underlying data changes.
|
|
1649
|
+
*
|
|
1650
|
+
* @param uri - The URI of the resource whose contents changed.
|
|
1651
|
+
*/
|
|
1652
|
+
async sendResourceUpdated(uri) {
|
|
1653
|
+
await Promise.all(
|
|
1654
|
+
this.#sessions.map((session) => session.sendResourceUpdated(uri))
|
|
1655
|
+
);
|
|
1656
|
+
}
|
|
1602
1657
|
/**
|
|
1603
1658
|
* Starts the server.
|
|
1604
1659
|
*/
|
|
@@ -1636,6 +1691,17 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
1636
1691
|
version: this.#options.version
|
|
1637
1692
|
});
|
|
1638
1693
|
await session.connect(transport);
|
|
1694
|
+
let stdinClosed = false;
|
|
1695
|
+
const onStdinClose = () => {
|
|
1696
|
+
if (stdinClosed) return;
|
|
1697
|
+
stdinClosed = true;
|
|
1698
|
+
process.stdin.off("close", onStdinClose);
|
|
1699
|
+
process.stdin.off("end", onStdinClose);
|
|
1700
|
+
transport.close().catch(() => {
|
|
1701
|
+
});
|
|
1702
|
+
};
|
|
1703
|
+
process.stdin.on("close", onStdinClose);
|
|
1704
|
+
process.stdin.on("end", onStdinClose);
|
|
1639
1705
|
this.#sessions.push(session);
|
|
1640
1706
|
session.once("error", () => {
|
|
1641
1707
|
this.#removeSession(session);
|
|
@@ -1643,6 +1709,8 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
1643
1709
|
if (transport.onclose) {
|
|
1644
1710
|
const originalOnClose = transport.onclose;
|
|
1645
1711
|
transport.onclose = () => {
|
|
1712
|
+
process.stdin.off("close", onStdinClose);
|
|
1713
|
+
process.stdin.off("end", onStdinClose);
|
|
1646
1714
|
this.#removeSession(session);
|
|
1647
1715
|
if (originalOnClose) {
|
|
1648
1716
|
originalOnClose();
|
|
@@ -1650,6 +1718,8 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
1650
1718
|
};
|
|
1651
1719
|
} else {
|
|
1652
1720
|
transport.onclose = () => {
|
|
1721
|
+
process.stdin.off("close", onStdinClose);
|
|
1722
|
+
process.stdin.off("end", onStdinClose);
|
|
1653
1723
|
this.#removeSession(session);
|
|
1654
1724
|
};
|
|
1655
1725
|
}
|
|
@@ -2296,4 +2366,4 @@ export {
|
|
|
2296
2366
|
FastMCPSession,
|
|
2297
2367
|
FastMCP
|
|
2298
2368
|
};
|
|
2299
|
-
//# sourceMappingURL=chunk-
|
|
2369
|
+
//# sourceMappingURL=chunk-2PFUZL7I.js.map
|