@prefecthq/fastmcp-ts 1.5.1 → 1.5.2
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/dist/cli/index.cjs +16 -3
- package/dist/cli/index.cjs.map +1 -1
- package/dist/client.d.ts +5 -0
- package/dist/client.js +13 -0
- package/dist/client.js.map +1 -1
- package/dist/server.d.ts +24 -24
- package/dist/server.js +36 -28
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
package/dist/server.d.ts
CHANGED
|
@@ -1054,6 +1054,7 @@ declare class FastMCP {
|
|
|
1054
1054
|
private _primaryServer;
|
|
1055
1055
|
private _stdioServer;
|
|
1056
1056
|
private _stdioState;
|
|
1057
|
+
private _stdioModern;
|
|
1057
1058
|
private _stdioHandle;
|
|
1058
1059
|
private _modernHandler;
|
|
1059
1060
|
private _statelessLegacyHandler;
|
|
@@ -1067,32 +1068,28 @@ declare class FastMCP {
|
|
|
1067
1068
|
/**
|
|
1068
1069
|
* Create a new Server instance with all request handlers wired up.
|
|
1069
1070
|
*
|
|
1070
|
-
* `
|
|
1071
|
-
* `resources/subscribe`/`unsubscribe` RPCs
|
|
1072
|
-
*
|
|
1073
|
-
*
|
|
1074
|
-
*
|
|
1075
|
-
*
|
|
1076
|
-
* legacy
|
|
1077
|
-
*
|
|
1078
|
-
*
|
|
1079
|
-
* calls the factory once the opening exchange has classified the era, so
|
|
1080
|
-
* the modern-vs-legacy choice is already known at construction time) and
|
|
1081
|
-
* passes it straight through as `opts.modern`.
|
|
1071
|
+
* `resources.subscribe` is advertised on both eras. On legacy it gates the
|
|
1072
|
+
* `resources/subscribe`/`unsubscribe` RPCs. On modern (2026-07-28) the same
|
|
1073
|
+
* capability gates the `subscriptions/listen` `resourceSubscriptions`
|
|
1074
|
+
* filter: the SDK's listen routers silently prune the filter from the
|
|
1075
|
+
* honored subset when the serving entry's capabilities omit `subscribe`,
|
|
1076
|
+
* so a modern server that supports per-resource updates MUST advertise it
|
|
1077
|
+
* (issue #88). The legacy RPCs are still physically absent from the modern
|
|
1078
|
+
* wire registry, so advertising the capability leaks no legacy-only
|
|
1079
|
+
* surface to a modern client.
|
|
1082
1080
|
*
|
|
1083
|
-
* The `completions` capability
|
|
1084
|
-
* BOTH era wire registries (the legacy 2025-11-25 registry and the
|
|
1085
|
-
* 2026-07-28 `dispatchRequestSchemas`), and `completions` is a valid
|
|
1086
|
-
* both eras' ServerCapabilities schemas
|
|
1087
|
-
*
|
|
1088
|
-
*
|
|
1089
|
-
*
|
|
1090
|
-
* `completion/complete` handler (`assertRequestHandlerCapability`).
|
|
1081
|
+
* The `completions` capability follows the same shape: `completion/complete`
|
|
1082
|
+
* is in BOTH era wire registries (the legacy 2025-11-25 registry and the
|
|
1083
|
+
* modern 2026-07-28 `dispatchRequestSchemas`), and `completions` is a valid
|
|
1084
|
+
* key in both eras' ServerCapabilities schemas, so it is declared
|
|
1085
|
+
* unconditionally. The SDK also requires this capability to be present to
|
|
1086
|
+
* register the `completion/complete` handler
|
|
1087
|
+
* (`assertRequestHandlerCapability`).
|
|
1091
1088
|
*
|
|
1092
|
-
* `stateless` withdraws the
|
|
1093
|
-
*
|
|
1094
|
-
*
|
|
1095
|
-
*
|
|
1089
|
+
* `stateless` withdraws the `resources.subscribe` capability. A stateless
|
|
1090
|
+
* server has no session for a subscription to live in and no channel to
|
|
1091
|
+
* deliver `notifications/resources/updated` on, so it must not claim the
|
|
1092
|
+
* capability.
|
|
1096
1093
|
*/
|
|
1097
1094
|
private _makeServer;
|
|
1098
1095
|
private _resolveToken;
|
|
@@ -1126,6 +1123,9 @@ declare class FastMCP {
|
|
|
1126
1123
|
* per-stream filtering, delivering only to `subscriptions/listen` streams that
|
|
1127
1124
|
* opted in to this URI. Optional chaining keeps it a no-op until the first
|
|
1128
1125
|
* modern HTTP request has actually built the handler.
|
|
1126
|
+
* - A modern stdio connection is sent the notification unconditionally; the
|
|
1127
|
+
* SDK's stdio listen router intercepts it and fans out per honored
|
|
1128
|
+
* subscription (or drops it when no stream opted in to the URI).
|
|
1129
1129
|
*
|
|
1130
1130
|
* Unsubscribed sessions (and the modern streams that never opted in) receive
|
|
1131
1131
|
* nothing, so calling this for a URI with no subscribers is safe and cheap.
|
package/dist/server.js
CHANGED
|
@@ -1081,6 +1081,9 @@ var FastMCP = class {
|
|
|
1081
1081
|
// Holds this connection's resource-subscription set; read by the resource-updated
|
|
1082
1082
|
// fan-out. Null unless serving stdio.
|
|
1083
1083
|
_stdioState = null;
|
|
1084
|
+
// Whether the current stdio connection negotiated the modern (2026-07-28) era.
|
|
1085
|
+
// Set by run()'s stdio factory; drives notifyResourceUpdated's stdio branch.
|
|
1086
|
+
_stdioModern = false;
|
|
1084
1087
|
_stdioHandle = null;
|
|
1085
1088
|
// Modern (2026-07-28) HTTP handler — one per FastMCP instance, lazily created.
|
|
1086
1089
|
// Builds a fresh Server (via _makeServer) per request; see createMcpHandler.
|
|
@@ -1124,32 +1127,28 @@ var FastMCP = class {
|
|
|
1124
1127
|
/**
|
|
1125
1128
|
* Create a new Server instance with all request handlers wired up.
|
|
1126
1129
|
*
|
|
1127
|
-
* `
|
|
1128
|
-
* `resources/subscribe`/`unsubscribe` RPCs
|
|
1129
|
-
*
|
|
1130
|
-
*
|
|
1131
|
-
*
|
|
1132
|
-
*
|
|
1133
|
-
* legacy
|
|
1134
|
-
*
|
|
1135
|
-
*
|
|
1136
|
-
* calls the factory once the opening exchange has classified the era, so
|
|
1137
|
-
* the modern-vs-legacy choice is already known at construction time) and
|
|
1138
|
-
* passes it straight through as `opts.modern`.
|
|
1130
|
+
* `resources.subscribe` is advertised on both eras. On legacy it gates the
|
|
1131
|
+
* `resources/subscribe`/`unsubscribe` RPCs. On modern (2026-07-28) the same
|
|
1132
|
+
* capability gates the `subscriptions/listen` `resourceSubscriptions`
|
|
1133
|
+
* filter: the SDK's listen routers silently prune the filter from the
|
|
1134
|
+
* honored subset when the serving entry's capabilities omit `subscribe`,
|
|
1135
|
+
* so a modern server that supports per-resource updates MUST advertise it
|
|
1136
|
+
* (issue #88). The legacy RPCs are still physically absent from the modern
|
|
1137
|
+
* wire registry, so advertising the capability leaks no legacy-only
|
|
1138
|
+
* surface to a modern client.
|
|
1139
1139
|
*
|
|
1140
|
-
* The `completions` capability
|
|
1141
|
-
* BOTH era wire registries (the legacy 2025-11-25 registry and the
|
|
1142
|
-
* 2026-07-28 `dispatchRequestSchemas`), and `completions` is a valid
|
|
1143
|
-
* both eras' ServerCapabilities schemas
|
|
1144
|
-
*
|
|
1145
|
-
*
|
|
1146
|
-
*
|
|
1147
|
-
* `completion/complete` handler (`assertRequestHandlerCapability`).
|
|
1140
|
+
* The `completions` capability follows the same shape: `completion/complete`
|
|
1141
|
+
* is in BOTH era wire registries (the legacy 2025-11-25 registry and the
|
|
1142
|
+
* modern 2026-07-28 `dispatchRequestSchemas`), and `completions` is a valid
|
|
1143
|
+
* key in both eras' ServerCapabilities schemas, so it is declared
|
|
1144
|
+
* unconditionally. The SDK also requires this capability to be present to
|
|
1145
|
+
* register the `completion/complete` handler
|
|
1146
|
+
* (`assertRequestHandlerCapability`).
|
|
1148
1147
|
*
|
|
1149
|
-
* `stateless` withdraws the
|
|
1150
|
-
*
|
|
1151
|
-
*
|
|
1152
|
-
*
|
|
1148
|
+
* `stateless` withdraws the `resources.subscribe` capability. A stateless
|
|
1149
|
+
* server has no session for a subscription to live in and no channel to
|
|
1150
|
+
* deliver `notifications/resources/updated` on, so it must not claim the
|
|
1151
|
+
* capability.
|
|
1153
1152
|
*/
|
|
1154
1153
|
_makeServer(sessionState, opts) {
|
|
1155
1154
|
const state = sessionState ?? this._primaryState;
|
|
@@ -1157,7 +1156,7 @@ var FastMCP = class {
|
|
|
1157
1156
|
const server = new Server2(
|
|
1158
1157
|
{ name: this.name, version: this.version },
|
|
1159
1158
|
{
|
|
1160
|
-
capabilities: { tools: { listChanged: true }, resources: { listChanged: true, ...opts?.
|
|
1159
|
+
capabilities: { tools: { listChanged: true }, resources: { listChanged: true, ...opts?.stateless ? {} : { subscribe: true } }, prompts: { listChanged: true }, logging: {}, completions: {}, ...extensions ? { extensions } : {} },
|
|
1161
1160
|
...this._cacheHints ? { cacheHints: this._cacheHints } : {},
|
|
1162
1161
|
...this._requestStateCodec ? { requestState: { verify: this._requestStateCodec.verify.bind(this._requestStateCodec) } } : {},
|
|
1163
1162
|
...this._inputRequiredOptions ? { inputRequired: this._inputRequiredOptions } : {}
|
|
@@ -1749,6 +1748,9 @@ var FastMCP = class {
|
|
|
1749
1748
|
* per-stream filtering, delivering only to `subscriptions/listen` streams that
|
|
1750
1749
|
* opted in to this URI. Optional chaining keeps it a no-op until the first
|
|
1751
1750
|
* modern HTTP request has actually built the handler.
|
|
1751
|
+
* - A modern stdio connection is sent the notification unconditionally; the
|
|
1752
|
+
* SDK's stdio listen router intercepts it and fans out per honored
|
|
1753
|
+
* subscription (or drops it when no stream opted in to the URI).
|
|
1752
1754
|
*
|
|
1753
1755
|
* Unsubscribed sessions (and the modern streams that never opted in) receive
|
|
1754
1756
|
* nothing, so calling this for a URI with no subscribers is safe and cheap.
|
|
@@ -1760,7 +1762,11 @@ var FastMCP = class {
|
|
|
1760
1762
|
});
|
|
1761
1763
|
};
|
|
1762
1764
|
pushIfSubscribed(this._primaryServer, this._primaryState);
|
|
1763
|
-
if (this._stdioServer)
|
|
1765
|
+
if (this._stdioServer) {
|
|
1766
|
+
if (this._stdioModern) this._stdioServer.sendResourceUpdated({ uri }).catch(() => {
|
|
1767
|
+
});
|
|
1768
|
+
else pushIfSubscribed(this._stdioServer, this._stdioState);
|
|
1769
|
+
}
|
|
1764
1770
|
for (const { server, state } of this._sessions.values()) pushIfSubscribed(server, state);
|
|
1765
1771
|
this._modernHandler?.notify.resourceUpdated(uri);
|
|
1766
1772
|
}
|
|
@@ -2280,7 +2286,8 @@ var FastMCP = class {
|
|
|
2280
2286
|
(ctx) => {
|
|
2281
2287
|
const stdioState = /* @__PURE__ */ new Map();
|
|
2282
2288
|
this._stdioState = stdioState;
|
|
2283
|
-
this.
|
|
2289
|
+
this._stdioModern = ctx.era === "modern";
|
|
2290
|
+
this._stdioServer = this._makeServer(stdioState);
|
|
2284
2291
|
return this._stdioServer;
|
|
2285
2292
|
},
|
|
2286
2293
|
{ transport: stdioTransport }
|
|
@@ -2317,7 +2324,7 @@ var FastMCP = class {
|
|
|
2317
2324
|
* session state and server-initiated-request shim for run()'s default HTTP path. */
|
|
2318
2325
|
_getModernHandler() {
|
|
2319
2326
|
if (!this._modernHandler) {
|
|
2320
|
-
this._modernHandler = createMcpHandler(() => this._makeServer(/* @__PURE__ */ new Map()
|
|
2327
|
+
this._modernHandler = createMcpHandler(() => this._makeServer(/* @__PURE__ */ new Map()), {
|
|
2321
2328
|
legacy: "reject",
|
|
2322
2329
|
...this._eventBus ? { bus: this._eventBus } : {}
|
|
2323
2330
|
});
|
|
@@ -2585,6 +2592,7 @@ var FastMCP = class {
|
|
|
2585
2592
|
this._stdioHandle = null;
|
|
2586
2593
|
this._stdioServer = null;
|
|
2587
2594
|
this._stdioState = null;
|
|
2595
|
+
this._stdioModern = false;
|
|
2588
2596
|
}
|
|
2589
2597
|
if (this._httpServer) {
|
|
2590
2598
|
await new Promise((resolve, reject) => {
|