fastmcp 1.12.0 → 1.14.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 +82 -4
- package/dist/FastMCP.d.ts +33 -6
- package/dist/FastMCP.js +140 -30
- package/dist/FastMCP.js.map +1 -1
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/FastMCP.test.ts +142 -1
- package/src/FastMCP.ts +208 -32
package/README.md
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
A TypeScript framework for building [MCP](https://modelcontextprotocol.io/) servers capable of handling client sessions.
|
|
4
4
|
|
|
5
5
|
> [!NOTE]
|
|
6
|
+
>
|
|
6
7
|
> For a Python implementation, see [FastMCP](https://github.com/jlowin/fastmcp).
|
|
7
8
|
|
|
8
9
|
## Features
|
|
@@ -350,7 +351,7 @@ server.addTool({
|
|
|
350
351
|
|
|
351
352
|
Each resource is identified by a unique URI and can contain either text or binary data.
|
|
352
353
|
|
|
353
|
-
```
|
|
354
|
+
```ts
|
|
354
355
|
server.addResource({
|
|
355
356
|
uri: "file:///logs/app.log",
|
|
356
357
|
name: "Application Logs",
|
|
@@ -363,16 +364,92 @@ server.addResource({
|
|
|
363
364
|
});
|
|
364
365
|
```
|
|
365
366
|
|
|
367
|
+
> [!NOTE]
|
|
368
|
+
>
|
|
369
|
+
> `load` can return multiple resources. This could be used, for example, to return a list of files inside a directory when the directory is read.
|
|
370
|
+
>
|
|
371
|
+
> ```ts
|
|
372
|
+
> async load() {
|
|
373
|
+
> return [
|
|
374
|
+
> {
|
|
375
|
+
> text: "First file content",
|
|
376
|
+
> },
|
|
377
|
+
> {
|
|
378
|
+
> text: "Second file content",
|
|
379
|
+
> },
|
|
380
|
+
> ];
|
|
381
|
+
> }
|
|
382
|
+
> ```
|
|
383
|
+
|
|
366
384
|
You can also return binary contents in `load`:
|
|
367
385
|
|
|
368
|
-
```
|
|
386
|
+
```ts
|
|
369
387
|
async load() {
|
|
370
388
|
return {
|
|
371
389
|
blob: 'base64-encoded-data'
|
|
372
|
-
}
|
|
390
|
+
};
|
|
373
391
|
}
|
|
374
392
|
```
|
|
375
393
|
|
|
394
|
+
### Resource templates
|
|
395
|
+
|
|
396
|
+
You can also define resource templates:
|
|
397
|
+
|
|
398
|
+
```ts
|
|
399
|
+
server.addResourceTemplate({
|
|
400
|
+
uriTemplate: "file:///logs/{name}.log",
|
|
401
|
+
name: "Application Logs",
|
|
402
|
+
mimeType: "text/plain",
|
|
403
|
+
arguments: [
|
|
404
|
+
{
|
|
405
|
+
name: "name",
|
|
406
|
+
description: "Name of the log",
|
|
407
|
+
required: true,
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
async load({ name }) {
|
|
411
|
+
return {
|
|
412
|
+
text: `Example log content for ${name}`,
|
|
413
|
+
};
|
|
414
|
+
},
|
|
415
|
+
});
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
#### Resource template argument auto-completion
|
|
419
|
+
|
|
420
|
+
Provide `complete` functions for resource template arguments to enable automatic completion:
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
server.addResourceTemplate({
|
|
424
|
+
uriTemplate: "file:///logs/{name}.log",
|
|
425
|
+
name: "Application Logs",
|
|
426
|
+
mimeType: "text/plain",
|
|
427
|
+
arguments: [
|
|
428
|
+
{
|
|
429
|
+
name: "name",
|
|
430
|
+
description: "Name of the log",
|
|
431
|
+
required: true,
|
|
432
|
+
complete: async (value) => {
|
|
433
|
+
if (value === "Example") {
|
|
434
|
+
return {
|
|
435
|
+
values: ["Example Log"],
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
return {
|
|
440
|
+
values: [],
|
|
441
|
+
};
|
|
442
|
+
},
|
|
443
|
+
},
|
|
444
|
+
],
|
|
445
|
+
async load({ name }) {
|
|
446
|
+
return {
|
|
447
|
+
text: `Example log content for ${name}`,
|
|
448
|
+
};
|
|
449
|
+
},
|
|
450
|
+
});
|
|
451
|
+
```
|
|
452
|
+
|
|
376
453
|
### Prompts
|
|
377
454
|
|
|
378
455
|
[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.
|
|
@@ -426,7 +503,7 @@ server.addPrompt({
|
|
|
426
503
|
});
|
|
427
504
|
```
|
|
428
505
|
|
|
429
|
-
####
|
|
506
|
+
#### Prompt argument auto-completion using `enum`
|
|
430
507
|
|
|
431
508
|
If you provide an `enum` array for an argument, the server will automatically provide completions for the argument.
|
|
432
509
|
|
|
@@ -548,6 +625,7 @@ npx fastmcp inspect server.ts
|
|
|
548
625
|
## Showcase
|
|
549
626
|
|
|
550
627
|
> [!NOTE]
|
|
628
|
+
>
|
|
551
629
|
> If you've developed a server using FastMCP, please [submit a PR](https://github.com/punkpeye/fastmcp) to showcase it here!
|
|
552
630
|
|
|
553
631
|
- https://github.com/apinetwork/piapi-mcp-server
|
package/dist/FastMCP.d.ts
CHANGED
|
@@ -97,16 +97,35 @@ type Tool<Params extends ToolParameters = ToolParameters> = {
|
|
|
97
97
|
parameters?: Params;
|
|
98
98
|
execute: (args: z.infer<Params>, context: Context) => Promise<string | ContentResult | TextContent | ImageContent>;
|
|
99
99
|
};
|
|
100
|
+
type ResourceResult = {
|
|
101
|
+
text: string;
|
|
102
|
+
} | {
|
|
103
|
+
blob: string;
|
|
104
|
+
};
|
|
105
|
+
type InputResourceTemplateArgument = Readonly<{
|
|
106
|
+
name: string;
|
|
107
|
+
description?: string;
|
|
108
|
+
complete?: ArgumentValueCompleter;
|
|
109
|
+
}>;
|
|
110
|
+
type ResourceTemplateArgument = Readonly<{
|
|
111
|
+
name: string;
|
|
112
|
+
description?: string;
|
|
113
|
+
complete?: ArgumentValueCompleter;
|
|
114
|
+
}>;
|
|
115
|
+
type InputResourceTemplate<Arguments extends ResourceTemplateArgument[] = ResourceTemplateArgument[]> = {
|
|
116
|
+
uriTemplate: string;
|
|
117
|
+
name: string;
|
|
118
|
+
description?: string;
|
|
119
|
+
mimeType?: string;
|
|
120
|
+
arguments: Arguments;
|
|
121
|
+
};
|
|
100
122
|
type Resource = {
|
|
101
123
|
uri: string;
|
|
102
124
|
name: string;
|
|
103
125
|
description?: string;
|
|
104
126
|
mimeType?: string;
|
|
105
|
-
load: () => Promise<
|
|
106
|
-
|
|
107
|
-
} | {
|
|
108
|
-
blob: string;
|
|
109
|
-
}>;
|
|
127
|
+
load: () => Promise<ResourceResult | ResourceResult[]>;
|
|
128
|
+
complete?: (name: string, value: string) => Promise<Completion>;
|
|
110
129
|
};
|
|
111
130
|
type ArgumentValueCompleter = (value: string) => Promise<Completion>;
|
|
112
131
|
type InputPromptArgument = Readonly<{
|
|
@@ -153,13 +172,16 @@ declare class FastMCPSessionEventEmitter extends FastMCPSessionEventEmitterBase
|
|
|
153
172
|
}
|
|
154
173
|
declare class FastMCPSession extends FastMCPSessionEventEmitter {
|
|
155
174
|
#private;
|
|
156
|
-
constructor({ name, version, tools, resources, prompts, }: {
|
|
175
|
+
constructor({ name, version, tools, resources, resourcesTemplates, prompts, }: {
|
|
157
176
|
name: string;
|
|
158
177
|
version: string;
|
|
159
178
|
tools: Tool[];
|
|
160
179
|
resources: Resource[];
|
|
180
|
+
resourcesTemplates: InputResourceTemplate[];
|
|
161
181
|
prompts: Prompt[];
|
|
162
182
|
});
|
|
183
|
+
private addResource;
|
|
184
|
+
private addResourceTemplate;
|
|
163
185
|
private addPrompt;
|
|
164
186
|
get clientCapabilities(): ClientCapabilities | null;
|
|
165
187
|
get server(): Server;
|
|
@@ -173,6 +195,7 @@ declare class FastMCPSession extends FastMCPSessionEventEmitter {
|
|
|
173
195
|
private setupLoggingHandlers;
|
|
174
196
|
private setupToolHandlers;
|
|
175
197
|
private setupResourceHandlers;
|
|
198
|
+
private setupResourceTemplateHandlers;
|
|
176
199
|
private setupPromptHandlers;
|
|
177
200
|
}
|
|
178
201
|
declare const FastMCPEventEmitterBase: {
|
|
@@ -193,6 +216,10 @@ declare class FastMCP extends FastMCPEventEmitter {
|
|
|
193
216
|
* Adds a resource to the server.
|
|
194
217
|
*/
|
|
195
218
|
addResource(resource: Resource): void;
|
|
219
|
+
/**
|
|
220
|
+
* Adds a resource template to the server.
|
|
221
|
+
*/
|
|
222
|
+
addResourceTemplate<const Args extends InputResourceTemplateArgument[]>(resource: InputResourceTemplate<Args>): void;
|
|
196
223
|
/**
|
|
197
224
|
* Adds a prompt to the server.
|
|
198
225
|
*/
|
package/dist/FastMCP.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
GetPromptRequestSchema,
|
|
9
9
|
ListPromptsRequestSchema,
|
|
10
10
|
ListResourcesRequestSchema,
|
|
11
|
+
ListResourceTemplatesRequestSchema,
|
|
11
12
|
ListToolsRequestSchema,
|
|
12
13
|
McpError,
|
|
13
14
|
ReadResourceRequestSchema,
|
|
@@ -108,16 +109,19 @@ var FastMCPSessionEventEmitter = class extends FastMCPSessionEventEmitterBase {
|
|
|
108
109
|
};
|
|
109
110
|
var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
110
111
|
#capabilities = {};
|
|
111
|
-
#loggingLevel = "info";
|
|
112
|
-
#server;
|
|
113
112
|
#clientCapabilities;
|
|
114
|
-
#
|
|
113
|
+
#loggingLevel = "info";
|
|
115
114
|
#prompts = [];
|
|
115
|
+
#resources = [];
|
|
116
|
+
#resourceTemplates = [];
|
|
117
|
+
#roots = [];
|
|
118
|
+
#server;
|
|
116
119
|
constructor({
|
|
117
120
|
name,
|
|
118
121
|
version,
|
|
119
122
|
tools,
|
|
120
123
|
resources,
|
|
124
|
+
resourcesTemplates,
|
|
121
125
|
prompts
|
|
122
126
|
}) {
|
|
123
127
|
super();
|
|
@@ -146,12 +150,44 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
146
150
|
this.setupToolHandlers(tools);
|
|
147
151
|
}
|
|
148
152
|
if (resources.length) {
|
|
153
|
+
for (const resource of resources) {
|
|
154
|
+
this.addResource(resource);
|
|
155
|
+
}
|
|
149
156
|
this.setupResourceHandlers(resources);
|
|
150
157
|
}
|
|
158
|
+
if (resourcesTemplates.length) {
|
|
159
|
+
for (const resourceTemplate of resourcesTemplates) {
|
|
160
|
+
this.addResourceTemplate(resourceTemplate);
|
|
161
|
+
}
|
|
162
|
+
this.setupResourceTemplateHandlers(resourcesTemplates);
|
|
163
|
+
}
|
|
151
164
|
if (prompts.length) {
|
|
152
165
|
this.setupPromptHandlers(prompts);
|
|
153
166
|
}
|
|
154
167
|
}
|
|
168
|
+
addResource(inputResource) {
|
|
169
|
+
this.#resources.push(inputResource);
|
|
170
|
+
}
|
|
171
|
+
addResourceTemplate(inputResourceTemplate) {
|
|
172
|
+
const completers = {};
|
|
173
|
+
for (const argument of inputResourceTemplate.arguments ?? []) {
|
|
174
|
+
if (argument.complete) {
|
|
175
|
+
completers[argument.name] = argument.complete;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const resourceTemplate = {
|
|
179
|
+
...inputResourceTemplate,
|
|
180
|
+
complete: async (name, value) => {
|
|
181
|
+
if (completers[name]) {
|
|
182
|
+
return await completers[name](value);
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
values: []
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
this.#resourceTemplates.push(resourceTemplate);
|
|
190
|
+
}
|
|
155
191
|
addPrompt(inputPrompt) {
|
|
156
192
|
const completers = {};
|
|
157
193
|
const enums = {};
|
|
@@ -267,6 +303,36 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
267
303
|
completion
|
|
268
304
|
};
|
|
269
305
|
}
|
|
306
|
+
if (request.params.ref.type === "ref/resource") {
|
|
307
|
+
const resource = this.#resourceTemplates.find(
|
|
308
|
+
(resource2) => resource2.uriTemplate === request.params.ref.uri
|
|
309
|
+
);
|
|
310
|
+
if (!resource) {
|
|
311
|
+
throw new UnexpectedStateError("Unknown resource", {
|
|
312
|
+
request
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
if (!("uriTemplate" in resource)) {
|
|
316
|
+
throw new UnexpectedStateError("Unexpected resource");
|
|
317
|
+
}
|
|
318
|
+
if (!resource.complete) {
|
|
319
|
+
throw new UnexpectedStateError(
|
|
320
|
+
"Resource does not support completion",
|
|
321
|
+
{
|
|
322
|
+
request
|
|
323
|
+
}
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
const completion = CompletionZodSchema.parse(
|
|
327
|
+
await resource.complete(
|
|
328
|
+
request.params.argument.name,
|
|
329
|
+
request.params.argument.value
|
|
330
|
+
)
|
|
331
|
+
);
|
|
332
|
+
return {
|
|
333
|
+
completion
|
|
334
|
+
};
|
|
335
|
+
}
|
|
270
336
|
throw new UnexpectedStateError("Unexpected completion request", {
|
|
271
337
|
request
|
|
272
338
|
});
|
|
@@ -417,36 +483,71 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
417
483
|
this.#server.setRequestHandler(
|
|
418
484
|
ReadResourceRequestSchema,
|
|
419
485
|
async (request) => {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
if (!resource) {
|
|
424
|
-
throw new McpError(
|
|
425
|
-
ErrorCode.MethodNotFound,
|
|
426
|
-
`Unknown resource: ${request.params.uri}`
|
|
427
|
-
);
|
|
428
|
-
}
|
|
429
|
-
let result;
|
|
430
|
-
try {
|
|
431
|
-
result = await resource.load();
|
|
432
|
-
} catch (error) {
|
|
433
|
-
throw new McpError(
|
|
434
|
-
ErrorCode.InternalError,
|
|
435
|
-
`Error reading resource: ${error}`,
|
|
436
|
-
{
|
|
437
|
-
uri: resource.uri
|
|
438
|
-
}
|
|
486
|
+
if ("uri" in request.params) {
|
|
487
|
+
const resource = resources.find(
|
|
488
|
+
(resource2) => "uri" in resource2 && resource2.uri === request.params.uri
|
|
439
489
|
);
|
|
490
|
+
if (!resource) {
|
|
491
|
+
throw new McpError(
|
|
492
|
+
ErrorCode.MethodNotFound,
|
|
493
|
+
`Unknown resource: ${request.params.uri}`
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
if (!("uri" in resource)) {
|
|
497
|
+
throw new UnexpectedStateError("Resource does not support reading");
|
|
498
|
+
}
|
|
499
|
+
let maybeArrayResult;
|
|
500
|
+
try {
|
|
501
|
+
maybeArrayResult = await resource.load();
|
|
502
|
+
} catch (error) {
|
|
503
|
+
throw new McpError(
|
|
504
|
+
ErrorCode.InternalError,
|
|
505
|
+
`Error reading resource: ${error}`,
|
|
506
|
+
{
|
|
507
|
+
uri: resource.uri
|
|
508
|
+
}
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
if (Array.isArray(maybeArrayResult)) {
|
|
512
|
+
return {
|
|
513
|
+
contents: maybeArrayResult.map((result) => ({
|
|
514
|
+
uri: resource.uri,
|
|
515
|
+
mimeType: resource.mimeType,
|
|
516
|
+
name: resource.name,
|
|
517
|
+
...result
|
|
518
|
+
}))
|
|
519
|
+
};
|
|
520
|
+
} else {
|
|
521
|
+
return {
|
|
522
|
+
contents: [
|
|
523
|
+
{
|
|
524
|
+
uri: resource.uri,
|
|
525
|
+
mimeType: resource.mimeType,
|
|
526
|
+
name: resource.name,
|
|
527
|
+
...maybeArrayResult
|
|
528
|
+
}
|
|
529
|
+
]
|
|
530
|
+
};
|
|
531
|
+
}
|
|
440
532
|
}
|
|
533
|
+
throw new UnexpectedStateError("Unknown resource request", {
|
|
534
|
+
request
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
setupResourceTemplateHandlers(resourceTemplates) {
|
|
540
|
+
this.#capabilities.resources = {};
|
|
541
|
+
this.#server.setRequestHandler(
|
|
542
|
+
ListResourceTemplatesRequestSchema,
|
|
543
|
+
async () => {
|
|
441
544
|
return {
|
|
442
|
-
|
|
443
|
-
{
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
}
|
|
449
|
-
]
|
|
545
|
+
resourceTemplates: resourceTemplates.map((resourceTemplate) => {
|
|
546
|
+
return {
|
|
547
|
+
name: resourceTemplate.name,
|
|
548
|
+
uriTemplate: resourceTemplate.uriTemplate
|
|
549
|
+
};
|
|
550
|
+
})
|
|
450
551
|
};
|
|
451
552
|
}
|
|
452
553
|
);
|
|
@@ -516,6 +617,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
516
617
|
#options;
|
|
517
618
|
#prompts = [];
|
|
518
619
|
#resources = [];
|
|
620
|
+
#resourcesTemplates = [];
|
|
519
621
|
#sessions = [];
|
|
520
622
|
#sseServer = null;
|
|
521
623
|
#tools = [];
|
|
@@ -534,6 +636,12 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
534
636
|
addResource(resource) {
|
|
535
637
|
this.#resources.push(resource);
|
|
536
638
|
}
|
|
639
|
+
/**
|
|
640
|
+
* Adds a resource template to the server.
|
|
641
|
+
*/
|
|
642
|
+
addResourceTemplate(resource) {
|
|
643
|
+
this.#resourcesTemplates.push(resource);
|
|
644
|
+
}
|
|
537
645
|
/**
|
|
538
646
|
* Adds a prompt to the server.
|
|
539
647
|
*/
|
|
@@ -553,6 +661,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
553
661
|
version: this.#options.version,
|
|
554
662
|
tools: this.#tools,
|
|
555
663
|
resources: this.#resources,
|
|
664
|
+
resourcesTemplates: this.#resourcesTemplates,
|
|
556
665
|
prompts: this.#prompts
|
|
557
666
|
});
|
|
558
667
|
await session.connect(transport);
|
|
@@ -571,6 +680,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
571
680
|
version: this.#options.version,
|
|
572
681
|
tools: this.#tools,
|
|
573
682
|
resources: this.#resources,
|
|
683
|
+
resourcesTemplates: this.#resourcesTemplates,
|
|
574
684
|
prompts: this.#prompts
|
|
575
685
|
});
|
|
576
686
|
},
|
package/dist/FastMCP.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/FastMCP.ts"],"sourcesContent":["import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ClientCapabilities,\n CompleteRequestSchema,\n ErrorCode,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n McpError,\n ReadResourceRequestSchema,\n Root,\n RootsListChangedNotificationSchema,\n ServerCapabilities,\n SetLevelRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { z } from \"zod\";\nimport { setTimeout as delay } from \"timers/promises\";\nimport { readFile } from \"fs/promises\";\nimport { fileTypeFromBuffer } from \"file-type\";\nimport { StrictEventEmitter } from \"strict-event-emitter-types\";\nimport { EventEmitter } from \"events\";\nimport Fuse from \"fuse.js\";\nimport { startSSEServer } from \"mcp-proxy\";\nimport { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\n\nexport type SSEServer = {\n close: () => Promise<void>;\n};\n\ntype FastMCPEvents = {\n connect: (event: { session: FastMCPSession }) => void;\n disconnect: (event: { session: FastMCPSession }) => void;\n};\n\ntype FastMCPSessionEvents = {\n rootsChanged: (event: { roots: Root[] }) => void;\n error: (event: { error: Error }) => void;\n};\n\n/**\n * Generates an image content object from a URL, file path, or buffer.\n */\nexport const imageContent = async (\n input: { url: string } | { path: string } | { buffer: Buffer },\n): Promise<ImageContent> => {\n let rawData: Buffer;\n\n if (\"url\" in input) {\n const response = await fetch(input.url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch image from URL: ${response.statusText}`);\n }\n\n rawData = Buffer.from(await response.arrayBuffer());\n } else if (\"path\" in input) {\n rawData = await readFile(input.path);\n } else if (\"buffer\" in input) {\n rawData = input.buffer;\n } else {\n throw new Error(\n \"Invalid input: Provide a valid 'url', 'path', or 'buffer'\",\n );\n }\n\n const mimeType = await fileTypeFromBuffer(rawData);\n\n const base64Data = rawData.toString(\"base64\");\n\n return {\n type: \"image\",\n data: base64Data,\n mimeType: mimeType?.mime ?? \"image/png\",\n } as const;\n};\n\nabstract class FastMCPError extends Error {\n public constructor(message?: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\ntype Extra = unknown;\n\ntype Extras = Record<string, Extra>;\n\nexport class UnexpectedStateError extends FastMCPError {\n public extras?: Extras;\n\n public constructor(message: string, extras?: Extras) {\n super(message);\n this.name = new.target.name;\n this.extras = extras;\n }\n}\n\n/**\n * An error that is meant to be surfaced to the user.\n */\nexport class UserError extends UnexpectedStateError {}\n\ntype ToolParameters = z.ZodTypeAny;\n\ntype Literal = boolean | null | number | string | undefined;\n\ntype SerializableValue =\n | Literal\n | SerializableValue[]\n | { [key: string]: SerializableValue };\n\ntype Progress = {\n /**\n * The progress thus far. This should increase every time progress is made, even if the total is unknown.\n */\n progress: number;\n /**\n * Total number of items to process (or total progress required), if known.\n */\n total?: number;\n};\n\ntype Context = {\n reportProgress: (progress: Progress) => Promise<void>;\n log: {\n debug: (message: string, data?: SerializableValue) => void;\n error: (message: string, data?: SerializableValue) => void;\n info: (message: string, data?: SerializableValue) => void;\n warn: (message: string, data?: SerializableValue) => void;\n };\n};\n\ntype TextContent = {\n type: \"text\";\n text: string;\n};\n\nconst TextContentZodSchema = z\n .object({\n type: z.literal(\"text\"),\n /**\n * The text content of the message.\n */\n text: z.string(),\n })\n .strict() satisfies z.ZodType<TextContent>;\n\ntype ImageContent = {\n type: \"image\";\n data: string;\n mimeType: string;\n};\n\nconst ImageContentZodSchema = z\n .object({\n type: z.literal(\"image\"),\n /**\n * The base64-encoded image data.\n */\n data: z.string().base64(),\n /**\n * The MIME type of the image. Different providers may support different image types.\n */\n mimeType: z.string(),\n })\n .strict() satisfies z.ZodType<ImageContent>;\n\ntype Content = TextContent | ImageContent;\n\nconst ContentZodSchema = z.discriminatedUnion(\"type\", [\n TextContentZodSchema,\n ImageContentZodSchema,\n]) satisfies z.ZodType<Content>;\n\ntype ContentResult = {\n content: Content[];\n isError?: boolean;\n};\n\nconst ContentResultZodSchema = z\n .object({\n content: ContentZodSchema.array(),\n isError: z.boolean().optional(),\n })\n .strict() satisfies z.ZodType<ContentResult>;\n\ntype Completion = {\n values: string[];\n total?: number;\n hasMore?: boolean;\n};\n\n/**\n * https://github.com/modelcontextprotocol/typescript-sdk/blob/3164da64d085ec4e022ae881329eee7b72f208d4/src/types.ts#L983-L1003\n */\nconst CompletionZodSchema = z.object({\n /**\n * An array of completion values. Must not exceed 100 items.\n */\n values: z.array(z.string()).max(100),\n /**\n * The total number of completion options available. This can exceed the number of values actually sent in the response.\n */\n total: z.optional(z.number().int()),\n /**\n * Indicates whether there are additional completion options beyond those provided in the current response, even if the exact total is unknown.\n */\n hasMore: z.optional(z.boolean()),\n}) satisfies z.ZodType<Completion>;\n\ntype Tool<Params extends ToolParameters = ToolParameters> = {\n name: string;\n description?: string;\n parameters?: Params;\n execute: (\n args: z.infer<Params>,\n context: Context,\n ) => Promise<string | ContentResult | TextContent | ImageContent>;\n};\n\ntype Resource = {\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n load: () => Promise<{ text: string } | { blob: string }>;\n};\n\ntype ArgumentValueCompleter = (value: string) => Promise<Completion>;\n\ntype InputPromptArgument = Readonly<{\n name: string;\n description?: string;\n required?: boolean;\n complete?: ArgumentValueCompleter;\n enum?: string[];\n}>;\n\ntype ArgumentsToObject<T extends InputPromptArgument[]> = {\n [K in T[number][\"name\"]]: Extract<\n T[number],\n { name: K }\n >[\"required\"] extends true\n ? string\n : string | undefined;\n};\n\ntype InputPrompt<\n Arguments extends InputPromptArgument[] = InputPromptArgument[],\n Args = ArgumentsToObject<Arguments>,\n> = {\n name: string;\n description?: string;\n arguments?: InputPromptArgument[];\n load: (args: Args) => Promise<string>;\n};\n\ntype PromptArgument = Readonly<{\n name: string;\n description?: string;\n required?: boolean;\n complete?: ArgumentValueCompleter;\n enum?: string[];\n}>;\n\ntype Prompt<\n Arguments extends PromptArgument[] = PromptArgument[],\n Args = ArgumentsToObject<Arguments>,\n> = {\n arguments?: PromptArgument[];\n complete?: (name: string, value: string) => Promise<Completion>;\n description?: string;\n load: (args: Args) => Promise<string>;\n name: string;\n};\n\ntype ServerOptions = {\n name: string;\n version: `${number}.${number}.${number}`;\n};\n\ntype LoggingLevel =\n | \"debug\"\n | \"info\"\n | \"notice\"\n | \"warning\"\n | \"error\"\n | \"critical\"\n | \"alert\"\n | \"emergency\";\n\nconst FastMCPSessionEventEmitterBase: {\n new (): StrictEventEmitter<EventEmitter, FastMCPSessionEvents>;\n} = EventEmitter;\n\nclass FastMCPSessionEventEmitter extends FastMCPSessionEventEmitterBase {}\n\nexport class FastMCPSession extends FastMCPSessionEventEmitter {\n #capabilities: ServerCapabilities = {};\n #loggingLevel: LoggingLevel = \"info\";\n #server: Server;\n #clientCapabilities?: ClientCapabilities;\n #roots: Root[] = [];\n #prompts: Prompt[] = [];\n\n constructor({\n name,\n version,\n tools,\n resources,\n prompts,\n }: {\n name: string;\n version: string;\n tools: Tool[];\n resources: Resource[];\n prompts: Prompt[];\n }) {\n super();\n\n if (tools.length) {\n this.#capabilities.tools = {};\n }\n\n if (resources.length) {\n this.#capabilities.resources = {};\n }\n\n if (prompts.length) {\n for (const prompt of prompts) {\n this.addPrompt(prompt);\n }\n\n this.#capabilities.prompts = {};\n }\n\n this.#capabilities.logging = {};\n\n this.#server = new Server(\n { name: name, version: version },\n { capabilities: this.#capabilities },\n );\n\n this.setupErrorHandling();\n this.setupLoggingHandlers();\n this.setupRootsHandlers();\n this.setupCompleteHandlers();\n\n if (tools.length) {\n this.setupToolHandlers(tools);\n }\n\n if (resources.length) {\n this.setupResourceHandlers(resources);\n }\n\n if (prompts.length) {\n this.setupPromptHandlers(prompts);\n }\n }\n\n private addPrompt(inputPrompt: InputPrompt) {\n const completers: Record<string, ArgumentValueCompleter> = {};\n const enums: Record<string, string[]> = {};\n\n for (const argument of inputPrompt.arguments ?? []) {\n if (argument.complete) {\n completers[argument.name] = argument.complete;\n }\n\n if (argument.enum) {\n enums[argument.name] = argument.enum;\n }\n }\n\n const prompt = {\n ...inputPrompt,\n complete: async (name: string, value: string) => {\n if (completers[name]) {\n return await completers[name](value);\n }\n\n if (enums[name]) {\n const fuse = new Fuse(enums[name], {\n keys: [\"value\"],\n });\n\n const result = fuse.search(value);\n\n return {\n values: result.map((item) => item.item),\n total: result.length,\n };\n }\n\n return {\n values: [],\n };\n },\n };\n\n this.#prompts.push(prompt);\n }\n\n public get clientCapabilities(): ClientCapabilities | null {\n return this.#clientCapabilities ?? null;\n }\n\n public get server(): Server {\n return this.#server;\n }\n\n #pingInterval: ReturnType<typeof setInterval> | null = null;\n\n public async connect(transport: Transport) {\n if (this.#server.transport) {\n throw new UnexpectedStateError(\"Server is already connected\");\n }\n\n await this.#server.connect(transport);\n\n let attempt = 0;\n\n while (attempt++ < 10) {\n const capabilities = await this.#server.getClientCapabilities();\n\n if (capabilities) {\n this.#clientCapabilities = capabilities;\n\n break;\n }\n\n await delay(100);\n }\n\n if (!this.#clientCapabilities) {\n throw new UnexpectedStateError(\"Server did not connect\");\n }\n\n if (this.#clientCapabilities?.roots) {\n const roots = await this.#server.listRoots();\n\n this.#roots = roots.roots;\n }\n\n this.#pingInterval = setInterval(async () => {\n try {\n await this.#server.ping();\n } catch (error) {\n this.emit(\"error\", {\n error: error as Error,\n });\n }\n }, 1000);\n }\n\n public get roots(): Root[] {\n return this.#roots;\n }\n\n public async close() {\n if (this.#pingInterval) {\n clearInterval(this.#pingInterval);\n }\n\n await this.#server.close();\n }\n\n private setupErrorHandling() {\n this.#server.onerror = (error) => {\n console.error(\"[MCP Error]\", error);\n };\n }\n\n public get loggingLevel(): LoggingLevel {\n return this.#loggingLevel;\n }\n\n private setupCompleteHandlers() {\n this.#server.setRequestHandler(CompleteRequestSchema, async (request) => {\n if (request.params.ref.type === \"ref/prompt\") {\n const prompt = this.#prompts.find(\n (prompt) => prompt.name === request.params.ref.name,\n );\n\n if (!prompt) {\n throw new UnexpectedStateError(\"Unknown prompt\", {\n request,\n });\n }\n\n if (!prompt.complete) {\n throw new UnexpectedStateError(\"Prompt does not support completion\", {\n request,\n });\n }\n\n const completion = CompletionZodSchema.parse(\n await prompt.complete(\n request.params.argument.name,\n request.params.argument.value,\n ),\n );\n\n return {\n completion,\n };\n }\n\n throw new UnexpectedStateError(\"Unexpected completion request\", {\n request,\n });\n });\n }\n\n private setupRootsHandlers() {\n this.#server.setNotificationHandler(\n RootsListChangedNotificationSchema,\n () => {\n this.#server.listRoots().then((roots) => {\n this.#roots = roots.roots;\n\n this.emit(\"rootsChanged\", {\n roots: roots.roots,\n });\n });\n },\n );\n }\n\n private setupLoggingHandlers() {\n this.#server.setRequestHandler(SetLevelRequestSchema, (request) => {\n this.#loggingLevel = request.params.level;\n\n return {};\n });\n }\n\n private setupToolHandlers(tools: Tool[]) {\n this.#server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: tools.map((tool) => {\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.parameters\n ? zodToJsonSchema(tool.parameters)\n : undefined,\n };\n }),\n };\n });\n\n this.#server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const tool = tools.find((tool) => tool.name === request.params.name);\n\n if (!tool) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown tool: ${request.params.name}`,\n );\n }\n\n let args: any = undefined;\n\n if (tool.parameters) {\n const parsed = tool.parameters.safeParse(request.params.arguments);\n\n if (!parsed.success) {\n throw new McpError(\n ErrorCode.InvalidRequest,\n `Invalid ${request.params.name} arguments`,\n );\n }\n\n args = parsed.data;\n }\n\n const progressToken = request.params?._meta?.progressToken;\n\n let result: ContentResult;\n\n try {\n const reportProgress = async (progress: Progress) => {\n await this.#server.notification({\n method: \"notifications/progress\",\n params: {\n ...progress,\n progressToken,\n },\n });\n };\n\n const log = {\n debug: (message: string, context?: SerializableValue) => {\n this.#server.sendLoggingMessage({\n level: \"debug\",\n data: {\n message,\n context,\n },\n });\n },\n error: (message: string, context?: SerializableValue) => {\n this.#server.sendLoggingMessage({\n level: \"error\",\n data: {\n message,\n context,\n },\n });\n },\n info: (message: string, context?: SerializableValue) => {\n this.#server.sendLoggingMessage({\n level: \"info\",\n data: {\n message,\n context,\n },\n });\n },\n warn: (message: string, context?: SerializableValue) => {\n this.#server.sendLoggingMessage({\n level: \"warning\",\n data: {\n message,\n context,\n },\n });\n },\n };\n\n const maybeStringResult = await tool.execute(args, {\n reportProgress,\n log,\n });\n\n if (typeof maybeStringResult === \"string\") {\n result = ContentResultZodSchema.parse({\n content: [{ type: \"text\", text: maybeStringResult }],\n });\n } else if (\"type\" in maybeStringResult) {\n result = ContentResultZodSchema.parse({\n content: [maybeStringResult],\n });\n } else {\n result = ContentResultZodSchema.parse(maybeStringResult);\n }\n } catch (error) {\n if (error instanceof UserError) {\n return {\n content: [{ type: \"text\", text: error.message }],\n isError: true,\n };\n }\n\n return {\n content: [{ type: \"text\", text: `Error: ${error}` }],\n isError: true,\n };\n }\n\n return result;\n });\n }\n\n private setupResourceHandlers(resources: Resource[]) {\n this.#server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: resources.map((resource) => {\n return {\n uri: resource.uri,\n name: resource.name,\n mimeType: resource.mimeType,\n };\n }),\n };\n });\n\n this.#server.setRequestHandler(\n ReadResourceRequestSchema,\n async (request) => {\n const resource = resources.find(\n (resource) => resource.uri === request.params.uri,\n );\n\n if (!resource) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown resource: ${request.params.uri}`,\n );\n }\n\n let result: Awaited<ReturnType<Resource[\"load\"]>>;\n\n try {\n result = await resource.load();\n } catch (error) {\n throw new McpError(\n ErrorCode.InternalError,\n `Error reading resource: ${error}`,\n {\n uri: resource.uri,\n },\n );\n }\n\n return {\n contents: [\n {\n uri: resource.uri,\n mimeType: resource.mimeType,\n name: resource.name,\n ...result,\n },\n ],\n };\n },\n );\n }\n\n private setupPromptHandlers(prompts: Prompt[]) {\n this.#server.setRequestHandler(ListPromptsRequestSchema, async () => {\n return {\n prompts: prompts.map((prompt) => {\n return {\n name: prompt.name,\n description: prompt.description,\n arguments: prompt.arguments,\n complete: prompt.complete,\n };\n }),\n };\n });\n\n this.#server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const prompt = prompts.find(\n (prompt) => prompt.name === request.params.name,\n );\n\n if (!prompt) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown prompt: ${request.params.name}`,\n );\n }\n\n const args = request.params.arguments;\n\n for (const arg of prompt.arguments ?? []) {\n if (arg.required && !(args && arg.name in args)) {\n throw new McpError(\n ErrorCode.InvalidRequest,\n `Missing required argument: ${arg.name}`,\n );\n }\n }\n\n let result: Awaited<ReturnType<Prompt[\"load\"]>>;\n\n try {\n result = await prompt.load(args as Record<string, string | undefined>);\n } catch (error) {\n throw new McpError(\n ErrorCode.InternalError,\n `Error loading prompt: ${error}`,\n );\n }\n\n return {\n description: prompt.description,\n messages: [\n {\n role: \"user\",\n content: { type: \"text\", text: result },\n },\n ],\n };\n });\n }\n}\n\nconst FastMCPEventEmitterBase: {\n new (): StrictEventEmitter<EventEmitter, FastMCPEvents>;\n} = EventEmitter;\n\nclass FastMCPEventEmitter extends FastMCPEventEmitterBase {}\n\nexport class FastMCP extends FastMCPEventEmitter {\n #options: ServerOptions;\n #prompts: InputPrompt[] = [];\n #resources: Resource[] = [];\n #sessions: FastMCPSession[] = [];\n #sseServer: SSEServer | null = null;\n #tools: Tool[] = [];\n\n constructor(public options: ServerOptions) {\n super();\n\n this.#options = options;\n }\n\n public get sessions(): FastMCPSession[] {\n return this.#sessions;\n }\n\n /**\n * Adds a tool to the server.\n */\n public addTool<Params extends ToolParameters>(tool: Tool<Params>) {\n this.#tools.push(tool as unknown as Tool);\n }\n\n /**\n * Adds a resource to the server.\n */\n public addResource(resource: Resource) {\n this.#resources.push(resource);\n }\n\n /**\n * Adds a prompt to the server.\n */\n public addPrompt<const Args extends InputPromptArgument[]>(\n prompt: InputPrompt<Args>,\n ) {\n this.#prompts.push(prompt);\n }\n\n /**\n * Starts the server.\n */\n public async start(\n options:\n | { transportType: \"stdio\" }\n | {\n transportType: \"sse\";\n sse: { endpoint: `/${string}`; port: number };\n } = {\n transportType: \"stdio\",\n },\n ) {\n if (options.transportType === \"stdio\") {\n const transport = new StdioServerTransport();\n\n const session = new FastMCPSession({\n name: this.#options.name,\n version: this.#options.version,\n tools: this.#tools,\n resources: this.#resources,\n prompts: this.#prompts,\n });\n\n await session.connect(transport);\n\n this.#sessions.push(session);\n\n this.emit(\"connect\", {\n session,\n });\n\n console.error(`server is running on stdio`);\n } else if (options.transportType === \"sse\") {\n this.#sseServer = await startSSEServer<FastMCPSession>({\n endpoint: options.sse.endpoint as `/${string}`,\n port: options.sse.port,\n createServer: async () => {\n return new FastMCPSession({\n name: this.#options.name,\n version: this.#options.version,\n tools: this.#tools,\n resources: this.#resources,\n prompts: this.#prompts,\n });\n },\n onClose: (session) => {\n this.emit(\"disconnect\", {\n session,\n });\n },\n onConnect: async (session) => {\n this.#sessions.push(session);\n\n this.emit(\"connect\", {\n session,\n });\n },\n });\n\n console.error(\n `server is running on SSE at http://localhost:${options.sse.port}${options.sse.endpoint}`,\n );\n } else {\n throw new Error(\"Invalid transport type\");\n }\n }\n\n /**\n * Stops the server.\n */\n public async stop() {\n if (this.#sseServer) {\n this.#sseServer.close();\n }\n }\n}\n"],"mappings":"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","names":["prompt","tool","resource"]}
|
|
1
|
+
{"version":3,"sources":["../src/FastMCP.ts"],"sourcesContent":["import { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ClientCapabilities,\n CompleteRequestSchema,\n ErrorCode,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourcesRequestSchema,\n ListResourceTemplatesRequestSchema,\n ListToolsRequestSchema,\n McpError,\n ReadResourceRequestSchema,\n Root,\n RootsListChangedNotificationSchema,\n ServerCapabilities,\n SetLevelRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport { z } from \"zod\";\nimport { setTimeout as delay } from \"timers/promises\";\nimport { readFile } from \"fs/promises\";\nimport { fileTypeFromBuffer } from \"file-type\";\nimport { StrictEventEmitter } from \"strict-event-emitter-types\";\nimport { EventEmitter } from \"events\";\nimport Fuse from \"fuse.js\";\nimport { startSSEServer } from \"mcp-proxy\";\nimport { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\n\nexport type SSEServer = {\n close: () => Promise<void>;\n};\n\ntype FastMCPEvents = {\n connect: (event: { session: FastMCPSession }) => void;\n disconnect: (event: { session: FastMCPSession }) => void;\n};\n\ntype FastMCPSessionEvents = {\n rootsChanged: (event: { roots: Root[] }) => void;\n error: (event: { error: Error }) => void;\n};\n\n/**\n * Generates an image content object from a URL, file path, or buffer.\n */\nexport const imageContent = async (\n input: { url: string } | { path: string } | { buffer: Buffer },\n): Promise<ImageContent> => {\n let rawData: Buffer;\n\n if (\"url\" in input) {\n const response = await fetch(input.url);\n\n if (!response.ok) {\n throw new Error(`Failed to fetch image from URL: ${response.statusText}`);\n }\n\n rawData = Buffer.from(await response.arrayBuffer());\n } else if (\"path\" in input) {\n rawData = await readFile(input.path);\n } else if (\"buffer\" in input) {\n rawData = input.buffer;\n } else {\n throw new Error(\n \"Invalid input: Provide a valid 'url', 'path', or 'buffer'\",\n );\n }\n\n const mimeType = await fileTypeFromBuffer(rawData);\n\n const base64Data = rawData.toString(\"base64\");\n\n return {\n type: \"image\",\n data: base64Data,\n mimeType: mimeType?.mime ?? \"image/png\",\n } as const;\n};\n\nabstract class FastMCPError extends Error {\n public constructor(message?: string) {\n super(message);\n this.name = new.target.name;\n }\n}\n\ntype Extra = unknown;\n\ntype Extras = Record<string, Extra>;\n\nexport class UnexpectedStateError extends FastMCPError {\n public extras?: Extras;\n\n public constructor(message: string, extras?: Extras) {\n super(message);\n this.name = new.target.name;\n this.extras = extras;\n }\n}\n\n/**\n * An error that is meant to be surfaced to the user.\n */\nexport class UserError extends UnexpectedStateError {}\n\ntype ToolParameters = z.ZodTypeAny;\n\ntype Literal = boolean | null | number | string | undefined;\n\ntype SerializableValue =\n | Literal\n | SerializableValue[]\n | { [key: string]: SerializableValue };\n\ntype Progress = {\n /**\n * The progress thus far. This should increase every time progress is made, even if the total is unknown.\n */\n progress: number;\n /**\n * Total number of items to process (or total progress required), if known.\n */\n total?: number;\n};\n\ntype Context = {\n reportProgress: (progress: Progress) => Promise<void>;\n log: {\n debug: (message: string, data?: SerializableValue) => void;\n error: (message: string, data?: SerializableValue) => void;\n info: (message: string, data?: SerializableValue) => void;\n warn: (message: string, data?: SerializableValue) => void;\n };\n};\n\ntype TextContent = {\n type: \"text\";\n text: string;\n};\n\nconst TextContentZodSchema = z\n .object({\n type: z.literal(\"text\"),\n /**\n * The text content of the message.\n */\n text: z.string(),\n })\n .strict() satisfies z.ZodType<TextContent>;\n\ntype ImageContent = {\n type: \"image\";\n data: string;\n mimeType: string;\n};\n\nconst ImageContentZodSchema = z\n .object({\n type: z.literal(\"image\"),\n /**\n * The base64-encoded image data.\n */\n data: z.string().base64(),\n /**\n * The MIME type of the image. Different providers may support different image types.\n */\n mimeType: z.string(),\n })\n .strict() satisfies z.ZodType<ImageContent>;\n\ntype Content = TextContent | ImageContent;\n\nconst ContentZodSchema = z.discriminatedUnion(\"type\", [\n TextContentZodSchema,\n ImageContentZodSchema,\n]) satisfies z.ZodType<Content>;\n\ntype ContentResult = {\n content: Content[];\n isError?: boolean;\n};\n\nconst ContentResultZodSchema = z\n .object({\n content: ContentZodSchema.array(),\n isError: z.boolean().optional(),\n })\n .strict() satisfies z.ZodType<ContentResult>;\n\ntype Completion = {\n values: string[];\n total?: number;\n hasMore?: boolean;\n};\n\n/**\n * https://github.com/modelcontextprotocol/typescript-sdk/blob/3164da64d085ec4e022ae881329eee7b72f208d4/src/types.ts#L983-L1003\n */\nconst CompletionZodSchema = z.object({\n /**\n * An array of completion values. Must not exceed 100 items.\n */\n values: z.array(z.string()).max(100),\n /**\n * The total number of completion options available. This can exceed the number of values actually sent in the response.\n */\n total: z.optional(z.number().int()),\n /**\n * Indicates whether there are additional completion options beyond those provided in the current response, even if the exact total is unknown.\n */\n hasMore: z.optional(z.boolean()),\n}) satisfies z.ZodType<Completion>;\n\ntype Tool<Params extends ToolParameters = ToolParameters> = {\n name: string;\n description?: string;\n parameters?: Params;\n execute: (\n args: z.infer<Params>,\n context: Context,\n ) => Promise<string | ContentResult | TextContent | ImageContent>;\n};\n\ntype ResourceResult =\n | {\n text: string;\n }\n | {\n blob: string;\n };\n\ntype InputResourceTemplateArgument = Readonly<{\n name: string;\n description?: string;\n complete?: ArgumentValueCompleter;\n}>;\n\ntype ResourceTemplateArgument = Readonly<{\n name: string;\n description?: string;\n complete?: ArgumentValueCompleter;\n}>;\n\ntype ResourceTemplate<\n Arguments extends ResourceTemplateArgument[] = ResourceTemplateArgument[],\n> = {\n uriTemplate: string;\n name: string;\n description?: string;\n mimeType?: string;\n arguments: Arguments;\n complete?: (name: string, value: string) => Promise<Completion>;\n};\n\ntype InputResourceTemplate<\n Arguments extends ResourceTemplateArgument[] = ResourceTemplateArgument[],\n> = {\n uriTemplate: string;\n name: string;\n description?: string;\n mimeType?: string;\n arguments: Arguments;\n};\n\ntype Resource = {\n uri: string;\n name: string;\n description?: string;\n mimeType?: string;\n load: () => Promise<ResourceResult | ResourceResult[]>;\n complete?: (name: string, value: string) => Promise<Completion>;\n};\n\ntype ArgumentValueCompleter = (value: string) => Promise<Completion>;\n\ntype InputPromptArgument = Readonly<{\n name: string;\n description?: string;\n required?: boolean;\n complete?: ArgumentValueCompleter;\n enum?: string[];\n}>;\n\ntype ArgumentsToObject<T extends InputPromptArgument[]> = {\n [K in T[number][\"name\"]]: Extract<\n T[number],\n { name: K }\n >[\"required\"] extends true\n ? string\n : string | undefined;\n};\n\ntype InputPrompt<\n Arguments extends InputPromptArgument[] = InputPromptArgument[],\n Args = ArgumentsToObject<Arguments>,\n> = {\n name: string;\n description?: string;\n arguments?: InputPromptArgument[];\n load: (args: Args) => Promise<string>;\n};\n\ntype PromptArgument = Readonly<{\n name: string;\n description?: string;\n required?: boolean;\n complete?: ArgumentValueCompleter;\n enum?: string[];\n}>;\n\ntype Prompt<\n Arguments extends PromptArgument[] = PromptArgument[],\n Args = ArgumentsToObject<Arguments>,\n> = {\n arguments?: PromptArgument[];\n complete?: (name: string, value: string) => Promise<Completion>;\n description?: string;\n load: (args: Args) => Promise<string>;\n name: string;\n};\n\ntype ServerOptions = {\n name: string;\n version: `${number}.${number}.${number}`;\n};\n\ntype LoggingLevel =\n | \"debug\"\n | \"info\"\n | \"notice\"\n | \"warning\"\n | \"error\"\n | \"critical\"\n | \"alert\"\n | \"emergency\";\n\nconst FastMCPSessionEventEmitterBase: {\n new (): StrictEventEmitter<EventEmitter, FastMCPSessionEvents>;\n} = EventEmitter;\n\nclass FastMCPSessionEventEmitter extends FastMCPSessionEventEmitterBase {}\n\nexport class FastMCPSession extends FastMCPSessionEventEmitter {\n #capabilities: ServerCapabilities = {};\n #clientCapabilities?: ClientCapabilities;\n #loggingLevel: LoggingLevel = \"info\";\n #prompts: Prompt[] = [];\n #resources: Resource[] = [];\n #resourceTemplates: ResourceTemplate[] = [];\n #roots: Root[] = [];\n #server: Server;\n\n constructor({\n name,\n version,\n tools,\n resources,\n resourcesTemplates,\n prompts,\n }: {\n name: string;\n version: string;\n tools: Tool[];\n resources: Resource[];\n resourcesTemplates: InputResourceTemplate[];\n prompts: Prompt[];\n }) {\n super();\n\n if (tools.length) {\n this.#capabilities.tools = {};\n }\n\n if (resources.length) {\n this.#capabilities.resources = {};\n }\n\n if (prompts.length) {\n for (const prompt of prompts) {\n this.addPrompt(prompt);\n }\n\n this.#capabilities.prompts = {};\n }\n\n this.#capabilities.logging = {};\n\n this.#server = new Server(\n { name: name, version: version },\n { capabilities: this.#capabilities },\n );\n\n this.setupErrorHandling();\n this.setupLoggingHandlers();\n this.setupRootsHandlers();\n this.setupCompleteHandlers();\n\n if (tools.length) {\n this.setupToolHandlers(tools);\n }\n\n if (resources.length) {\n for (const resource of resources) {\n this.addResource(resource);\n }\n\n this.setupResourceHandlers(resources);\n }\n\n if (resourcesTemplates.length) {\n for (const resourceTemplate of resourcesTemplates) {\n this.addResourceTemplate(resourceTemplate);\n }\n\n this.setupResourceTemplateHandlers(resourcesTemplates);\n }\n\n if (prompts.length) {\n this.setupPromptHandlers(prompts);\n }\n }\n\n private addResource(inputResource: Resource) {\n this.#resources.push(inputResource);\n }\n\n private addResourceTemplate(inputResourceTemplate: InputResourceTemplate) {\n const completers: Record<string, ArgumentValueCompleter> = {};\n\n for (const argument of inputResourceTemplate.arguments ?? []) {\n if (argument.complete) {\n completers[argument.name] = argument.complete;\n }\n }\n\n const resourceTemplate = {\n ...inputResourceTemplate,\n complete: async (name: string, value: string) => {\n if (completers[name]) {\n return await completers[name](value);\n }\n\n return {\n values: [],\n };\n },\n };\n\n this.#resourceTemplates.push(resourceTemplate);\n }\n\n private addPrompt(inputPrompt: InputPrompt) {\n const completers: Record<string, ArgumentValueCompleter> = {};\n const enums: Record<string, string[]> = {};\n\n for (const argument of inputPrompt.arguments ?? []) {\n if (argument.complete) {\n completers[argument.name] = argument.complete;\n }\n\n if (argument.enum) {\n enums[argument.name] = argument.enum;\n }\n }\n\n const prompt = {\n ...inputPrompt,\n complete: async (name: string, value: string) => {\n if (completers[name]) {\n return await completers[name](value);\n }\n\n if (enums[name]) {\n const fuse = new Fuse(enums[name], {\n keys: [\"value\"],\n });\n\n const result = fuse.search(value);\n\n return {\n values: result.map((item) => item.item),\n total: result.length,\n };\n }\n\n return {\n values: [],\n };\n },\n };\n\n this.#prompts.push(prompt);\n }\n\n public get clientCapabilities(): ClientCapabilities | null {\n return this.#clientCapabilities ?? null;\n }\n\n public get server(): Server {\n return this.#server;\n }\n\n #pingInterval: ReturnType<typeof setInterval> | null = null;\n\n public async connect(transport: Transport) {\n if (this.#server.transport) {\n throw new UnexpectedStateError(\"Server is already connected\");\n }\n\n await this.#server.connect(transport);\n\n let attempt = 0;\n\n while (attempt++ < 10) {\n const capabilities = await this.#server.getClientCapabilities();\n\n if (capabilities) {\n this.#clientCapabilities = capabilities;\n\n break;\n }\n\n await delay(100);\n }\n\n if (!this.#clientCapabilities) {\n throw new UnexpectedStateError(\"Server did not connect\");\n }\n\n if (this.#clientCapabilities?.roots) {\n const roots = await this.#server.listRoots();\n\n this.#roots = roots.roots;\n }\n\n this.#pingInterval = setInterval(async () => {\n try {\n await this.#server.ping();\n } catch (error) {\n this.emit(\"error\", {\n error: error as Error,\n });\n }\n }, 1000);\n }\n\n public get roots(): Root[] {\n return this.#roots;\n }\n\n public async close() {\n if (this.#pingInterval) {\n clearInterval(this.#pingInterval);\n }\n\n await this.#server.close();\n }\n\n private setupErrorHandling() {\n this.#server.onerror = (error) => {\n console.error(\"[MCP Error]\", error);\n };\n }\n\n public get loggingLevel(): LoggingLevel {\n return this.#loggingLevel;\n }\n\n private setupCompleteHandlers() {\n this.#server.setRequestHandler(CompleteRequestSchema, async (request) => {\n if (request.params.ref.type === \"ref/prompt\") {\n const prompt = this.#prompts.find(\n (prompt) => prompt.name === request.params.ref.name,\n );\n\n if (!prompt) {\n throw new UnexpectedStateError(\"Unknown prompt\", {\n request,\n });\n }\n\n if (!prompt.complete) {\n throw new UnexpectedStateError(\"Prompt does not support completion\", {\n request,\n });\n }\n\n const completion = CompletionZodSchema.parse(\n await prompt.complete(\n request.params.argument.name,\n request.params.argument.value,\n ),\n );\n\n return {\n completion,\n };\n }\n\n if (request.params.ref.type === \"ref/resource\") {\n const resource = this.#resourceTemplates.find(\n (resource) => resource.uriTemplate === request.params.ref.uri,\n );\n\n if (!resource) {\n throw new UnexpectedStateError(\"Unknown resource\", {\n request,\n });\n }\n\n if (!(\"uriTemplate\" in resource)) {\n throw new UnexpectedStateError(\"Unexpected resource\");\n }\n\n if (!resource.complete) {\n throw new UnexpectedStateError(\n \"Resource does not support completion\",\n {\n request,\n },\n );\n }\n\n const completion = CompletionZodSchema.parse(\n await resource.complete(\n request.params.argument.name,\n request.params.argument.value,\n ),\n );\n\n return {\n completion,\n };\n }\n\n throw new UnexpectedStateError(\"Unexpected completion request\", {\n request,\n });\n });\n }\n\n private setupRootsHandlers() {\n this.#server.setNotificationHandler(\n RootsListChangedNotificationSchema,\n () => {\n this.#server.listRoots().then((roots) => {\n this.#roots = roots.roots;\n\n this.emit(\"rootsChanged\", {\n roots: roots.roots,\n });\n });\n },\n );\n }\n\n private setupLoggingHandlers() {\n this.#server.setRequestHandler(SetLevelRequestSchema, (request) => {\n this.#loggingLevel = request.params.level;\n\n return {};\n });\n }\n\n private setupToolHandlers(tools: Tool[]) {\n this.#server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: tools.map((tool) => {\n return {\n name: tool.name,\n description: tool.description,\n inputSchema: tool.parameters\n ? zodToJsonSchema(tool.parameters)\n : undefined,\n };\n }),\n };\n });\n\n this.#server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const tool = tools.find((tool) => tool.name === request.params.name);\n\n if (!tool) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown tool: ${request.params.name}`,\n );\n }\n\n let args: any = undefined;\n\n if (tool.parameters) {\n const parsed = tool.parameters.safeParse(request.params.arguments);\n\n if (!parsed.success) {\n throw new McpError(\n ErrorCode.InvalidRequest,\n `Invalid ${request.params.name} arguments`,\n );\n }\n\n args = parsed.data;\n }\n\n const progressToken = request.params?._meta?.progressToken;\n\n let result: ContentResult;\n\n try {\n const reportProgress = async (progress: Progress) => {\n await this.#server.notification({\n method: \"notifications/progress\",\n params: {\n ...progress,\n progressToken,\n },\n });\n };\n\n const log = {\n debug: (message: string, context?: SerializableValue) => {\n this.#server.sendLoggingMessage({\n level: \"debug\",\n data: {\n message,\n context,\n },\n });\n },\n error: (message: string, context?: SerializableValue) => {\n this.#server.sendLoggingMessage({\n level: \"error\",\n data: {\n message,\n context,\n },\n });\n },\n info: (message: string, context?: SerializableValue) => {\n this.#server.sendLoggingMessage({\n level: \"info\",\n data: {\n message,\n context,\n },\n });\n },\n warn: (message: string, context?: SerializableValue) => {\n this.#server.sendLoggingMessage({\n level: \"warning\",\n data: {\n message,\n context,\n },\n });\n },\n };\n\n const maybeStringResult = await tool.execute(args, {\n reportProgress,\n log,\n });\n\n if (typeof maybeStringResult === \"string\") {\n result = ContentResultZodSchema.parse({\n content: [{ type: \"text\", text: maybeStringResult }],\n });\n } else if (\"type\" in maybeStringResult) {\n result = ContentResultZodSchema.parse({\n content: [maybeStringResult],\n });\n } else {\n result = ContentResultZodSchema.parse(maybeStringResult);\n }\n } catch (error) {\n if (error instanceof UserError) {\n return {\n content: [{ type: \"text\", text: error.message }],\n isError: true,\n };\n }\n\n return {\n content: [{ type: \"text\", text: `Error: ${error}` }],\n isError: true,\n };\n }\n\n return result;\n });\n }\n\n private setupResourceHandlers(resources: Resource[]) {\n this.#server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return {\n resources: resources.map((resource) => {\n return {\n uri: resource.uri,\n name: resource.name,\n mimeType: resource.mimeType,\n };\n }),\n };\n });\n\n this.#server.setRequestHandler(\n ReadResourceRequestSchema,\n async (request) => {\n if (\"uri\" in request.params) {\n const resource = resources.find(\n (resource) =>\n \"uri\" in resource && resource.uri === request.params.uri,\n );\n\n if (!resource) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown resource: ${request.params.uri}`,\n );\n }\n\n if (!(\"uri\" in resource)) {\n throw new UnexpectedStateError(\"Resource does not support reading\");\n }\n\n let maybeArrayResult: Awaited<ReturnType<Resource[\"load\"]>>;\n\n try {\n maybeArrayResult = await resource.load();\n } catch (error) {\n throw new McpError(\n ErrorCode.InternalError,\n `Error reading resource: ${error}`,\n {\n uri: resource.uri,\n },\n );\n }\n\n if (Array.isArray(maybeArrayResult)) {\n return {\n contents: maybeArrayResult.map((result) => ({\n uri: resource.uri,\n mimeType: resource.mimeType,\n name: resource.name,\n ...result,\n })),\n };\n } else {\n return {\n contents: [\n {\n uri: resource.uri,\n mimeType: resource.mimeType,\n name: resource.name,\n ...maybeArrayResult,\n },\n ],\n };\n }\n }\n\n throw new UnexpectedStateError(\"Unknown resource request\", {\n request,\n });\n },\n );\n }\n\n private setupResourceTemplateHandlers(resourceTemplates: ResourceTemplate[]) {\n this.#capabilities.resources = {};\n\n this.#server.setRequestHandler(\n ListResourceTemplatesRequestSchema,\n async () => {\n return {\n resourceTemplates: resourceTemplates.map((resourceTemplate) => {\n return {\n name: resourceTemplate.name,\n uriTemplate: resourceTemplate.uriTemplate,\n };\n }),\n };\n },\n );\n }\n\n private setupPromptHandlers(prompts: Prompt[]) {\n this.#server.setRequestHandler(ListPromptsRequestSchema, async () => {\n return {\n prompts: prompts.map((prompt) => {\n return {\n name: prompt.name,\n description: prompt.description,\n arguments: prompt.arguments,\n complete: prompt.complete,\n };\n }),\n };\n });\n\n this.#server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const prompt = prompts.find(\n (prompt) => prompt.name === request.params.name,\n );\n\n if (!prompt) {\n throw new McpError(\n ErrorCode.MethodNotFound,\n `Unknown prompt: ${request.params.name}`,\n );\n }\n\n const args = request.params.arguments;\n\n for (const arg of prompt.arguments ?? []) {\n if (arg.required && !(args && arg.name in args)) {\n throw new McpError(\n ErrorCode.InvalidRequest,\n `Missing required argument: ${arg.name}`,\n );\n }\n }\n\n let result: Awaited<ReturnType<Prompt[\"load\"]>>;\n\n try {\n result = await prompt.load(args as Record<string, string | undefined>);\n } catch (error) {\n throw new McpError(\n ErrorCode.InternalError,\n `Error loading prompt: ${error}`,\n );\n }\n\n return {\n description: prompt.description,\n messages: [\n {\n role: \"user\",\n content: { type: \"text\", text: result },\n },\n ],\n };\n });\n }\n}\n\nconst FastMCPEventEmitterBase: {\n new (): StrictEventEmitter<EventEmitter, FastMCPEvents>;\n} = EventEmitter;\n\nclass FastMCPEventEmitter extends FastMCPEventEmitterBase {}\n\nexport class FastMCP extends FastMCPEventEmitter {\n #options: ServerOptions;\n #prompts: InputPrompt[] = [];\n #resources: Resource[] = [];\n #resourcesTemplates: InputResourceTemplate[] = [];\n #sessions: FastMCPSession[] = [];\n #sseServer: SSEServer | null = null;\n #tools: Tool[] = [];\n\n constructor(public options: ServerOptions) {\n super();\n\n this.#options = options;\n }\n\n public get sessions(): FastMCPSession[] {\n return this.#sessions;\n }\n\n /**\n * Adds a tool to the server.\n */\n public addTool<Params extends ToolParameters>(tool: Tool<Params>) {\n this.#tools.push(tool as unknown as Tool);\n }\n\n /**\n * Adds a resource to the server.\n */\n public addResource(resource: Resource) {\n this.#resources.push(resource);\n }\n\n /**\n * Adds a resource template to the server.\n */\n public addResourceTemplate<\n const Args extends InputResourceTemplateArgument[],\n >(resource: InputResourceTemplate<Args>) {\n this.#resourcesTemplates.push(resource);\n }\n\n /**\n * Adds a prompt to the server.\n */\n public addPrompt<const Args extends InputPromptArgument[]>(\n prompt: InputPrompt<Args>,\n ) {\n this.#prompts.push(prompt);\n }\n\n /**\n * Starts the server.\n */\n public async start(\n options:\n | { transportType: \"stdio\" }\n | {\n transportType: \"sse\";\n sse: { endpoint: `/${string}`; port: number };\n } = {\n transportType: \"stdio\",\n },\n ) {\n if (options.transportType === \"stdio\") {\n const transport = new StdioServerTransport();\n\n const session = new FastMCPSession({\n name: this.#options.name,\n version: this.#options.version,\n tools: this.#tools,\n resources: this.#resources,\n resourcesTemplates: this.#resourcesTemplates,\n prompts: this.#prompts,\n });\n\n await session.connect(transport);\n\n this.#sessions.push(session);\n\n this.emit(\"connect\", {\n session,\n });\n\n console.error(`server is running on stdio`);\n } else if (options.transportType === \"sse\") {\n this.#sseServer = await startSSEServer<FastMCPSession>({\n endpoint: options.sse.endpoint as `/${string}`,\n port: options.sse.port,\n createServer: async () => {\n return new FastMCPSession({\n name: this.#options.name,\n version: this.#options.version,\n tools: this.#tools,\n resources: this.#resources,\n resourcesTemplates: this.#resourcesTemplates,\n prompts: this.#prompts,\n });\n },\n onClose: (session) => {\n this.emit(\"disconnect\", {\n session,\n });\n },\n onConnect: async (session) => {\n this.#sessions.push(session);\n\n this.emit(\"connect\", {\n session,\n });\n },\n });\n\n console.error(\n `server is running on SSE at http://localhost:${options.sse.port}${options.sse.endpoint}`,\n );\n } else {\n throw new Error(\"Invalid transport type\");\n }\n }\n\n /**\n * Stops the server.\n */\n public async stop() {\n if (this.#sseServer) {\n this.#sseServer.close();\n }\n }\n}\n"],"mappings":"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","names":["prompt","resource","tool"]}
|
package/jsr.json
CHANGED
package/package.json
CHANGED
package/src/FastMCP.test.ts
CHANGED
|
@@ -546,6 +546,57 @@ test("clients reads a resource", async () => {
|
|
|
546
546
|
});
|
|
547
547
|
});
|
|
548
548
|
|
|
549
|
+
test("clients reads a resource that returns multiple resources", async () => {
|
|
550
|
+
await runWithTestServer({
|
|
551
|
+
server: async () => {
|
|
552
|
+
const server = new FastMCP({
|
|
553
|
+
name: "Test",
|
|
554
|
+
version: "1.0.0",
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
server.addResource({
|
|
558
|
+
uri: "file:///logs/app.log",
|
|
559
|
+
name: "Application Logs",
|
|
560
|
+
mimeType: "text/plain",
|
|
561
|
+
async load() {
|
|
562
|
+
return [
|
|
563
|
+
{
|
|
564
|
+
text: "a",
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
text: "b",
|
|
568
|
+
},
|
|
569
|
+
];
|
|
570
|
+
},
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
return server;
|
|
574
|
+
},
|
|
575
|
+
run: async ({ client }) => {
|
|
576
|
+
expect(
|
|
577
|
+
await client.readResource({
|
|
578
|
+
uri: "file:///logs/app.log",
|
|
579
|
+
}),
|
|
580
|
+
).toEqual({
|
|
581
|
+
contents: [
|
|
582
|
+
{
|
|
583
|
+
uri: "file:///logs/app.log",
|
|
584
|
+
name: "Application Logs",
|
|
585
|
+
text: "a",
|
|
586
|
+
mimeType: "text/plain",
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
uri: "file:///logs/app.log",
|
|
590
|
+
name: "Application Logs",
|
|
591
|
+
text: "b",
|
|
592
|
+
mimeType: "text/plain",
|
|
593
|
+
},
|
|
594
|
+
],
|
|
595
|
+
});
|
|
596
|
+
},
|
|
597
|
+
});
|
|
598
|
+
});
|
|
599
|
+
|
|
549
600
|
test("adds prompts", async () => {
|
|
550
601
|
await runWithTestServer({
|
|
551
602
|
server: async () => {
|
|
@@ -900,7 +951,7 @@ test("session sends pings to the client", async () => {
|
|
|
900
951
|
});
|
|
901
952
|
});
|
|
902
953
|
|
|
903
|
-
test("prompt
|
|
954
|
+
test("completes prompt arguments", async () => {
|
|
904
955
|
await runWithTestServer({
|
|
905
956
|
server: async () => {
|
|
906
957
|
const server = new FastMCP({
|
|
@@ -1004,3 +1055,93 @@ test("adds automatic prompt argument completion when enum is provided", async ()
|
|
|
1004
1055
|
},
|
|
1005
1056
|
});
|
|
1006
1057
|
});
|
|
1058
|
+
|
|
1059
|
+
test("completes template resource arguments", async () => {
|
|
1060
|
+
await runWithTestServer({
|
|
1061
|
+
server: async () => {
|
|
1062
|
+
const server = new FastMCP({
|
|
1063
|
+
name: "Test",
|
|
1064
|
+
version: "1.0.0",
|
|
1065
|
+
});
|
|
1066
|
+
|
|
1067
|
+
server.addResourceTemplate({
|
|
1068
|
+
uriTemplate: "issue:///{issueId}",
|
|
1069
|
+
name: "Issue",
|
|
1070
|
+
mimeType: "text/plain",
|
|
1071
|
+
arguments: [
|
|
1072
|
+
{
|
|
1073
|
+
name: "issueId",
|
|
1074
|
+
description: "ID of the issue",
|
|
1075
|
+
complete: async (value) => {
|
|
1076
|
+
if (value === "123") {
|
|
1077
|
+
return {
|
|
1078
|
+
values: ["123456"],
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
return {
|
|
1083
|
+
values: [],
|
|
1084
|
+
};
|
|
1085
|
+
},
|
|
1086
|
+
},
|
|
1087
|
+
],
|
|
1088
|
+
});
|
|
1089
|
+
|
|
1090
|
+
return server;
|
|
1091
|
+
},
|
|
1092
|
+
run: async ({ client }) => {
|
|
1093
|
+
const response = await client.complete({
|
|
1094
|
+
ref: {
|
|
1095
|
+
type: "ref/resource",
|
|
1096
|
+
uri: "issue:///{issueId}",
|
|
1097
|
+
},
|
|
1098
|
+
argument: {
|
|
1099
|
+
name: "issueId",
|
|
1100
|
+
value: "123",
|
|
1101
|
+
},
|
|
1102
|
+
});
|
|
1103
|
+
|
|
1104
|
+
expect(response).toEqual({
|
|
1105
|
+
completion: {
|
|
1106
|
+
values: ["123456"],
|
|
1107
|
+
},
|
|
1108
|
+
});
|
|
1109
|
+
},
|
|
1110
|
+
});
|
|
1111
|
+
});
|
|
1112
|
+
|
|
1113
|
+
test("lists resource templates", async () => {
|
|
1114
|
+
await runWithTestServer({
|
|
1115
|
+
server: async () => {
|
|
1116
|
+
const server = new FastMCP({
|
|
1117
|
+
name: "Test",
|
|
1118
|
+
version: "1.0.0",
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
server.addResourceTemplate({
|
|
1122
|
+
uriTemplate: "file:///logs/{name}.log",
|
|
1123
|
+
name: "Application Logs",
|
|
1124
|
+
mimeType: "text/plain",
|
|
1125
|
+
arguments: [
|
|
1126
|
+
{
|
|
1127
|
+
name: "name",
|
|
1128
|
+
description: "Name of the log",
|
|
1129
|
+
required: true,
|
|
1130
|
+
},
|
|
1131
|
+
],
|
|
1132
|
+
});
|
|
1133
|
+
|
|
1134
|
+
return server;
|
|
1135
|
+
},
|
|
1136
|
+
run: async ({ client }) => {
|
|
1137
|
+
expect(await client.listResourceTemplates()).toEqual({
|
|
1138
|
+
resourceTemplates: [
|
|
1139
|
+
{
|
|
1140
|
+
name: "Application Logs",
|
|
1141
|
+
uriTemplate: "file:///logs/{name}.log",
|
|
1142
|
+
},
|
|
1143
|
+
],
|
|
1144
|
+
});
|
|
1145
|
+
},
|
|
1146
|
+
});
|
|
1147
|
+
});
|
package/src/FastMCP.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
GetPromptRequestSchema,
|
|
9
9
|
ListPromptsRequestSchema,
|
|
10
10
|
ListResourcesRequestSchema,
|
|
11
|
+
ListResourceTemplatesRequestSchema,
|
|
11
12
|
ListToolsRequestSchema,
|
|
12
13
|
McpError,
|
|
13
14
|
ReadResourceRequestSchema,
|
|
@@ -222,12 +223,54 @@ type Tool<Params extends ToolParameters = ToolParameters> = {
|
|
|
222
223
|
) => Promise<string | ContentResult | TextContent | ImageContent>;
|
|
223
224
|
};
|
|
224
225
|
|
|
226
|
+
type ResourceResult =
|
|
227
|
+
| {
|
|
228
|
+
text: string;
|
|
229
|
+
}
|
|
230
|
+
| {
|
|
231
|
+
blob: string;
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
type InputResourceTemplateArgument = Readonly<{
|
|
235
|
+
name: string;
|
|
236
|
+
description?: string;
|
|
237
|
+
complete?: ArgumentValueCompleter;
|
|
238
|
+
}>;
|
|
239
|
+
|
|
240
|
+
type ResourceTemplateArgument = Readonly<{
|
|
241
|
+
name: string;
|
|
242
|
+
description?: string;
|
|
243
|
+
complete?: ArgumentValueCompleter;
|
|
244
|
+
}>;
|
|
245
|
+
|
|
246
|
+
type ResourceTemplate<
|
|
247
|
+
Arguments extends ResourceTemplateArgument[] = ResourceTemplateArgument[],
|
|
248
|
+
> = {
|
|
249
|
+
uriTemplate: string;
|
|
250
|
+
name: string;
|
|
251
|
+
description?: string;
|
|
252
|
+
mimeType?: string;
|
|
253
|
+
arguments: Arguments;
|
|
254
|
+
complete?: (name: string, value: string) => Promise<Completion>;
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
type InputResourceTemplate<
|
|
258
|
+
Arguments extends ResourceTemplateArgument[] = ResourceTemplateArgument[],
|
|
259
|
+
> = {
|
|
260
|
+
uriTemplate: string;
|
|
261
|
+
name: string;
|
|
262
|
+
description?: string;
|
|
263
|
+
mimeType?: string;
|
|
264
|
+
arguments: Arguments;
|
|
265
|
+
};
|
|
266
|
+
|
|
225
267
|
type Resource = {
|
|
226
268
|
uri: string;
|
|
227
269
|
name: string;
|
|
228
270
|
description?: string;
|
|
229
271
|
mimeType?: string;
|
|
230
|
-
load: () => Promise<
|
|
272
|
+
load: () => Promise<ResourceResult | ResourceResult[]>;
|
|
273
|
+
complete?: (name: string, value: string) => Promise<Completion>;
|
|
231
274
|
};
|
|
232
275
|
|
|
233
276
|
type ArgumentValueCompleter = (value: string) => Promise<Completion>;
|
|
@@ -301,23 +344,27 @@ class FastMCPSessionEventEmitter extends FastMCPSessionEventEmitterBase {}
|
|
|
301
344
|
|
|
302
345
|
export class FastMCPSession extends FastMCPSessionEventEmitter {
|
|
303
346
|
#capabilities: ServerCapabilities = {};
|
|
304
|
-
#loggingLevel: LoggingLevel = "info";
|
|
305
|
-
#server: Server;
|
|
306
347
|
#clientCapabilities?: ClientCapabilities;
|
|
307
|
-
#
|
|
348
|
+
#loggingLevel: LoggingLevel = "info";
|
|
308
349
|
#prompts: Prompt[] = [];
|
|
350
|
+
#resources: Resource[] = [];
|
|
351
|
+
#resourceTemplates: ResourceTemplate[] = [];
|
|
352
|
+
#roots: Root[] = [];
|
|
353
|
+
#server: Server;
|
|
309
354
|
|
|
310
355
|
constructor({
|
|
311
356
|
name,
|
|
312
357
|
version,
|
|
313
358
|
tools,
|
|
314
359
|
resources,
|
|
360
|
+
resourcesTemplates,
|
|
315
361
|
prompts,
|
|
316
362
|
}: {
|
|
317
363
|
name: string;
|
|
318
364
|
version: string;
|
|
319
365
|
tools: Tool[];
|
|
320
366
|
resources: Resource[];
|
|
367
|
+
resourcesTemplates: InputResourceTemplate[];
|
|
321
368
|
prompts: Prompt[];
|
|
322
369
|
}) {
|
|
323
370
|
super();
|
|
@@ -355,14 +402,55 @@ export class FastMCPSession extends FastMCPSessionEventEmitter {
|
|
|
355
402
|
}
|
|
356
403
|
|
|
357
404
|
if (resources.length) {
|
|
405
|
+
for (const resource of resources) {
|
|
406
|
+
this.addResource(resource);
|
|
407
|
+
}
|
|
408
|
+
|
|
358
409
|
this.setupResourceHandlers(resources);
|
|
359
410
|
}
|
|
360
411
|
|
|
412
|
+
if (resourcesTemplates.length) {
|
|
413
|
+
for (const resourceTemplate of resourcesTemplates) {
|
|
414
|
+
this.addResourceTemplate(resourceTemplate);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
this.setupResourceTemplateHandlers(resourcesTemplates);
|
|
418
|
+
}
|
|
419
|
+
|
|
361
420
|
if (prompts.length) {
|
|
362
421
|
this.setupPromptHandlers(prompts);
|
|
363
422
|
}
|
|
364
423
|
}
|
|
365
424
|
|
|
425
|
+
private addResource(inputResource: Resource) {
|
|
426
|
+
this.#resources.push(inputResource);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private addResourceTemplate(inputResourceTemplate: InputResourceTemplate) {
|
|
430
|
+
const completers: Record<string, ArgumentValueCompleter> = {};
|
|
431
|
+
|
|
432
|
+
for (const argument of inputResourceTemplate.arguments ?? []) {
|
|
433
|
+
if (argument.complete) {
|
|
434
|
+
completers[argument.name] = argument.complete;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const resourceTemplate = {
|
|
439
|
+
...inputResourceTemplate,
|
|
440
|
+
complete: async (name: string, value: string) => {
|
|
441
|
+
if (completers[name]) {
|
|
442
|
+
return await completers[name](value);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
return {
|
|
446
|
+
values: [],
|
|
447
|
+
};
|
|
448
|
+
},
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
this.#resourceTemplates.push(resourceTemplate);
|
|
452
|
+
}
|
|
453
|
+
|
|
366
454
|
private addPrompt(inputPrompt: InputPrompt) {
|
|
367
455
|
const completers: Record<string, ArgumentValueCompleter> = {};
|
|
368
456
|
const enums: Record<string, string[]> = {};
|
|
@@ -511,6 +599,42 @@ export class FastMCPSession extends FastMCPSessionEventEmitter {
|
|
|
511
599
|
};
|
|
512
600
|
}
|
|
513
601
|
|
|
602
|
+
if (request.params.ref.type === "ref/resource") {
|
|
603
|
+
const resource = this.#resourceTemplates.find(
|
|
604
|
+
(resource) => resource.uriTemplate === request.params.ref.uri,
|
|
605
|
+
);
|
|
606
|
+
|
|
607
|
+
if (!resource) {
|
|
608
|
+
throw new UnexpectedStateError("Unknown resource", {
|
|
609
|
+
request,
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
if (!("uriTemplate" in resource)) {
|
|
614
|
+
throw new UnexpectedStateError("Unexpected resource");
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
if (!resource.complete) {
|
|
618
|
+
throw new UnexpectedStateError(
|
|
619
|
+
"Resource does not support completion",
|
|
620
|
+
{
|
|
621
|
+
request,
|
|
622
|
+
},
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
const completion = CompletionZodSchema.parse(
|
|
627
|
+
await resource.complete(
|
|
628
|
+
request.params.argument.name,
|
|
629
|
+
request.params.argument.value,
|
|
630
|
+
),
|
|
631
|
+
);
|
|
632
|
+
|
|
633
|
+
return {
|
|
634
|
+
completion,
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
|
|
514
638
|
throw new UnexpectedStateError("Unexpected completion request", {
|
|
515
639
|
request,
|
|
516
640
|
});
|
|
@@ -684,40 +808,80 @@ export class FastMCPSession extends FastMCPSessionEventEmitter {
|
|
|
684
808
|
this.#server.setRequestHandler(
|
|
685
809
|
ReadResourceRequestSchema,
|
|
686
810
|
async (request) => {
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
if (!resource) {
|
|
692
|
-
throw new McpError(
|
|
693
|
-
ErrorCode.MethodNotFound,
|
|
694
|
-
`Unknown resource: ${request.params.uri}`,
|
|
811
|
+
if ("uri" in request.params) {
|
|
812
|
+
const resource = resources.find(
|
|
813
|
+
(resource) =>
|
|
814
|
+
"uri" in resource && resource.uri === request.params.uri,
|
|
695
815
|
);
|
|
816
|
+
|
|
817
|
+
if (!resource) {
|
|
818
|
+
throw new McpError(
|
|
819
|
+
ErrorCode.MethodNotFound,
|
|
820
|
+
`Unknown resource: ${request.params.uri}`,
|
|
821
|
+
);
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
if (!("uri" in resource)) {
|
|
825
|
+
throw new UnexpectedStateError("Resource does not support reading");
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
let maybeArrayResult: Awaited<ReturnType<Resource["load"]>>;
|
|
829
|
+
|
|
830
|
+
try {
|
|
831
|
+
maybeArrayResult = await resource.load();
|
|
832
|
+
} catch (error) {
|
|
833
|
+
throw new McpError(
|
|
834
|
+
ErrorCode.InternalError,
|
|
835
|
+
`Error reading resource: ${error}`,
|
|
836
|
+
{
|
|
837
|
+
uri: resource.uri,
|
|
838
|
+
},
|
|
839
|
+
);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
if (Array.isArray(maybeArrayResult)) {
|
|
843
|
+
return {
|
|
844
|
+
contents: maybeArrayResult.map((result) => ({
|
|
845
|
+
uri: resource.uri,
|
|
846
|
+
mimeType: resource.mimeType,
|
|
847
|
+
name: resource.name,
|
|
848
|
+
...result,
|
|
849
|
+
})),
|
|
850
|
+
};
|
|
851
|
+
} else {
|
|
852
|
+
return {
|
|
853
|
+
contents: [
|
|
854
|
+
{
|
|
855
|
+
uri: resource.uri,
|
|
856
|
+
mimeType: resource.mimeType,
|
|
857
|
+
name: resource.name,
|
|
858
|
+
...maybeArrayResult,
|
|
859
|
+
},
|
|
860
|
+
],
|
|
861
|
+
};
|
|
862
|
+
}
|
|
696
863
|
}
|
|
697
864
|
|
|
698
|
-
|
|
865
|
+
throw new UnexpectedStateError("Unknown resource request", {
|
|
866
|
+
request,
|
|
867
|
+
});
|
|
868
|
+
},
|
|
869
|
+
);
|
|
870
|
+
}
|
|
699
871
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
} catch (error) {
|
|
703
|
-
throw new McpError(
|
|
704
|
-
ErrorCode.InternalError,
|
|
705
|
-
`Error reading resource: ${error}`,
|
|
706
|
-
{
|
|
707
|
-
uri: resource.uri,
|
|
708
|
-
},
|
|
709
|
-
);
|
|
710
|
-
}
|
|
872
|
+
private setupResourceTemplateHandlers(resourceTemplates: ResourceTemplate[]) {
|
|
873
|
+
this.#capabilities.resources = {};
|
|
711
874
|
|
|
875
|
+
this.#server.setRequestHandler(
|
|
876
|
+
ListResourceTemplatesRequestSchema,
|
|
877
|
+
async () => {
|
|
712
878
|
return {
|
|
713
|
-
|
|
714
|
-
{
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
},
|
|
720
|
-
],
|
|
879
|
+
resourceTemplates: resourceTemplates.map((resourceTemplate) => {
|
|
880
|
+
return {
|
|
881
|
+
name: resourceTemplate.name,
|
|
882
|
+
uriTemplate: resourceTemplate.uriTemplate,
|
|
883
|
+
};
|
|
884
|
+
}),
|
|
721
885
|
};
|
|
722
886
|
},
|
|
723
887
|
);
|
|
@@ -794,6 +958,7 @@ export class FastMCP extends FastMCPEventEmitter {
|
|
|
794
958
|
#options: ServerOptions;
|
|
795
959
|
#prompts: InputPrompt[] = [];
|
|
796
960
|
#resources: Resource[] = [];
|
|
961
|
+
#resourcesTemplates: InputResourceTemplate[] = [];
|
|
797
962
|
#sessions: FastMCPSession[] = [];
|
|
798
963
|
#sseServer: SSEServer | null = null;
|
|
799
964
|
#tools: Tool[] = [];
|
|
@@ -822,6 +987,15 @@ export class FastMCP extends FastMCPEventEmitter {
|
|
|
822
987
|
this.#resources.push(resource);
|
|
823
988
|
}
|
|
824
989
|
|
|
990
|
+
/**
|
|
991
|
+
* Adds a resource template to the server.
|
|
992
|
+
*/
|
|
993
|
+
public addResourceTemplate<
|
|
994
|
+
const Args extends InputResourceTemplateArgument[],
|
|
995
|
+
>(resource: InputResourceTemplate<Args>) {
|
|
996
|
+
this.#resourcesTemplates.push(resource);
|
|
997
|
+
}
|
|
998
|
+
|
|
825
999
|
/**
|
|
826
1000
|
* Adds a prompt to the server.
|
|
827
1001
|
*/
|
|
@@ -852,6 +1026,7 @@ export class FastMCP extends FastMCPEventEmitter {
|
|
|
852
1026
|
version: this.#options.version,
|
|
853
1027
|
tools: this.#tools,
|
|
854
1028
|
resources: this.#resources,
|
|
1029
|
+
resourcesTemplates: this.#resourcesTemplates,
|
|
855
1030
|
prompts: this.#prompts,
|
|
856
1031
|
});
|
|
857
1032
|
|
|
@@ -874,6 +1049,7 @@ export class FastMCP extends FastMCPEventEmitter {
|
|
|
874
1049
|
version: this.#options.version,
|
|
875
1050
|
tools: this.#tools,
|
|
876
1051
|
resources: this.#resources,
|
|
1052
|
+
resourcesTemplates: this.#resourcesTemplates,
|
|
877
1053
|
prompts: this.#prompts,
|
|
878
1054
|
});
|
|
879
1055
|
},
|