fastmcp 4.13.1 → 4.14.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 CHANGED
@@ -903,6 +903,52 @@ By default, ping behavior is optimized for each transport type:
903
903
 
904
904
  This configurable approach helps reduce log verbosity and optimize performance for different usage scenarios.
905
905
 
906
+ #### Keeping Long Tool Calls Alive (`streamKeepalive`)
907
+
908
+ Pings travel on the standalone server-to-client stream, so they never keep an
909
+ individual tool call's connection open — and in `stateless` mode that stream does
910
+ not exist at all. A tool that runs for minutes without producing output leaves
911
+ its response connection silent, and an idle-connection timeout in front of the
912
+ server (AWS ALB defaults to 60 seconds) closes it before the result is written.
913
+
914
+ This applies to **both** session modes. A stateful deployment keeps its
915
+ standalone stream warm with pings while the connection carrying the tool call
916
+ goes idle and is closed anyway; stateless has no standalone stream to begin
917
+ with.
918
+
919
+ `streamKeepalive` writes periodically to the in-flight tool call's own response
920
+ stream, which is the connection that would otherwise be closed. It is opt-in:
921
+
922
+ ```ts
923
+ const server = new FastMCP({
924
+ name: "My Server",
925
+ version: "1.0.0",
926
+ streamKeepalive: {
927
+ // Opt in; disabled by default
928
+ enabled: true,
929
+ // Keep comfortably below the shortest idle timeout on the path
930
+ intervalMs: 20000,
931
+ },
932
+ });
933
+ ```
934
+
935
+ Each keepalive is a `notifications/message` (level configurable via `logLevel`,
936
+ default `debug`) tagged with the logger `fastmcp-keepalive`, related to the tool
937
+ call being served. Keepalives start when a tool begins executing and stop when
938
+ the request stops waiting for it — on success, error, timeout, or client
939
+ cancellation — so idle connections stay quiet. Because the messages are related
940
+ to the request, this works in stateful and `stateless` mode alike, and needs no
941
+ client support beyond the standard logging notification.
942
+
943
+ Limits worth knowing:
944
+
945
+ - It has no effect with `httpStream.enableJsonResponse`, which buffers a single
946
+ JSON reply instead of streaming, so there is no open stream to write to.
947
+ - It only covers tool calls. Other long-running requests (`resources/read`,
948
+ `prompts/get`) still write nothing until they finish.
949
+ - On `stdio` there is no proxy to keep alive, so enabling it there only adds
950
+ notification traffic.
951
+
906
952
  ### Health-check Endpoint
907
953
 
908
954
  When you run FastMCP with the `httpStream` transport you can optionally expose a
package/dist/FastMCP.cjs CHANGED
@@ -11,7 +11,7 @@
11
11
 
12
12
 
13
13
 
14
- var _chunkO72VCMGVcjs = require('./chunk-O72VCMGV.cjs');
14
+ var _chunkB5WJ5VRVcjs = require('./chunk-B5WJ5VRV.cjs');
15
15
 
16
16
 
17
17
 
@@ -49,5 +49,5 @@ var _chunk5FVNY65Mcjs = require('./chunk-5FVNY65M.cjs');
49
49
 
50
50
 
51
51
 
