fastmcp 1.27.7 → 2.1.0
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 +132 -31
- package/dist/FastMCP.d.ts +41 -9
- package/dist/FastMCP.js +38 -46
- package/dist/FastMCP.js.map +1 -1
- package/jsr.json +1 -1
- package/package.json +9 -9
- package/src/FastMCP.test.ts +123 -26
- package/src/FastMCP.ts +106 -56
- package/src/examples/addition.ts +40 -4
package/README.md
CHANGED
|
@@ -15,14 +15,15 @@ A TypeScript framework for building [MCP](https://glama.ai/mcp) servers capable
|
|
|
15
15
|
- [Audio content](#returning-an-audio)
|
|
16
16
|
- [Logging](#logging)
|
|
17
17
|
- [Error handling](#errors)
|
|
18
|
-
- [
|
|
19
|
-
- [HTTP Streaming](#http-streaming)
|
|
18
|
+
- [HTTP Streaming](#http-streaming) (with SSE compatibility)
|
|
20
19
|
- CORS (enabled by default)
|
|
21
20
|
- [Progress notifications](#progress)
|
|
21
|
+
- [Streaming output](#streaming-output)
|
|
22
22
|
- [Typed server events](#typed-server-events)
|
|
23
23
|
- [Prompt argument auto-completion](#prompt-argument-auto-completion)
|
|
24
24
|
- [Sampling](#requestsampling)
|
|
25
25
|
- [Configurable ping behavior](#configurable-ping-behavior)
|
|
26
|
+
- [Health-check endpoint](#health-check-endpoint)
|
|
26
27
|
- [Roots](#roots-management)
|
|
27
28
|
- CLI for [testing](#test-with-mcp-cli) and [debugging](#inspect-with-mcp-inspector)
|
|
28
29
|
|
|
@@ -87,24 +88,6 @@ If you are looking for a boilerplate repository to build your own MCP server, ch
|
|
|
87
88
|
|
|
88
89
|
FastMCP supports multiple transport options for remote communication, allowing an MCP hosted on a remote machine to be accessed over the network.
|
|
89
90
|
|
|
90
|
-
#### SSE
|
|
91
|
-
|
|
92
|
-
[Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events) (SSE) provide a mechanism for servers to send real-time updates to clients over an HTTPS connection.
|
|
93
|
-
|
|
94
|
-
You can run the server with SSE support:
|
|
95
|
-
|
|
96
|
-
```ts
|
|
97
|
-
server.start({
|
|
98
|
-
transportType: "sse",
|
|
99
|
-
sse: {
|
|
100
|
-
endpoint: "/sse",
|
|
101
|
-
port: 8080,
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
This will start the server and listen for SSE connections on `http://localhost:8080/sse`.
|
|
107
|
-
|
|
108
91
|
#### HTTP Streaming
|
|
109
92
|
|
|
110
93
|
[HTTP streaming](https://www.cloudflare.com/learning/video/what-is-http-live-streaming/) provides a more efficient alternative to SSE in environments that support it, with potentially better performance for larger payloads.
|
|
@@ -115,7 +98,6 @@ You can run the server with HTTP streaming support:
|
|
|
115
98
|
server.start({
|
|
116
99
|
transportType: "httpStream",
|
|
117
100
|
httpStream: {
|
|
118
|
-
endpoint: "/stream",
|
|
119
101
|
port: 8080,
|
|
120
102
|
},
|
|
121
103
|
});
|
|
@@ -125,10 +107,10 @@ This will start the server and listen for HTTP streaming connections on `http://
|
|
|
125
107
|
|
|
126
108
|
You can connect to these servers using the appropriate client transport.
|
|
127
109
|
|
|
128
|
-
For
|
|
110
|
+
For HTTP streaming connections:
|
|
129
111
|
|
|
130
112
|
```ts
|
|
131
|
-
import {
|
|
113
|
+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
132
114
|
|
|
133
115
|
const client = new Client(
|
|
134
116
|
{
|
|
@@ -140,15 +122,17 @@ const client = new Client(
|
|
|
140
122
|
},
|
|
141
123
|
);
|
|
142
124
|
|
|
143
|
-
const transport = new
|
|
125
|
+
const transport = new StreamableHTTPClientTransport(
|
|
126
|
+
new URL(`http://localhost:8080/stream`),
|
|
127
|
+
);
|
|
144
128
|
|
|
145
129
|
await client.connect(transport);
|
|
146
130
|
```
|
|
147
131
|
|
|
148
|
-
For
|
|
132
|
+
For SSE connections:
|
|
149
133
|
|
|
150
134
|
```ts
|
|
151
|
-
import {
|
|
135
|
+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
152
136
|
|
|
153
137
|
const client = new Client(
|
|
154
138
|
{
|
|
@@ -160,9 +144,7 @@ const client = new Client(
|
|
|
160
144
|
},
|
|
161
145
|
);
|
|
162
146
|
|
|
163
|
-
const transport = new
|
|
164
|
-
new URL(`http://localhost:8080/stream`),
|
|
165
|
-
);
|
|
147
|
+
const transport = new SSEClientTransport(new URL(`http://localhost:8080/sse`));
|
|
166
148
|
|
|
167
149
|
await client.connect(transport);
|
|
168
150
|
```
|
|
@@ -420,6 +402,47 @@ By default, ping behavior is optimized for each transport type:
|
|
|
420
402
|
|
|
421
403
|
This configurable approach helps reduce log verbosity and optimize performance for different usage scenarios.
|
|
422
404
|
|
|
405
|
+
### Health-check Endpoint
|
|
406
|
+
|
|
407
|
+
When you run FastMCP with the `httpStream` transport you can optionally expose a
|
|
408
|
+
simple HTTP endpoint that returns a plain-text response useful for load-balancer
|
|
409
|
+
or container orchestration liveness checks.
|
|
410
|
+
|
|
411
|
+
Enable (or customise) the endpoint via the `health` key in the server options:
|
|
412
|
+
|
|
413
|
+
```ts
|
|
414
|
+
const server = new FastMCP({
|
|
415
|
+
name: "My Server",
|
|
416
|
+
version: "1.0.0",
|
|
417
|
+
health: {
|
|
418
|
+
// Enable / disable (default: true)
|
|
419
|
+
enabled: true,
|
|
420
|
+
// Body returned by the endpoint (default: 'ok')
|
|
421
|
+
message: "healthy",
|
|
422
|
+
// Path that should respond (default: '/health')
|
|
423
|
+
path: "/healthz",
|
|
424
|
+
// HTTP status code to return (default: 200)
|
|
425
|
+
status: 200,
|
|
426
|
+
},
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
await server.start({
|
|
430
|
+
transportType: "httpStream",
|
|
431
|
+
httpStream: { port: 8080 },
|
|
432
|
+
});
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Now a request to `http://localhost:8080/healthz` will return:
|
|
436
|
+
|
|
437
|
+
```
|
|
438
|
+
HTTP/1.1 200 OK
|
|
439
|
+
content-type: text/plain
|
|
440
|
+
|
|
441
|
+
healthy
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
The endpoint is ignored when the server is started with the `stdio` transport.
|
|
445
|
+
|
|
423
446
|
#### Roots Management
|
|
424
447
|
|
|
425
448
|
FastMCP supports [Roots](https://modelcontextprotocol.io/docs/concepts/roots) - Feature that allows clients to provide a set of filesystem-like root locations that can be listed and dynamically updated. The Roots feature can be configured or disabled in server options:
|
|
@@ -668,6 +691,86 @@ server.addTool({
|
|
|
668
691
|
});
|
|
669
692
|
```
|
|
670
693
|
|
|
694
|
+
#### Streaming Output
|
|
695
|
+
|
|
696
|
+
FastMCP supports streaming partial results from tools while they're still executing, enabling responsive UIs and real-time feedback. This is particularly useful for:
|
|
697
|
+
|
|
698
|
+
- Long-running operations that generate content incrementally
|
|
699
|
+
- Progressive generation of text, images, or other media
|
|
700
|
+
- Operations where users benefit from seeing immediate partial results
|
|
701
|
+
|
|
702
|
+
To enable streaming for a tool, add the `streamingHint` annotation and use the `streamContent` method:
|
|
703
|
+
|
|
704
|
+
```js
|
|
705
|
+
server.addTool({
|
|
706
|
+
name: "generateText",
|
|
707
|
+
description: "Generate text incrementally",
|
|
708
|
+
parameters: z.object({
|
|
709
|
+
prompt: z.string(),
|
|
710
|
+
}),
|
|
711
|
+
annotations: {
|
|
712
|
+
streamingHint: true, // Signals this tool uses streaming
|
|
713
|
+
readOnlyHint: true,
|
|
714
|
+
},
|
|
715
|
+
execute: async (args, { streamContent }) => {
|
|
716
|
+
// Send initial content immediately
|
|
717
|
+
await streamContent({ type: "text", text: "Starting generation...\n" });
|
|
718
|
+
|
|
719
|
+
// Simulate incremental content generation
|
|
720
|
+
const words = "The quick brown fox jumps over the lazy dog.".split(" ");
|
|
721
|
+
for (const word of words) {
|
|
722
|
+
await streamContent({ type: "text", text: word + " " });
|
|
723
|
+
await new Promise((resolve) => setTimeout(resolve, 300)); // Simulate delay
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// When using streamContent, you can:
|
|
727
|
+
// 1. Return void (if all content was streamed)
|
|
728
|
+
// 2. Return a final result (which will be appended to streamed content)
|
|
729
|
+
|
|
730
|
+
// Option 1: All content was streamed, so return void
|
|
731
|
+
return;
|
|
732
|
+
|
|
733
|
+
// Option 2: Return final content that will be appended
|
|
734
|
+
// return "Generation complete!";
|
|
735
|
+
},
|
|
736
|
+
});
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
Streaming works with all content types (text, image, audio) and can be combined with progress reporting:
|
|
740
|
+
|
|
741
|
+
```js
|
|
742
|
+
server.addTool({
|
|
743
|
+
name: "processData",
|
|
744
|
+
description: "Process data with streaming updates",
|
|
745
|
+
parameters: z.object({
|
|
746
|
+
datasetSize: z.number(),
|
|
747
|
+
}),
|
|
748
|
+
annotations: {
|
|
749
|
+
streamingHint: true,
|
|
750
|
+
},
|
|
751
|
+
execute: async (args, { streamContent, reportProgress }) => {
|
|
752
|
+
const total = args.datasetSize;
|
|
753
|
+
|
|
754
|
+
for (let i = 0; i < total; i++) {
|
|
755
|
+
// Report numeric progress
|
|
756
|
+
await reportProgress({ progress: i, total });
|
|
757
|
+
|
|
758
|
+
// Stream intermediate results
|
|
759
|
+
if (i % 10 === 0) {
|
|
760
|
+
await streamContent({
|
|
761
|
+
type: "text",
|
|
762
|
+
text: `Processed ${i} of ${total} items...\n`,
|
|
763
|
+
});
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return "Processing complete!";
|
|
770
|
+
},
|
|
771
|
+
});
|
|
772
|
+
```
|
|
773
|
+
|
|
671
774
|
#### Tool Annotations
|
|
672
775
|
|
|
673
776
|
As of the MCP Specification (2025-03-26), tools can include annotations that provide richer context and control by adding metadata about a tool's behavior:
|
|
@@ -892,8 +995,6 @@ server.addPrompt({
|
|
|
892
995
|
FastMCP allows you to `authenticate` clients using a custom function:
|
|
893
996
|
|
|
894
997
|
```ts
|
|
895
|
-
import { AuthError } from "fastmcp";
|
|
896
|
-
|
|
897
998
|
const server = new FastMCP({
|
|
898
999
|
name: "My Server",
|
|
899
1000
|
version: "1.0.0",
|
package/dist/FastMCP.d.ts
CHANGED
|
@@ -49,6 +49,7 @@ type Context<T extends FastMCPSessionAuth> = {
|
|
|
49
49
|
};
|
|
50
50
|
reportProgress: (progress: Progress) => Promise<void>;
|
|
51
51
|
session: T | undefined;
|
|
52
|
+
streamContent: (content: Content | Content[]) => Promise<void>;
|
|
52
53
|
};
|
|
53
54
|
type Extra = unknown;
|
|
54
55
|
type Extras = Record<string, Extra>;
|
|
@@ -187,6 +188,38 @@ type ResourceTemplateArgumentsToObject<T extends {
|
|
|
187
188
|
};
|
|
188
189
|
type ServerOptions<T extends FastMCPSessionAuth> = {
|
|
189
190
|
authenticate?: Authenticate<T>;
|
|
191
|
+
/**
|
|
192
|
+
* Configuration for the health-check endpoint that can be exposed when the
|
|
193
|
+
* server is running using the HTTP Stream transport. When enabled, the
|
|
194
|
+
* server will respond to an HTTP GET request with the configured path (by
|
|
195
|
+
* default "/health") rendering a plain-text response (by default "ok") and
|
|
196
|
+
* the configured status code (by default 200).
|
|
197
|
+
*
|
|
198
|
+
* The endpoint is only added when the server is started with
|
|
199
|
+
* `transportType: "httpStream"` – it is ignored for the stdio transport.
|
|
200
|
+
*/
|
|
201
|
+
health?: {
|
|
202
|
+
/**
|
|
203
|
+
* When set to `false` the health-check endpoint is disabled.
|
|
204
|
+
* @default true
|
|
205
|
+
*/
|
|
206
|
+
enabled?: boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Plain-text body returned by the endpoint.
|
|
209
|
+
* @default "ok"
|
|
210
|
+
*/
|
|
211
|
+
message?: string;
|
|
212
|
+
/**
|
|
213
|
+
* HTTP path that should be handled.
|
|
214
|
+
* @default "/health"
|
|
215
|
+
*/
|
|
216
|
+
path?: string;
|
|
217
|
+
/**
|
|
218
|
+
* HTTP response status that will be returned.
|
|
219
|
+
* @default 200
|
|
220
|
+
*/
|
|
221
|
+
status?: number;
|
|
222
|
+
};
|
|
190
223
|
instructions?: string;
|
|
191
224
|
name: string;
|
|
192
225
|
ping?: {
|
|
@@ -221,9 +254,15 @@ type ServerOptions<T extends FastMCPSessionAuth> = {
|
|
|
221
254
|
version: `${number}.${number}.${number}`;
|
|
222
255
|
};
|
|
223
256
|
type Tool<T extends FastMCPSessionAuth, Params extends ToolParameters = ToolParameters> = {
|
|
224
|
-
annotations?:
|
|
257
|
+
annotations?: {
|
|
258
|
+
/**
|
|
259
|
+
* When true, the tool leverages incremental content streaming
|
|
260
|
+
* Return void for tools that handle all their output via streaming
|
|
261
|
+
*/
|
|
262
|
+
streamingHint?: boolean;
|
|
263
|
+
} & ToolAnnotations;
|
|
225
264
|
description?: string;
|
|
226
|
-
execute: (args: StandardSchemaV1.InferOutput<Params>, context: Context<T>) => Promise<AudioContent | ContentResult | ImageContent | string | TextContent>;
|
|
265
|
+
execute: (args: StandardSchemaV1.InferOutput<Params>, context: Context<T>) => Promise<AudioContent | ContentResult | ImageContent | string | TextContent | void>;
|
|
227
266
|
name: string;
|
|
228
267
|
parameters?: Params;
|
|
229
268
|
timeoutMs?: number;
|
|
@@ -337,16 +376,9 @@ declare class FastMCP<T extends Record<string, unknown> | undefined = undefined>
|
|
|
337
376
|
*/
|
|
338
377
|
start(options?: {
|
|
339
378
|
httpStream: {
|
|
340
|
-
endpoint: `/${string}`;
|
|
341
379
|
port: number;
|
|
342
380
|
};
|
|
343
381
|
transportType: "httpStream";
|
|
344
|
-
} | {
|
|
345
|
-
sse: {
|
|
346
|
-
endpoint: `/${string}`;
|
|
347
|
-
port: number;
|
|
348
|
-
};
|
|
349
|
-
transportType: "sse";
|
|
350
382
|
} | {
|
|
351
383
|
transportType: "stdio";
|
|
352
384
|
}): Promise<void>;
|
package/dist/FastMCP.js
CHANGED
|
@@ -19,7 +19,7 @@ import { EventEmitter } from "events";
|
|
|
19
19
|
import { fileTypeFromBuffer } from "file-type";
|
|
20
20
|
import { readFile } from "fs/promises";
|
|
21
21
|
import Fuse from "fuse.js";
|
|
22
|
-
import {
|
|
22
|
+
import { startHTTPServer } from "mcp-proxy";
|
|
23
23
|
import { setTimeout as delay } from "timers/promises";
|
|
24
24
|
import { fetch } from "undici";
|
|
25
25
|
import parseURITemplate from "uri-templates";
|
|
@@ -354,7 +354,7 @@ ${e instanceof Error ? e.stack : JSON.stringify(e)}`
|
|
|
354
354
|
const pingConfig = this.#pingConfig || {};
|
|
355
355
|
let defaultEnabled = false;
|
|
356
356
|
if ("type" in transport) {
|
|
357
|
-
if (transport.type === "
|
|
357
|
+
if (transport.type === "httpStream") {
|
|
358
358
|
defaultEnabled = true;
|
|
359
359
|
}
|
|
360
360
|
}
|
|
@@ -773,10 +773,21 @@ ${e instanceof Error ? e.stack : JSON.stringify(e)}`
|
|
|
773
773
|
});
|
|
774
774
|
}
|
|
775
775
|
};
|
|
776
|
+
const streamContent = async (content) => {
|
|
777
|
+
const contentArray = Array.isArray(content) ? content : [content];
|
|
778
|
+
await this.#server.notification({
|
|
779
|
+
method: "notifications/tool/streamContent",
|
|
780
|
+
params: {
|
|
781
|
+
content: contentArray,
|
|
782
|
+
toolName: request.params.name
|
|
783
|
+
}
|
|
784
|
+
});
|
|
785
|
+
};
|
|
776
786
|
const executeToolPromise = tool.execute(args, {
|
|
777
787
|
log,
|
|
778
788
|
reportProgress,
|
|
779
|
-
session: this.#auth
|
|
789
|
+
session: this.#auth,
|
|
790
|
+
streamContent
|
|
780
791
|
});
|
|
781
792
|
const maybeStringResult = await (tool.timeoutMs ? Promise.race([
|
|
782
793
|
executeToolPromise,
|
|
@@ -790,7 +801,11 @@ ${e instanceof Error ? e.stack : JSON.stringify(e)}`
|
|
|
790
801
|
}, tool.timeoutMs);
|
|
791
802
|
})
|
|
792
803
|
]) : executeToolPromise);
|
|
793
|
-
if (
|
|
804
|
+
if (maybeStringResult === void 0 || maybeStringResult === null) {
|
|
805
|
+
result = ContentResultZodSchema.parse({
|
|
806
|
+
content: []
|
|
807
|
+
});
|
|
808
|
+
} else if (typeof maybeStringResult === "string") {
|
|
794
809
|
result = ContentResultZodSchema.parse({
|
|
795
810
|
content: [{ text: maybeStringResult, type: "text" }]
|
|
796
811
|
});
|
|
@@ -837,7 +852,6 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
837
852
|
#resources = [];
|
|
838
853
|
#resourcesTemplates = [];
|
|
839
854
|
#sessions = [];
|
|
840
|
-
#sseServer = null;
|
|
841
855
|
#tools = [];
|
|
842
856
|
/**
|
|
843
857
|
* Adds a prompt to the server.
|
|
@@ -887,8 +901,8 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
887
901
|
this.emit("connect", {
|
|
888
902
|
session
|
|
889
903
|
});
|
|
890
|
-
} else if (options.transportType === "
|
|
891
|
-
this.#
|
|
904
|
+
} else if (options.transportType === "httpStream") {
|
|
905
|
+
this.#httpStreamServer = await startHTTPServer({
|
|
892
906
|
createServer: async (request) => {
|
|
893
907
|
let auth;
|
|
894
908
|
if (this.#authenticate) {
|
|
@@ -906,7 +920,6 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
906
920
|
version: this.#options.version
|
|
907
921
|
});
|
|
908
922
|
},
|
|
909
|
-
endpoint: options.sse.endpoint,
|
|
910
923
|
onClose: (session) => {
|
|
911
924
|
this.emit("disconnect", {
|
|
912
925
|
session
|
|
@@ -918,46 +931,28 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
918
931
|
session
|
|
919
932
|
});
|
|
920
933
|
},
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
934
|
+
onUnhandledRequest: async (req, res) => {
|
|
935
|
+
const healthConfig = this.#options.health ?? {};
|
|
936
|
+
const enabled = healthConfig.enabled === void 0 ? true : healthConfig.enabled;
|
|
937
|
+
if (enabled) {
|
|
938
|
+
const path = healthConfig.path ?? "/health";
|
|
939
|
+
try {
|
|
940
|
+
if (req.method === "GET" && new URL(req.url || "", "http://localhost").pathname === path) {
|
|
941
|
+
res.writeHead(healthConfig.status ?? 200, {
|
|
942
|
+
"Content-Type": "text/plain"
|
|
943
|
+
}).end(healthConfig.message ?? "ok");
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
} catch (error) {
|
|
947
|
+
console.error("[FastMCP error] health endpoint error", error);
|
|
948
|
+
}
|
|
932
949
|
}
|
|
933
|
-
|
|
934
|
-
auth,
|
|
935
|
-
name: this.#options.name,
|
|
936
|
-
ping: this.#options.ping,
|
|
937
|
-
prompts: this.#prompts,
|
|
938
|
-
resources: this.#resources,
|
|
939
|
-
resourcesTemplates: this.#resourcesTemplates,
|
|
940
|
-
roots: this.#options.roots,
|
|
941
|
-
tools: this.#tools,
|
|
942
|
-
version: this.#options.version
|
|
943
|
-
});
|
|
944
|
-
},
|
|
945
|
-
endpoint: options.httpStream.endpoint,
|
|
946
|
-
onClose: (session) => {
|
|
947
|
-
this.emit("disconnect", {
|
|
948
|
-
session
|
|
949
|
-
});
|
|
950
|
-
},
|
|
951
|
-
onConnect: async (session) => {
|
|
952
|
-
this.#sessions.push(session);
|
|
953
|
-
this.emit("connect", {
|
|
954
|
-
session
|
|
955
|
-
});
|
|
950
|
+
res.writeHead(404).end();
|
|
956
951
|
},
|
|
957
952
|
port: options.httpStream.port
|
|
958
953
|
});
|
|
959
954
|
console.info(
|
|
960
|
-
`[FastMCP info] server is running on HTTP Stream at http://localhost:${options.httpStream.port}
|
|
955
|
+
`[FastMCP info] server is running on HTTP Stream at http://localhost:${options.httpStream.port}/stream`
|
|
961
956
|
);
|
|
962
957
|
} else {
|
|
963
958
|
throw new Error("Invalid transport type");
|
|
@@ -967,9 +962,6 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
967
962
|
* Stops the server.
|
|
968
963
|
*/
|
|
969
964
|
async stop() {
|
|
970
|
-
if (this.#sseServer) {
|
|
971
|
-
await this.#sseServer.close();
|
|
972
|
-
}
|
|
973
965
|
if (this.#httpStreamServer) {
|
|
974
966
|
await this.#httpStreamServer.close();
|
|
975
967
|
}
|