fastmcp 1.6.1 → 1.8.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 +76 -10
- package/dist/FastMCP.d.ts +42 -8
- package/dist/FastMCP.js +184 -103
- package/dist/FastMCP.js.map +1 -1
- package/jsr.json +1 -1
- package/package.json +5 -4
- package/src/FastMCP.test.ts +234 -22
- package/src/FastMCP.ts +233 -113
- package/src/examples/addition.ts +26 -0
- package/vitest.config.js +9 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# FastMCP
|
|
2
2
|
|
|
3
|
-
A TypeScript framework for building [MCP](https://modelcontextprotocol.io/) servers.
|
|
3
|
+
A TypeScript framework for building [MCP](https://modelcontextprotocol.io/) servers capable of handling client sessions.
|
|
4
4
|
|
|
5
5
|
> [!NOTE]
|
|
6
6
|
> For a Python implementation, see [FastMCP](https://github.com/jlowin/fastmcp).
|
|
@@ -8,13 +8,15 @@ A TypeScript framework for building [MCP](https://modelcontextprotocol.io/) serv
|
|
|
8
8
|
## Features
|
|
9
9
|
|
|
10
10
|
- Simple Tool, Resource, Prompt definition
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
11
|
+
- [Sessions](#sessions)
|
|
12
|
+
- [Image content](#returning-an-image)
|
|
13
|
+
- [Logging](#logging)
|
|
14
|
+
- [Error handling](#errors)
|
|
15
|
+
- [SSE](#sse)
|
|
16
|
+
- [Progress notifications](#progress)
|
|
17
|
+
- [Typed events](#typed-events)
|
|
18
|
+
- Roots
|
|
19
|
+
- CLI for [testing](#test-with-mcp-cli) and [debugging](#inspect-with-mcp-inspector)
|
|
18
20
|
|
|
19
21
|
## Installation
|
|
20
22
|
|
|
@@ -50,6 +52,8 @@ server.start({
|
|
|
50
52
|
});
|
|
51
53
|
```
|
|
52
54
|
|
|
55
|
+
_That's it!_ You have a working MCP server.
|
|
56
|
+
|
|
53
57
|
You can test the server in terminal with:
|
|
54
58
|
|
|
55
59
|
```bash
|
|
@@ -371,7 +375,7 @@ async load() {
|
|
|
371
375
|
|
|
372
376
|
[Prompts](https://modelcontextprotocol.io/docs/concepts/prompts) enable servers to define reusable prompt templates and workflows that clients can easily surface to users and LLMs. They provide a powerful way to standardize and share common LLM interactions.
|
|
373
377
|
|
|
374
|
-
```
|
|
378
|
+
```ts
|
|
375
379
|
server.addPrompt({
|
|
376
380
|
name: "git-commit",
|
|
377
381
|
description: "Generate a Git commit message",
|
|
@@ -388,6 +392,68 @@ server.addPrompt({
|
|
|
388
392
|
});
|
|
389
393
|
```
|
|
390
394
|
|
|
395
|
+
### Sessions
|
|
396
|
+
|
|
397
|
+
The `session` object is an instance of `FastMCPSession` and it describes active client sessions.
|
|
398
|
+
|
|
399
|
+
```ts
|
|
400
|
+
server.sessions;
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
We allocate a new server instance for each client connection to enable 1:1 communication between a client and the server.
|
|
404
|
+
|
|
405
|
+
### Typed events
|
|
406
|
+
|
|
407
|
+
You can listen to events emitted by the server using the `on` method:
|
|
408
|
+
|
|
409
|
+
```ts
|
|
410
|
+
server.on("connect", (event) => {
|
|
411
|
+
console.log("Client connected:", event.session);
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
server.on("disconnect", (event) => {
|
|
415
|
+
console.log("Client disconnected:", event.session);
|
|
416
|
+
});
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
## `FastMCPSession`
|
|
420
|
+
|
|
421
|
+
`FastMCPSession` represents a client session and provides methods to interact with the client.
|
|
422
|
+
|
|
423
|
+
Refer to [Sessions](#sessions) for examples of how to obtain a `FastMCPSession` instance.
|
|
424
|
+
|
|
425
|
+
### `clientCapabilities`
|
|
426
|
+
|
|
427
|
+
The `clientCapabilities` property contains the client capabilities.
|
|
428
|
+
|
|
429
|
+
```ts
|
|
430
|
+
session.clientCapabilities;
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### `loggingLevel`
|
|
434
|
+
|
|
435
|
+
The `loggingLevel` property describes the logging level as set by the client.
|
|
436
|
+
|
|
437
|
+
```ts
|
|
438
|
+
session.loggingLevel;
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### `roots`
|
|
442
|
+
|
|
443
|
+
The `roots` property contains the roots as set by the client.
|
|
444
|
+
|
|
445
|
+
```ts
|
|
446
|
+
session.roots;
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### `server`
|
|
450
|
+
|
|
451
|
+
The `server` property contains an instance of MCP server that is associated with the session.
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
session.server;
|
|
455
|
+
```
|
|
456
|
+
|
|
391
457
|
## Running Your Server
|
|
392
458
|
|
|
393
459
|
### Test with `mcp-cli`
|
|
@@ -414,7 +480,7 @@ npx fastmcp inspect server.ts
|
|
|
414
480
|
> [!NOTE]
|
|
415
481
|
> If you've developed a server using FastMCP, please [submit a PR](https://github.com/punkpeye/fastmcp) to showcase it here!
|
|
416
482
|
|
|
417
|
-
|
|
483
|
+
- https://github.com/apinetwork/piapi-mcp-server
|
|
418
484
|
|
|
419
485
|
## Acknowledgements
|
|
420
486
|
|
package/dist/FastMCP.d.ts
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { ClientCapabilities, Root } from '@modelcontextprotocol/sdk/types.js';
|
|
1
3
|
import { z } from 'zod';
|
|
4
|
+
import { StrictEventEmitter } from 'strict-event-emitter-types';
|
|
5
|
+
import { EventEmitter } from 'events';
|
|
6
|
+
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
2
7
|
|
|
8
|
+
type SSEServer = {
|
|
9
|
+
close: () => Promise<void>;
|
|
10
|
+
};
|
|
11
|
+
type FastMCPEvents = {
|
|
12
|
+
connect: (event: {
|
|
13
|
+
session: FastMCPSession;
|
|
14
|
+
}) => void;
|
|
15
|
+
disconnect: (event: {
|
|
16
|
+
session: FastMCPSession;
|
|
17
|
+
}) => void;
|
|
18
|
+
};
|
|
3
19
|
/**
|
|
4
20
|
* Generates an image content object from a URL, file path, or buffer.
|
|
5
21
|
*/
|
|
@@ -100,19 +116,37 @@ type ServerOptions = {
|
|
|
100
116
|
version: `${number}.${number}.${number}`;
|
|
101
117
|
};
|
|
102
118
|
type LoggingLevel = "debug" | "info" | "notice" | "warning" | "error" | "critical" | "alert" | "emergency";
|
|
103
|
-
declare class
|
|
119
|
+
declare class FastMCPSession {
|
|
104
120
|
#private;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
121
|
+
constructor({ name, version, tools, resources, prompts, }: {
|
|
122
|
+
name: string;
|
|
123
|
+
version: string;
|
|
124
|
+
tools: Tool[];
|
|
125
|
+
resources: Resource[];
|
|
126
|
+
prompts: Prompt[];
|
|
127
|
+
});
|
|
128
|
+
get clientCapabilities(): ClientCapabilities | null;
|
|
129
|
+
get server(): Server;
|
|
130
|
+
connect(transport: Transport): Promise<void>;
|
|
131
|
+
get roots(): Root[];
|
|
132
|
+
close(): Promise<void>;
|
|
108
133
|
private setupErrorHandling;
|
|
109
|
-
/**
|
|
110
|
-
* Returns the current logging level.
|
|
111
|
-
*/
|
|
112
134
|
get loggingLevel(): LoggingLevel;
|
|
135
|
+
private setupLoggingHandlers;
|
|
113
136
|
private setupToolHandlers;
|
|
114
137
|
private setupResourceHandlers;
|
|
115
138
|
private setupPromptHandlers;
|
|
139
|
+
}
|
|
140
|
+
declare const FastMCPEventEmitterBase: {
|
|
141
|
+
new (): StrictEventEmitter<EventEmitter, FastMCPEvents>;
|
|
142
|
+
};
|
|
143
|
+
declare class FastMCPEventEmitter extends FastMCPEventEmitterBase {
|
|
144
|
+
}
|
|
145
|
+
declare class FastMCP extends FastMCPEventEmitter {
|
|
146
|
+
#private;
|
|
147
|
+
options: ServerOptions;
|
|
148
|
+
constructor(options: ServerOptions);
|
|
149
|
+
get sessions(): FastMCPSession[];
|
|
116
150
|
/**
|
|
117
151
|
* Adds a tool to the server.
|
|
118
152
|
*/
|
|
@@ -143,4 +177,4 @@ declare class FastMCP {
|
|
|
143
177
|
stop(): Promise<void>;
|
|
144
178
|
}
|
|
145
179
|
|
|
146
|
-
export { FastMCP, UserError, imageContent };
|
|
180
|
+
export { FastMCP, FastMCPSession, type SSEServer, UserError, imageContent };
|
package/dist/FastMCP.js
CHANGED
|
@@ -14,8 +14,10 @@ import {
|
|
|
14
14
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
15
15
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
16
16
|
import { z } from "zod";
|
|
17
|
+
import { setTimeout as delay } from "timers/promises";
|
|
17
18
|
import { readFile } from "fs/promises";
|
|
18
19
|
import { fileTypeFromBuffer } from "file-type";
|
|
20
|
+
import { EventEmitter } from "events";
|
|
19
21
|
import { startSSEServer } from "mcp-proxy";
|
|
20
22
|
var imageContent = async (input) => {
|
|
21
23
|
let rawData;
|
|
@@ -84,55 +86,97 @@ var ContentResultZodSchema = z.object({
|
|
|
84
86
|
content: ContentZodSchema.array(),
|
|
85
87
|
isError: z.boolean().optional()
|
|
86
88
|
}).strict();
|
|
87
|
-
var
|
|
88
|
-
|
|
89
|
-
this.options = options;
|
|
90
|
-
this.#options = options;
|
|
91
|
-
this.#tools = [];
|
|
92
|
-
this.#resources = [];
|
|
93
|
-
this.#prompts = [];
|
|
94
|
-
}
|
|
95
|
-
#tools;
|
|
96
|
-
#resources;
|
|
97
|
-
#prompts;
|
|
98
|
-
#server = null;
|
|
99
|
-
#options;
|
|
89
|
+
var FastMCPSession = class {
|
|
90
|
+
#capabilities = {};
|
|
100
91
|
#loggingLevel = "info";
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
92
|
+
#server;
|
|
93
|
+
#clientCapabilities;
|
|
94
|
+
#roots = [];
|
|
95
|
+
constructor({
|
|
96
|
+
name,
|
|
97
|
+
version,
|
|
98
|
+
tools,
|
|
99
|
+
resources,
|
|
100
|
+
prompts
|
|
101
|
+
}) {
|
|
102
|
+
if (tools.length) {
|
|
103
|
+
this.#capabilities.tools = {};
|
|
105
104
|
}
|
|
106
|
-
if (
|
|
107
|
-
this.
|
|
105
|
+
if (resources.length) {
|
|
106
|
+
this.#capabilities.resources = {};
|
|
108
107
|
}
|
|
109
|
-
if (
|
|
110
|
-
this.
|
|
108
|
+
if (prompts.length) {
|
|
109
|
+
this.#capabilities.prompts = {};
|
|
111
110
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
111
|
+
this.#capabilities.logging = {};
|
|
112
|
+
this.#server = new Server(
|
|
113
|
+
{ name, version },
|
|
114
|
+
{ capabilities: this.#capabilities }
|
|
115
|
+
);
|
|
116
|
+
this.setupErrorHandling();
|
|
117
|
+
this.setupLoggingHandlers();
|
|
118
|
+
if (tools.length) {
|
|
119
|
+
this.setupToolHandlers(tools);
|
|
120
|
+
}
|
|
121
|
+
if (resources.length) {
|
|
122
|
+
this.setupResourceHandlers(resources);
|
|
123
|
+
}
|
|
124
|
+
if (prompts.length) {
|
|
125
|
+
this.setupPromptHandlers(prompts);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
get clientCapabilities() {
|
|
129
|
+
return this.#clientCapabilities ?? null;
|
|
130
|
+
}
|
|
131
|
+
get server() {
|
|
132
|
+
return this.#server;
|
|
133
|
+
}
|
|
134
|
+
async connect(transport) {
|
|
135
|
+
if (this.#server.transport) {
|
|
136
|
+
throw new UnexpectedStateError("Server is already connected");
|
|
137
|
+
}
|
|
138
|
+
await this.#server.connect(transport);
|
|
139
|
+
let attempt = 0;
|
|
140
|
+
while (attempt++ < 10) {
|
|
141
|
+
const capabilities = await this.#server.getClientCapabilities();
|
|
142
|
+
if (capabilities) {
|
|
143
|
+
this.#clientCapabilities = capabilities;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
await delay(100);
|
|
147
|
+
}
|
|
148
|
+
if (this.#clientCapabilities?.roots) {
|
|
149
|
+
const roots = await this.#server.listRoots();
|
|
150
|
+
this.#roots = roots.roots;
|
|
151
|
+
}
|
|
152
|
+
if (!this.#clientCapabilities) {
|
|
153
|
+
throw new UnexpectedStateError("Server did not connect");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
get roots() {
|
|
157
|
+
return this.#roots;
|
|
158
|
+
}
|
|
159
|
+
async close() {
|
|
160
|
+
await this.#server.close();
|
|
116
161
|
}
|
|
117
|
-
setupErrorHandling(
|
|
118
|
-
server.onerror = (error) => {
|
|
162
|
+
setupErrorHandling() {
|
|
163
|
+
this.#server.onerror = (error) => {
|
|
119
164
|
console.error("[MCP Error]", error);
|
|
120
165
|
};
|
|
121
|
-
process.on("SIGINT", async () => {
|
|
122
|
-
await server.close();
|
|
123
|
-
process.exit(0);
|
|
124
|
-
});
|
|
125
166
|
}
|
|
126
|
-
/**
|
|
127
|
-
* Returns the current logging level.
|
|
128
|
-
*/
|
|
129
167
|
get loggingLevel() {
|
|
130
168
|
return this.#loggingLevel;
|
|
131
169
|
}
|
|
132
|
-
|
|
133
|
-
server.setRequestHandler(
|
|
170
|
+
setupLoggingHandlers() {
|
|
171
|
+
this.#server.setRequestHandler(SetLevelRequestSchema, (request) => {
|
|
172
|
+
this.#loggingLevel = request.params.level;
|
|
173
|
+
return {};
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
setupToolHandlers(tools) {
|
|
177
|
+
this.#server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
134
178
|
return {
|
|
135
|
-
tools:
|
|
179
|
+
tools: tools.map((tool) => {
|
|
136
180
|
return {
|
|
137
181
|
name: tool.name,
|
|
138
182
|
description: tool.description,
|
|
@@ -141,10 +185,8 @@ var FastMCP = class {
|
|
|
141
185
|
})
|
|
142
186
|
};
|
|
143
187
|
});
|
|
144
|
-
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
145
|
-
const tool =
|
|
146
|
-
(tool2) => tool2.name === request.params.name
|
|
147
|
-
);
|
|
188
|
+
this.#server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
189
|
+
const tool = tools.find((tool2) => tool2.name === request.params.name);
|
|
148
190
|
if (!tool) {
|
|
149
191
|
throw new McpError(
|
|
150
192
|
ErrorCode.MethodNotFound,
|
|
@@ -166,7 +208,7 @@ var FastMCP = class {
|
|
|
166
208
|
let result;
|
|
167
209
|
try {
|
|
168
210
|
const reportProgress = async (progress) => {
|
|
169
|
-
await server.notification({
|
|
211
|
+
await this.#server.notification({
|
|
170
212
|
method: "notifications/progress",
|
|
171
213
|
params: {
|
|
172
214
|
...progress,
|
|
@@ -176,7 +218,7 @@ var FastMCP = class {
|
|
|
176
218
|
};
|
|
177
219
|
const log = {
|
|
178
220
|
debug: (message, context) => {
|
|
179
|
-
server.sendLoggingMessage({
|
|
221
|
+
this.#server.sendLoggingMessage({
|
|
180
222
|
level: "debug",
|
|
181
223
|
data: {
|
|
182
224
|
message,
|
|
@@ -185,7 +227,7 @@ var FastMCP = class {
|
|
|
185
227
|
});
|
|
186
228
|
},
|
|
187
229
|
error: (message, context) => {
|
|
188
|
-
server.sendLoggingMessage({
|
|
230
|
+
this.#server.sendLoggingMessage({
|
|
189
231
|
level: "error",
|
|
190
232
|
data: {
|
|
191
233
|
message,
|
|
@@ -194,7 +236,7 @@ var FastMCP = class {
|
|
|
194
236
|
});
|
|
195
237
|
},
|
|
196
238
|
info: (message, context) => {
|
|
197
|
-
server.sendLoggingMessage({
|
|
239
|
+
this.#server.sendLoggingMessage({
|
|
198
240
|
level: "info",
|
|
199
241
|
data: {
|
|
200
242
|
message,
|
|
@@ -203,7 +245,7 @@ var FastMCP = class {
|
|
|
203
245
|
});
|
|
204
246
|
},
|
|
205
247
|
warn: (message, context) => {
|
|
206
|
-
server.sendLoggingMessage({
|
|
248
|
+
this.#server.sendLoggingMessage({
|
|
207
249
|
level: "warning",
|
|
208
250
|
data: {
|
|
209
251
|
message,
|
|
@@ -242,10 +284,10 @@ var FastMCP = class {
|
|
|
242
284
|
return result;
|
|
243
285
|
});
|
|
244
286
|
}
|
|
245
|
-
setupResourceHandlers(
|
|
246
|
-
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
287
|
+
setupResourceHandlers(resources) {
|
|
288
|
+
this.#server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
247
289
|
return {
|
|
248
|
-
resources:
|
|
290
|
+
resources: resources.map((resource) => {
|
|
249
291
|
return {
|
|
250
292
|
uri: resource.uri,
|
|
251
293
|
name: resource.name,
|
|
@@ -254,43 +296,46 @@ var FastMCP = class {
|
|
|
254
296
|
})
|
|
255
297
|
};
|
|
256
298
|
});
|
|
257
|
-
server.setRequestHandler(
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
throw new McpError(
|
|
263
|
-
ErrorCode.MethodNotFound,
|
|
264
|
-
`Unknown resource: ${request.params.uri}`
|
|
265
|
-
);
|
|
266
|
-
}
|
|
267
|
-
let result;
|
|
268
|
-
try {
|
|
269
|
-
result = await resource.load();
|
|
270
|
-
} catch (error) {
|
|
271
|
-
throw new McpError(
|
|
272
|
-
ErrorCode.InternalError,
|
|
273
|
-
`Error reading resource: ${error}`,
|
|
274
|
-
{
|
|
275
|
-
uri: resource.uri
|
|
276
|
-
}
|
|
299
|
+
this.#server.setRequestHandler(
|
|
300
|
+
ReadResourceRequestSchema,
|
|
301
|
+
async (request) => {
|
|
302
|
+
const resource = resources.find(
|
|
303
|
+
(resource2) => resource2.uri === request.params.uri
|
|
277
304
|
);
|
|
305
|
+
if (!resource) {
|
|
306
|
+
throw new McpError(
|
|
307
|
+
ErrorCode.MethodNotFound,
|
|
308
|
+
`Unknown resource: ${request.params.uri}`
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
let result;
|
|
312
|
+
try {
|
|
313
|
+
result = await resource.load();
|
|
314
|
+
} catch (error) {
|
|
315
|
+
throw new McpError(
|
|
316
|
+
ErrorCode.InternalError,
|
|
317
|
+
`Error reading resource: ${error}`,
|
|
318
|
+
{
|
|
319
|
+
uri: resource.uri
|
|
320
|
+
}
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
return {
|
|
324
|
+
contents: [
|
|
325
|
+
{
|
|
326
|
+
uri: resource.uri,
|
|
327
|
+
mimeType: resource.mimeType,
|
|
328
|
+
...result
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
};
|
|
278
332
|
}
|
|
279
|
-
|
|
280
|
-
contents: [
|
|
281
|
-
{
|
|
282
|
-
uri: resource.uri,
|
|
283
|
-
mimeType: resource.mimeType,
|
|
284
|
-
...result
|
|
285
|
-
}
|
|
286
|
-
]
|
|
287
|
-
};
|
|
288
|
-
});
|
|
333
|
+
);
|
|
289
334
|
}
|
|
290
|
-
setupPromptHandlers(
|
|
291
|
-
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
335
|
+
setupPromptHandlers(prompts) {
|
|
336
|
+
this.#server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
292
337
|
return {
|
|
293
|
-
prompts:
|
|
338
|
+
prompts: prompts.map((prompt) => {
|
|
294
339
|
return {
|
|
295
340
|
name: prompt.name,
|
|
296
341
|
description: prompt.description,
|
|
@@ -299,8 +344,8 @@ var FastMCP = class {
|
|
|
299
344
|
})
|
|
300
345
|
};
|
|
301
346
|
});
|
|
302
|
-
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
303
|
-
const prompt =
|
|
347
|
+
this.#server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
348
|
+
const prompt = prompts.find(
|
|
304
349
|
(prompt2) => prompt2.name === request.params.name
|
|
305
350
|
);
|
|
306
351
|
if (!prompt) {
|
|
@@ -340,6 +385,25 @@ var FastMCP = class {
|
|
|
340
385
|
};
|
|
341
386
|
});
|
|
342
387
|
}
|
|
388
|
+
};
|
|
389
|
+
var FastMCPEventEmitterBase = EventEmitter;
|
|
390
|
+
var FastMCPEventEmitter = class extends FastMCPEventEmitterBase {
|
|
391
|
+
};
|
|
392
|
+
var FastMCP = class extends FastMCPEventEmitter {
|
|
393
|
+
constructor(options) {
|
|
394
|
+
super();
|
|
395
|
+
this.options = options;
|
|
396
|
+
this.#options = options;
|
|
397
|
+
}
|
|
398
|
+
#options;
|
|
399
|
+
#prompts = [];
|
|
400
|
+
#resources = [];
|
|
401
|
+
#sessions = [];
|
|
402
|
+
#sseServer = null;
|
|
403
|
+
#tools = [];
|
|
404
|
+
get sessions() {
|
|
405
|
+
return this.#sessions;
|
|
406
|
+
}
|
|
343
407
|
/**
|
|
344
408
|
* Adds a tool to the server.
|
|
345
409
|
*/
|
|
@@ -358,39 +422,55 @@ var FastMCP = class {
|
|
|
358
422
|
addPrompt(prompt) {
|
|
359
423
|
this.#prompts.push(prompt);
|
|
360
424
|
}
|
|
361
|
-
#sseServer = null;
|
|
362
425
|
/**
|
|
363
426
|
* Starts the server.
|
|
364
427
|
*/
|
|
365
428
|
async start(options = {
|
|
366
429
|
transportType: "stdio"
|
|
367
430
|
}) {
|
|
368
|
-
const capabilities = {};
|
|
369
|
-
if (this.#tools.length) {
|
|
370
|
-
capabilities.tools = {};
|
|
371
|
-
}
|
|
372
|
-
if (this.#resources.length) {
|
|
373
|
-
capabilities.resources = {};
|
|
374
|
-
}
|
|
375
|
-
if (this.#prompts.length) {
|
|
376
|
-
capabilities.prompts = {};
|
|
377
|
-
}
|
|
378
|
-
capabilities.logging = {};
|
|
379
|
-
this.#server = new Server(
|
|
380
|
-
{ name: this.#options.name, version: this.#options.version },
|
|
381
|
-
{ capabilities }
|
|
382
|
-
);
|
|
383
|
-
this.setupHandlers(this.#server);
|
|
384
431
|
if (options.transportType === "stdio") {
|
|
385
432
|
const transport = new StdioServerTransport();
|
|
386
|
-
|
|
433
|
+
const session = new FastMCPSession({
|
|
434
|
+
name: this.#options.name,
|
|
435
|
+
version: this.#options.version,
|
|
436
|
+
tools: this.#tools,
|
|
437
|
+
resources: this.#resources,
|
|
438
|
+
prompts: this.#prompts
|
|
439
|
+
});
|
|
440
|
+
await session.connect(transport);
|
|
441
|
+
this.#sessions.push(session);
|
|
442
|
+
this.emit("connect", {
|
|
443
|
+
session
|
|
444
|
+
});
|
|
387
445
|
console.error(`server is running on stdio`);
|
|
388
446
|
} else if (options.transportType === "sse") {
|
|
389
447
|
this.#sseServer = await startSSEServer({
|
|
390
448
|
endpoint: options.sse.endpoint,
|
|
391
449
|
port: options.sse.port,
|
|
392
|
-
|
|
450
|
+
createServer: async () => {
|
|
451
|
+
return new FastMCPSession({
|
|
452
|
+
name: this.#options.name,
|
|
453
|
+
version: this.#options.version,
|
|
454
|
+
tools: this.#tools,
|
|
455
|
+
resources: this.#resources,
|
|
456
|
+
prompts: this.#prompts
|
|
457
|
+
});
|
|
458
|
+
},
|
|
459
|
+
onClose: (session) => {
|
|
460
|
+
this.emit("disconnect", {
|
|
461
|
+
session
|
|
462
|
+
});
|
|
463
|
+
},
|
|
464
|
+
onConnect: async (session) => {
|
|
465
|
+
this.#sessions.push(session);
|
|
466
|
+
this.emit("connect", {
|
|
467
|
+
session
|
|
468
|
+
});
|
|
469
|
+
}
|
|
393
470
|
});
|
|
471
|
+
console.error(
|
|
472
|
+
`server is running on SSE at http://localhost:${options.sse.port}${options.sse.endpoint}`
|
|
473
|
+
);
|
|
394
474
|
} else {
|
|
395
475
|
throw new Error("Invalid transport type");
|
|
396
476
|
}
|
|
@@ -406,6 +486,7 @@ var FastMCP = class {
|
|
|
406
486
|
};
|
|
407
487
|
export {
|
|
408
488
|
FastMCP,
|
|
489
|
+
FastMCPSession,
|
|
409
490
|
UserError,
|
|
410
491
|
imageContent
|
|
411
492
|
};
|