52
- exports.AuthProvider = _chunk5FVNY65Mcjs.AuthProvider; exports.AzureProvider = _chunk5FVNY65Mcjs.AzureProvider; exports.DiscoveryDocumentCache = _chunkO72VCMGVcjs.DiscoveryDocumentCache; exports.FastMCP = _chunkO72VCMGVcjs.FastMCP; exports.FastMCPError = _chunkO72VCMGVcjs.FastMCPError; exports.FastMCPSession = _chunkO72VCMGVcjs.FastMCPSession; exports.GitHubProvider = _chunk5FVNY65Mcjs.GitHubProvider; exports.GoogleProvider = _chunk5FVNY65Mcjs.GoogleProvider; exports.MEDIA_FETCH_TIMEOUT_MS = _chunkO72VCMGVcjs.MEDIA_FETCH_TIMEOUT_MS; exports.OAuthProvider = _chunk5FVNY65Mcjs.OAuthProvider; exports.ServerState = _chunkO72VCMGVcjs.ServerState; exports.SessionError = _chunkO72VCMGVcjs.SessionError; exports.UnexpectedStateError = _chunkO72VCMGVcjs.UnexpectedStateError; exports.UserError = _chunkO72VCMGVcjs.UserError; exports.audioContent = _chunkO72VCMGVcjs.audioContent; exports.getAuthSession = _chunk5FVNY65Mcjs.getAuthSession; exports.imageContent = _chunkO72VCMGVcjs.imageContent; exports.jsonSchemaAdapter = _chunkO72VCMGVcjs.jsonSchemaAdapter; exports.requireAll = _chunk5FVNY65Mcjs.requireAll; exports.requireAny = _chunk5FVNY65Mcjs.requireAny; exports.requireAuth = _chunk5FVNY65Mcjs.requireAuth; exports.requireRole = _chunk5FVNY65Mcjs.requireRole; exports.requireScopes = _chunk5FVNY65Mcjs.requireScopes;
52
+ exports.AuthProvider = _chunk5FVNY65Mcjs.AuthProvider; exports.AzureProvider = _chunk5FVNY65Mcjs.AzureProvider; exports.DiscoveryDocumentCache = _chunkB5WJ5VRVcjs.DiscoveryDocumentCache; exports.FastMCP = _chunkB5WJ5VRVcjs.FastMCP; exports.FastMCPError = _chunkB5WJ5VRVcjs.FastMCPError; exports.FastMCPSession = _chunkB5WJ5VRVcjs.FastMCPSession; exports.GitHubProvider = _chunk5FVNY65Mcjs.GitHubProvider; exports.GoogleProvider = _chunk5FVNY65Mcjs.GoogleProvider; exports.MEDIA_FETCH_TIMEOUT_MS = _chunkB5WJ5VRVcjs.MEDIA_FETCH_TIMEOUT_MS; exports.OAuthProvider = _chunk5FVNY65Mcjs.OAuthProvider; exports.ServerState = _chunkB5WJ5VRVcjs.ServerState; exports.SessionError = _chunkB5WJ5VRVcjs.SessionError; exports.UnexpectedStateError = _chunkB5WJ5VRVcjs.UnexpectedStateError; exports.UserError = _chunkB5WJ5VRVcjs.UserError; exports.audioContent = _chunkB5WJ5VRVcjs.audioContent; exports.getAuthSession = _chunk5FVNY65Mcjs.getAuthSession; exports.imageContent = _chunkB5WJ5VRVcjs.imageContent; exports.jsonSchemaAdapter = _chunkB5WJ5VRVcjs.jsonSchemaAdapter; exports.requireAll = _chunk5FVNY65Mcjs.requireAll; exports.requireAny = _chunk5FVNY65Mcjs.requireAny; exports.requireAuth = _chunk5FVNY65Mcjs.requireAuth; exports.requireRole = _chunk5FVNY65Mcjs.requireRole; exports.requireScopes = _chunk5FVNY65Mcjs.requireScopes;
53
53
  //# sourceMappingURL=FastMCP.cjs.map
@@ -697,6 +697,36 @@ type ServerOptions<T extends FastMCPSessionAuth> = {
697
697
  */
698
698
  enabled?: boolean;
699
699
  };
700
+ /**
701
+ * Writes periodically to an in-flight tool call's own response stream, so a
702
+ * proxy or load balancer does not close the connection as idle while a
703
+ * long-running tool produces no output.
704
+ *
705
+ * Unlike {@link ServerOptions.ping}, these messages are related to the
706
+ * request being served, so they travel on that request's stream instead of
707
+ * the standalone server-to-client stream. That makes them the only option
708
+ * that works with `httpStream.stateless`, where no standing server-to-client
709
+ * stream exists.
710
+ */
711
+ streamKeepalive?: {
712
+ /**
713
+ * Whether to write keepalives. Opt-in.
714
+ * @default false
715
+ */
716
+ enabled?: boolean;
717
+ /**
718
+ * Interval between keepalives. Keep it comfortably below the shortest idle
719
+ * timeout on the path (AWS ALB defaults to 60s). Values below 1ms fall back
720
+ * to the default.
721
+ * @default 20000 (20s)
722
+ */
723
+ intervalMs?: number;
724
+ /**
725
+ * Level reported on the keepalive notification.
726
+ * @default 'debug'
727
+ */
728
+ logLevel?: LoggingLevel;
729
+ };
700
730
  /**
701
731
  * General utilities
702
732
  */
@@ -840,7 +870,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
840
870
  get server(): Server;
841
871
  get sessionId(): string | undefined;
842
872
  set sessionId(value: string | undefined);
843
- constructor({ auth, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, tools, transportType, utils, version, }: {
873
+ constructor({ auth, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, tools, transportType, utils, version, }: {
844
874
  auth?: T;
845
875
  instructions?: string;
846
876
  logger: Logger;
@@ -853,6 +883,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
853
883
  roots?: ServerOptions<T>["roots"];
854
884
  sessionId?: string;
855
885
  stateless?: boolean;
886
+ streamKeepalive?: ServerOptions<T>["streamKeepalive"];
856
887
  tools: Tool<T>[];
857
888
  transportType?: "httpStream" | "stdio";
858
889
  utils?: ServerOptions<T>["utils"];
package/dist/FastMCP.d.ts CHANGED
@@ -697,6 +697,36 @@ type ServerOptions<T extends FastMCPSessionAuth> = {
697
697
  */
698
698
  enabled?: boolean;
699
699
  };
700
+ /**
701
+ * Writes periodically to an in-flight tool call's own response stream, so a
702
+ * proxy or load balancer does not close the connection as idle while a
703
+ * long-running tool produces no output.
704
+ *
705
+ * Unlike {@link ServerOptions.ping}, these messages are related to the
706
+ * request being served, so they travel on that request's stream instead of
707
+ * the standalone server-to-client stream. That makes them the only option
708
+ * that works with `httpStream.stateless`, where no standing server-to-client
709
+ * stream exists.
710
+ */
711
+ streamKeepalive?: {
712
+ /**
713
+ * Whether to write keepalives. Opt-in.
714
+ * @default false
715
+ */
716
+ enabled?: boolean;
717
+ /**
718
+ * Interval between keepalives. Keep it comfortably below the shortest idle
719
+ * timeout on the path (AWS ALB defaults to 60s). Values below 1ms fall back
720
+ * to the default.
721
+ * @default 20000 (20s)
722
+ */
723
+ intervalMs?: number;
724
+ /**
725
+ * Level reported on the keepalive notification.
726
+ * @default 'debug'
727
+ */
728
+ logLevel?: LoggingLevel;
729
+ };
700
730
  /**
701
731
  * General utilities
702
732
  */
@@ -840,7 +870,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
840
870
  get server(): Server;
841
871
  get sessionId(): string | undefined;
842
872
  set sessionId(value: string | undefined);
843
- constructor({ auth, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, tools, transportType, utils, version, }: {
873
+ constructor({ auth, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, tools, transportType, utils, version, }: {
844
874
  auth?: T;
845
875
  instructions?: string;
846
876
  logger: Logger;
@@ -853,6 +883,7 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
853
883
  roots?: ServerOptions<T>["roots"];
854
884
  sessionId?: string;
855
885
  stateless?: boolean;
886
+ streamKeepalive?: ServerOptions<T>["streamKeepalive"];
856
887
  tools: Tool<T>[];
857
888
  transportType?: "httpStream" | "stdio";
858
889
  utils?: ServerOptions<T>["utils"];
package/dist/FastMCP.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  audioContent,
12
12
  imageContent,
13
13
  jsonSchemaAdapter
14
- } from "./chunk-3BMGHXXY.js";
14
+ } from "./chunk-SGCRCQNU.js";
15
15
  import {
16
16
  AuthProvider,
17
17
  AzureProvider,