fastmcp 1.22.4 → 1.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,5 @@
1
- import { FastMCP, FastMCPSession, UserError, imageContent } from "./FastMCP.js";
2
- import { z } from "zod";
3
- import { test, expect, vi } from "vitest";
4
1
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
5
2
  import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
6
- import { getRandomPort } from "get-port-please";
7
- import { setTimeout as delay } from "timers/promises";
8
3
  import {
9
4
  CreateMessageRequestSchema,
10
5
  ErrorCode,
@@ -14,14 +9,19 @@ import {
14
9
  PingRequestSchema,
15
10
  Root,
16
11
  } from "@modelcontextprotocol/sdk/types.js";
17
- import { createEventSource, EventSourceClient } from 'eventsource-client';
12
+ import { createEventSource, EventSourceClient } from "eventsource-client";
13
+ import { getRandomPort } from "get-port-please";
14
+ import { setTimeout as delay } from "timers/promises";
15
+ import { expect, test, vi } from "vitest";
16
+ import { z } from "zod";
17
+
18
+ import { FastMCP, FastMCPSession, imageContent, UserError } from "./FastMCP.js";
18
19
 
19
20
  const runWithTestServer = async ({
20
- run,
21
21
  client: createClient,
22
+ run,
22
23
  server: createServer,
23
24
  }: {
24
- server?: () => Promise<FastMCP>;
25
25
  client?: () => Promise<Client>;
26
26
  run: ({
27
27
  client,
@@ -31,6 +31,7 @@ const runWithTestServer = async ({
31
31
  server: FastMCP;
32
32
  session: FastMCPSession;
33
33
  }) => Promise<void>;
34
+ server?: () => Promise<FastMCP>;
34
35
  }) => {
35
36
  const port = await getRandomPort();
36
37
 
@@ -42,11 +43,11 @@ const runWithTestServer = async ({
42
43
  });
43
44
 
44
45
  await server.start({
45
- transportType: "sse",
46
46
  sse: {
47
47
  endpoint: "/sse",
48
48
  port,
49
49
  },
50
+ transportType: "sse",
50
51
  });
51
52
 
52
53
  try {
@@ -68,7 +69,6 @@ const runWithTestServer = async ({
68
69
 
69
70
  const session = await new Promise<FastMCPSession>((resolve) => {
70
71
  server.on("connect", (event) => {
71
-
72
72
  resolve(event.session);
73
73
  });
74
74
 
@@ -85,51 +85,26 @@ const runWithTestServer = async ({
85
85
 
86
86
  test("adds tools", async () => {
87
87
  await runWithTestServer({
88
- server: async () => {
89
- const server = new FastMCP({
90
- name: "Test",
91
- version: "1.0.0",
92
- });
93
-
94
- server.addTool({
95
- name: "add",
96
- description: "Add two numbers",
97
- parameters: z.object({
98
- a: z.number(),
99
- b: z.number(),
100
- }),
101
- execute: async (args) => {
102
- return String(args.a + args.b);
103
- },
104
- });
105
-
106
- return server;
107
- },
108
88
  run: async ({ client }) => {
109
89
  expect(await client.listTools()).toEqual({
110
90
  tools: [
111
91
  {
112
- name: "add",
113
92
  description: "Add two numbers",
114
93
  inputSchema: {
115
- additionalProperties: false,
116
94
  $schema: "http://json-schema.org/draft-07/schema#",
117
- type: "object",
95
+ additionalProperties: false,
118
96
  properties: {
119
97
  a: { type: "number" },
120
98
  b: { type: "number" },
121
99
  },
122
100
  required: ["a", "b"],
101
+ type: "object",
123
102
  },
103
+ name: "add",
124
104
  },
125
105
  ],
126
106
  });
127
107
  },
128
- });
129
- });
130
-
131
- test("calls a tool", async () => {
132
- await runWithTestServer({
133
108
  server: async () => {
134
109
  const server = new FastMCP({
135
110
  name: "Test",
@@ -137,37 +112,37 @@ test("calls a tool", async () => {
137
112
  });
138
113
 
139
114
  server.addTool({
140
- name: "add",
141
115
  description: "Add two numbers",
116
+ execute: async (args) => {
117
+ return String(args.a + args.b);
118
+ },
119
+ name: "add",
142
120
  parameters: z.object({
143
121
  a: z.number(),
144
122
  b: z.number(),
145
123
  }),
146
- execute: async (args) => {
147
- return String(args.a + args.b);
148
- },
149
124
  });
150
125
 
151
126
  return server;
152
127
  },
128
+ });
129
+ });
130
+
131
+ test("calls a tool", async () => {
132
+ await runWithTestServer({
153
133
  run: async ({ client }) => {
154
134
  expect(
155
135
  await client.callTool({
156
- name: "add",
157
136
  arguments: {
158
137
  a: 1,
159
138
  b: 2,
160
139
  },
140
+ name: "add",
161
141
  }),
162
142
  ).toEqual({
163
- content: [{ type: "text", text: "3" }],
143
+ content: [{ text: "3", type: "text" }],
164
144
  });
165
145
  },
166
- });
167
- });
168
-
169
- test("returns a list", async () => {
170
- await runWithTestServer({
171
146
  server: async () => {
172
147
  const server = new FastMCP({
173
148
  name: "Test",
@@ -175,45 +150,40 @@ test("returns a list", async () => {
175
150
  });
176
151
 
177
152
  server.addTool({
178
- name: "add",
179
153
  description: "Add two numbers",
154
+ execute: async (args) => {
155
+ return String(args.a + args.b);
156
+ },
157
+ name: "add",
180
158
  parameters: z.object({
181
159
  a: z.number(),
182
160
  b: z.number(),
183
161
  }),
184
- execute: async () => {
185
- return {
186
- content: [
187
- { type: "text", text: "a" },
188
- { type: "text", text: "b" },
189
- ],
190
- };
191
- },
192
162
  });
193
163
 
194
164
  return server;
195
165
  },
166
+ });
167
+ });
168
+
169
+ test("returns a list", async () => {
170
+ await runWithTestServer({
196
171
  run: async ({ client }) => {
197
172
  expect(
198
173
  await client.callTool({
199
- name: "add",
200
174
  arguments: {
201
175
  a: 1,
202
176
  b: 2,
203
177
  },
178
+ name: "add",
204
179
  }),
205
180
  ).toEqual({
206
181
  content: [
207
- { type: "text", text: "a" },
208
- { type: "text", text: "b" },
182
+ { text: "a", type: "text" },
183
+ { text: "b", type: "text" },
209
184
  ],
210
185
  });
211
186
  },
212
- });
213
- });
214
-
215
- test("returns an image", async () => {
216
- await runWithTestServer({
217
187
  server: async () => {
218
188
  const server = new FastMCP({
219
189
  name: "Test",
@@ -221,48 +191,48 @@ test("returns an image", async () => {
221
191
  });
222
192
 
223
193
  server.addTool({
224
- name: "add",
225
194
  description: "Add two numbers",
195
+ execute: async () => {
196
+ return {
197
+ content: [
198
+ { text: "a", type: "text" },
199
+ { text: "b", type: "text" },
200
+ ],
201
+ };
202
+ },
203
+ name: "add",
226
204
  parameters: z.object({
227
205
  a: z.number(),
228
206
  b: z.number(),
229
207
  }),
230
- execute: async () => {
231
- return imageContent({
232
- buffer: Buffer.from(
233
- "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
234
- "base64",
235
- ),
236
- });
237
- },
238
208
  });
239
209
 
240
210
  return server;
241
211
  },
212
+ });
213
+ });
214
+
215
+ test("returns an image", async () => {
216
+ await runWithTestServer({
242
217
  run: async ({ client }) => {
243
218
  expect(
244
219
  await client.callTool({
245
- name: "add",
246
220
  arguments: {
247
221
  a: 1,
248
222
  b: 2,
249
223
  },
224
+ name: "add",
250
225
  }),
251
226
  ).toEqual({
252
227
  content: [
253
228
  {
254
- type: "image",
255
229
  data: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
256
230
  mimeType: "image/png",
231
+ type: "image",
257
232
  },
258
233
  ],
259
234
  });
260
235
  },
261
- });
262
- });
263
-
264
- test("handles UserError errors", async () => {
265
- await runWithTestServer({
266
236
  server: async () => {
267
237
  const server = new FastMCP({
268
238
  name: "Test",
@@ -270,54 +240,76 @@ test("handles UserError errors", async () => {
270
240
  });
271
241
 
272
242
  server.addTool({
273
- name: "add",
274
243
  description: "Add two numbers",
244
+ execute: async () => {
245
+ return imageContent({
246
+ buffer: Buffer.from(
247
+ "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=",
248
+ "base64",
249
+ ),
250
+ });
251
+ },
252
+ name: "add",
275
253
  parameters: z.object({
276
254
  a: z.number(),
277
255
  b: z.number(),
278
256
  }),
279
- execute: async () => {
280
- throw new UserError("Something went wrong");
281
- },
282
257
  });
283
258
 
284
259
  return server;
285
260
  },
261
+ });
262
+ });
263
+
264
+ test("handles UserError errors", async () => {
265
+ await runWithTestServer({
286
266
  run: async ({ client }) => {
287
267
  expect(
288
268
  await client.callTool({
289
- name: "add",
290
269
  arguments: {
291
270
  a: 1,
292
271
  b: 2,
293
272
  },
273
+ name: "add",
294
274
  }),
295
275
  ).toEqual({
296
- content: [{ type: "text", text: "Something went wrong" }],
276
+ content: [{ text: "Something went wrong", type: "text" }],
297
277
  isError: true,
298
278
  });
299
279
  },
300
- });
301
- });
302
-
303
- test("calling an unknown tool throws McpError with MethodNotFound code", async () => {
304
- await runWithTestServer({
305
280
  server: async () => {
306
281
  const server = new FastMCP({
307
282
  name: "Test",
308
283
  version: "1.0.0",
309
284
  });
310
285
 
286
+ server.addTool({
287
+ description: "Add two numbers",
288
+ execute: async () => {
289
+ throw new UserError("Something went wrong");
290
+ },
291
+ name: "add",
292
+ parameters: z.object({
293
+ a: z.number(),
294
+ b: z.number(),
295
+ }),
296
+ });
297
+
311
298
  return server;
312
299
  },
300
+ });
301
+ });
302
+
303
+ test("calling an unknown tool throws McpError with MethodNotFound code", async () => {
304
+ await runWithTestServer({
313
305
  run: async ({ client }) => {
314
306
  try {
315
307
  await client.callTool({
316
- name: "add",
317
308
  arguments: {
318
309
  a: 1,
319
310
  b: 2,
320
311
  },
312
+ name: "add",
321
313
  });
322
314
  } catch (error) {
323
315
  expect(error).toBeInstanceOf(McpError);
@@ -326,48 +318,29 @@ test("calling an unknown tool throws McpError with MethodNotFound code", async (
326
318
  expect(error.code).toBe(ErrorCode.MethodNotFound);
327
319
  }
328
320
  },
329
- });
330
- });
331
-
332
- test("tracks tool progress", async () => {
333
- await runWithTestServer({
334
321
  server: async () => {
335
322
  const server = new FastMCP({
336
323
  name: "Test",
337
324
  version: "1.0.0",
338
325
  });
339
326
 
340
- server.addTool({
341
- name: "add",
342
- description: "Add two numbers",
343
- parameters: z.object({
344
- a: z.number(),
345
- b: z.number(),
346
- }),
347
- execute: async (args, { reportProgress }) => {
348
- reportProgress({
349
- progress: 0,
350
- total: 10,
351
- });
352
-
353
- await delay(100);
354
-
355
- return String(args.a + args.b);
356
- },
357
- });
358
-
359
327
  return server;
360
328
  },
329
+ });
330
+ });
331
+
332
+ test("tracks tool progress", async () => {
333
+ await runWithTestServer({
361
334
  run: async ({ client }) => {
362
335
  const onProgress = vi.fn();
363
336
 
364
337
  await client.callTool(
365
338
  {
366
- name: "add",
367
339
  arguments: {
368
340
  a: 1,
369
341
  b: 2,
370
342
  },
343
+ name: "add",
371
344
  },
372
345
  undefined,
373
346
  {
@@ -381,6 +354,33 @@ test("tracks tool progress", async () => {
381
354
  total: 10,
382
355
  });
383
356
  },
357
+ server: async () => {
358
+ const server = new FastMCP({
359
+ name: "Test",
360
+ version: "1.0.0",
361
+ });
362
+
363
+ server.addTool({
364
+ description: "Add two numbers",
365
+ execute: async (args, { reportProgress }) => {
366
+ reportProgress({
367
+ progress: 0,
368
+ total: 10,
369
+ });
370
+
371
+ await delay(100);
372
+
373
+ return String(args.a + args.b);
374
+ },
375
+ name: "add",
376
+ parameters: z.object({
377
+ a: z.number(),
378
+ b: z.number(),
379
+ }),
380
+ });
381
+
382
+ return server;
383
+ },
384
384
  });
385
385
  });
386
386
 
@@ -400,33 +400,6 @@ test("sets logging levels", async () => {
400
400
 
401
401
  test("sends logging messages to the client", async () => {
402
402
  await runWithTestServer({
403
- server: async () => {
404
- const server = new FastMCP({
405
- name: "Test",
406
- version: "1.0.0",
407
- });
408
-
409
- server.addTool({
410
- name: "add",
411
- description: "Add two numbers",
412
- parameters: z.object({
413
- a: z.number(),
414
- b: z.number(),
415
- }),
416
- execute: async (args, { log }) => {
417
- log.debug("debug message", {
418
- foo: "bar",
419
- });
420
- log.error("error message");
421
- log.info("info message");
422
- log.warn("warn message");
423
-
424
- return String(args.a + args.b);
425
- },
426
- });
427
-
428
- return server;
429
- },
430
403
  run: async ({ client }) => {
431
404
  const onLog = vi.fn();
432
405
 
@@ -443,20 +416,20 @@ test("sends logging messages to the client", async () => {
443
416
  );
444
417
 
445
418
  await client.callTool({
446
- name: "add",
447
419
  arguments: {
448
420
  a: 1,
449
421
  b: 2,
450
422
  },
423
+ name: "add",
451
424
  });
452
425
 
453
426
  expect(onLog).toHaveBeenCalledTimes(4);
454
427
  expect(onLog).toHaveBeenNthCalledWith(1, {
455
- level: "debug",
456
- message: "debug message",
457
428
  context: {
458
429
  foo: "bar",
459
430
  },
431
+ level: "debug",
432
+ message: "debug message",
460
433
  });
461
434
  expect(onLog).toHaveBeenNthCalledWith(2, {
462
435
  level: "error",
@@ -471,46 +444,49 @@ test("sends logging messages to the client", async () => {
471
444
  message: "warn message",
472
445
  });
473
446
  },
447
+ server: async () => {
448
+ const server = new FastMCP({
449
+ name: "Test",
450
+ version: "1.0.0",
451
+ });
452
+
453
+ server.addTool({
454
+ description: "Add two numbers",
455
+ execute: async (args, { log }) => {
456
+ log.debug("debug message", {
457
+ foo: "bar",
458
+ });
459
+ log.error("error message");
460
+ log.info("info message");
461
+ log.warn("warn message");
462
+
463
+ return String(args.a + args.b);
464
+ },
465
+ name: "add",
466
+ parameters: z.object({
467
+ a: z.number(),
468
+ b: z.number(),
469
+ }),
470
+ });
471
+
472
+ return server;
473
+ },
474
474
  });
475
475
  });
476
476
 
477
477
  test("adds resources", async () => {
478
478
  await runWithTestServer({
479
- server: async () => {
480
- const server = new FastMCP({
481
- name: "Test",
482
- version: "1.0.0",
483
- });
484
-
485
- server.addResource({
486
- uri: "file:///logs/app.log",
487
- name: "Application Logs",
488
- mimeType: "text/plain",
489
- async load() {
490
- return {
491
- text: "Example log content",
492
- };
493
- },
494
- });
495
-
496
- return server;
497
- },
498
479
  run: async ({ client }) => {
499
480
  expect(await client.listResources()).toEqual({
500
481
  resources: [
501
482
  {
502
- uri: "file:///logs/app.log",
503
- name: "Application Logs",
504
483
  mimeType: "text/plain",
484
+ name: "Application Logs",
485
+ uri: "file:///logs/app.log",
505
486
  },
506
487
  ],
507
488
  });
508
489
  },
509
- });
510
- });
511
-
512
- test("clients reads a resource", async () => {
513
- await runWithTestServer({
514
490
  server: async () => {
515
491
  const server = new FastMCP({
516
492
  name: "Test",
@@ -518,18 +494,23 @@ test("clients reads a resource", async () => {
518
494
  });
519
495
 
520
496
  server.addResource({
521
- uri: "file:///logs/app.log",
522
- name: "Application Logs",
523
- mimeType: "text/plain",
524
497
  async load() {
525
498
  return {
526
499
  text: "Example log content",
527
500
  };
528
501
  },
502
+ mimeType: "text/plain",
503
+ name: "Application Logs",
504
+ uri: "file:///logs/app.log",
529
505
  });
530
506
 
531
507
  return server;
532
508
  },
509
+ });
510
+ });
511
+
512
+ test("clients reads a resource", async () => {
513
+ await runWithTestServer({
533
514
  run: async ({ client }) => {
534
515
  expect(
535
516
  await client.readResource({
@@ -538,19 +519,14 @@ test("clients reads a resource", async () => {
538
519
  ).toEqual({
539
520
  contents: [
540
521
  {
541
- uri: "file:///logs/app.log",
522
+ mimeType: "text/plain",
542
523
  name: "Application Logs",
543
524
  text: "Example log content",
544
- mimeType: "text/plain",
525
+ uri: "file:///logs/app.log",
545
526
  },
546
527
  ],
547
528
  });
548
529
  },
549
- });
550
- });
551
-
552
- test("clients reads a resource that returns multiple resources", async () => {
553
- await runWithTestServer({
554
530
  server: async () => {
555
531
  const server = new FastMCP({
556
532
  name: "Test",
@@ -558,23 +534,23 @@ test("clients reads a resource that returns multiple resources", async () => {
558
534
  });
559
535
 
560
536
  server.addResource({
561
- uri: "file:///logs/app.log",
562
- name: "Application Logs",
563
- mimeType: "text/plain",
564
537
  async load() {
565
- return [
566
- {
567
- text: "a",
568
- },
569
- {
570
- text: "b",
571
- },
572
- ];
538
+ return {
539
+ text: "Example log content",
540
+ };
573
541
  },
542
+ mimeType: "text/plain",
543
+ name: "Application Logs",
544
+ uri: "file:///logs/app.log",
574
545
  });
575
546
 
576
547
  return server;
577
548
  },
549
+ });
550
+ });
551
+
552
+ test("clients reads a resource that returns multiple resources", async () => {
553
+ await runWithTestServer({
578
554
  run: async ({ client }) => {
579
555
  expect(
580
556
  await client.readResource({
@@ -583,65 +559,66 @@ test("clients reads a resource that returns multiple resources", async () => {
583
559
  ).toEqual({
584
560
  contents: [
585
561
  {
586
- uri: "file:///logs/app.log",
562
+ mimeType: "text/plain",
587
563
  name: "Application Logs",
588
564
  text: "a",
589
- mimeType: "text/plain",
565
+ uri: "file:///logs/app.log",
590
566
  },
591
567
  {
592
- uri: "file:///logs/app.log",
568
+ mimeType: "text/plain",
593
569
  name: "Application Logs",
594
570
  text: "b",
595
- mimeType: "text/plain",
571
+ uri: "file:///logs/app.log",
596
572
  },
597
573
  ],
598
574
  });
599
575
  },
600
- });
601
- });
602
-
603
- test("adds prompts", async () => {
604
- await runWithTestServer({
605
576
  server: async () => {
606
577
  const server = new FastMCP({
607
578
  name: "Test",
608
579
  version: "1.0.0",
609
580
  });
610
581
 
611
- server.addPrompt({
612
- name: "git-commit",
613
- description: "Generate a Git commit message",
614
- arguments: [
615
- {
616
- name: "changes",
617
- description: "Git diff or description of changes",
618
- required: true,
619
- },
620
- ],
621
- load: async (args) => {
622
- return `Generate a concise but descriptive commit message for these changes:\n\n${args.changes}`;
582
+ server.addResource({
583
+ async load() {
584
+ return [
585
+ {
586
+ text: "a",
587
+ },
588
+ {
589
+ text: "b",
590
+ },
591
+ ];
623
592
  },
593
+ mimeType: "text/plain",
594
+ name: "Application Logs",
595
+ uri: "file:///logs/app.log",
624
596
  });
625
597
 
626
598
  return server;
627
599
  },
600
+ });
601
+ });
602
+
603
+ test("adds prompts", async () => {
604
+ await runWithTestServer({
628
605
  run: async ({ client }) => {
629
606
  expect(
630
607
  await client.getPrompt({
631
- name: "git-commit",
632
608
  arguments: {
633
609
  changes: "foo",
634
610
  },
611
+ name: "git-commit",
635
612
  }),
636
613
  ).toEqual({
637
614
  description: "Generate a Git commit message",
638
615
  messages: [
639
616
  {
640
- role: "user",
641
617
  content: {
642
- type: "text",
643
618
  text: "Generate a concise but descriptive commit message for these changes:\n\nfoo",
619
+ type: "text",
644
620
  },
621
+ role: "user",
645
622
  },
646
623
  ],
647
624
  });
@@ -649,18 +626,41 @@ test("adds prompts", async () => {
649
626
  expect(await client.listPrompts()).toEqual({
650
627
  prompts: [
651
628
  {
652
- name: "git-commit",
653
- description: "Generate a Git commit message",
654
629
  arguments: [
655
630
  {
656
- name: "changes",
657
631
  description: "Git diff or description of changes",
632
+ name: "changes",
658
633
  required: true,
659
634
  },
660
635
  ],
636
+ description: "Generate a Git commit message",
637
+ name: "git-commit",
638
+ },
639
+ ],
640
+ });
641
+ },
642
+ server: async () => {
643
+ const server = new FastMCP({
644
+ name: "Test",
645
+ version: "1.0.0",
646
+ });
647
+
648
+ server.addPrompt({
649
+ arguments: [
650
+ {
651
+ description: "Git diff or description of changes",
652
+ name: "changes",
653
+ required: true,
661
654
  },
662
655
  ],
656
+ description: "Generate a Git commit message",
657
+ load: async (args) => {
658
+ return `Generate a concise but descriptive commit message for these changes:\n\n${args.changes}`;
659
+ },
660
+ name: "git-commit",
663
661
  });
662
+
663
+ return server;
664
664
  },
665
665
  });
666
666
  });
@@ -680,11 +680,11 @@ test("uses events to notify server of client connect/disconnect", async () => {
680
680
  server.on("disconnect", onDisconnect);
681
681
 
682
682
  await server.start({
683
- transportType: "sse",
684
683
  sse: {
685
684
  endpoint: "/sse",
686
685
  port,
687
686
  },
687
+ transportType: "sse",
688
688
  });
689
689
 
690
690
  const client = new Client(
@@ -729,11 +729,11 @@ test("handles multiple clients", async () => {
729
729
  });
730
730
 
731
731
  await server.start({
732
- transportType: "sse",
733
732
  sse: {
734
733
  endpoint: "/sse",
735
734
  port,
736
735
  },
736
+ transportType: "sse",
737
737
  });
738
738
 
739
739
  const client1 = new Client(
@@ -799,8 +799,8 @@ test("session knows about client capabilities", async () => {
799
799
  return {
800
800
  roots: [
801
801
  {
802
- uri: "file:///home/user/projects/frontend",
803
802
  name: "Frontend Repository",
803
+ uri: "file:///home/user/projects/frontend",
804
804
  },
805
805
  ],
806
806
  };
@@ -839,8 +839,8 @@ test("session knows about roots", async () => {
839
839
  return {
840
840
  roots: [
841
841
  {
842
- uri: "file:///home/user/projects/frontend",
843
842
  name: "Frontend Repository",
843
+ uri: "file:///home/user/projects/frontend",
844
844
  },
845
845
  ],
846
846
  };
@@ -851,8 +851,8 @@ test("session knows about roots", async () => {
851
851
  run: async ({ session }) => {
852
852
  expect(session.roots).toEqual([
853
853
  {
854
- uri: "file:///home/user/projects/frontend",
855
854
  name: "Frontend Repository",
855
+ uri: "file:///home/user/projects/frontend",
856
856
  },
857
857
  ]);
858
858
  },
@@ -860,10 +860,10 @@ test("session knows about roots", async () => {
860
860
  });
861
861
 
862
862
  test("session listens to roots changes", async () => {
863
- let clientRoots: Root[] = [
863
+ const clientRoots: Root[] = [
864
864
  {
865
- uri: "file:///home/user/projects/frontend",
866
865
  name: "Frontend Repository",
866
+ uri: "file:///home/user/projects/frontend",
867
867
  },
868
868
  ];
869
869
 
@@ -891,17 +891,17 @@ test("session listens to roots changes", async () => {
891
891
 
892
892
  return client;
893
893
  },
894
- run: async ({ session, client }) => {
894
+ run: async ({ client, session }) => {
895
895
  expect(session.roots).toEqual([
896
896
  {
897
- uri: "file:///home/user/projects/frontend",
898
897
  name: "Frontend Repository",
898
+ uri: "file:///home/user/projects/frontend",
899
899
  },
900
900
  ]);
901
901
 
902
902
  clientRoots.push({
903
- uri: "file:///home/user/projects/backend",
904
903
  name: "Backend Repository",
904
+ uri: "file:///home/user/projects/backend",
905
905
  });
906
906
 
907
907
  await client.sendRootsListChanged();
@@ -914,12 +914,12 @@ test("session listens to roots changes", async () => {
914
914
 
915
915
  expect(session.roots).toEqual([
916
916
  {
917
- uri: "file:///home/user/projects/frontend",
918
917
  name: "Frontend Repository",
918
+ uri: "file:///home/user/projects/frontend",
919
919
  },
920
920
  {
921
- uri: "file:///home/user/projects/backend",
922
921
  name: "Backend Repository",
922
+ uri: "file:///home/user/projects/backend",
923
923
  },
924
924
  ]);
925
925
 
@@ -927,12 +927,12 @@ test("session listens to roots changes", async () => {
927
927
  expect(onRootsChanged).toHaveBeenCalledWith({
928
928
  roots: [
929
929
  {
930
- uri: "file:///home/user/projects/frontend",
931
930
  name: "Frontend Repository",
931
+ uri: "file:///home/user/projects/frontend",
932
932
  },
933
933
  {
934
- uri: "file:///home/user/projects/backend",
935
934
  name: "Backend Repository",
935
+ uri: "file:///home/user/projects/backend",
936
936
  },
937
937
  ],
938
938
  });
@@ -956,6 +956,24 @@ test("session sends pings to the client", async () => {
956
956
 
957
957
  test("completes prompt arguments", async () => {
958
958
  await runWithTestServer({
959
+ run: async ({ client }) => {
960
+ const response = await client.complete({
961
+ argument: {
962
+ name: "name",
963
+ value: "Germ",
964
+ },
965
+ ref: {
966
+ name: "countryPoem",
967
+ type: "ref/prompt",
968
+ },
969
+ });
970
+
971
+ expect(response).toEqual({
972
+ completion: {
973
+ values: ["Germany"],
974
+ },
975
+ });
976
+ },
959
977
  server: async () => {
960
978
  const server = new FastMCP({
961
979
  name: "Test",
@@ -963,16 +981,8 @@ test("completes prompt arguments", async () => {
963
981
  });
964
982
 
965
983
  server.addPrompt({
966
- name: "countryPoem",
967
- description: "Writes a poem about a country",
968
- load: async ({ name }) => {
969
- return `Hello, ${name}!`;
970
- },
971
984
  arguments: [
972
985
  {
973
- name: "name",
974
- description: "Name of the country",
975
- required: true,
976
986
  complete: async (value) => {
977
987
  if (value === "Germ") {
978
988
  return {
@@ -984,35 +994,44 @@ test("completes prompt arguments", async () => {
984
994
  values: [],
985
995
  };
986
996
  },
997
+ description: "Name of the country",
998
+ name: "name",
999
+ required: true,
987
1000
  },
988
1001
  ],
1002
+ description: "Writes a poem about a country",
1003
+ load: async ({ name }) => {
1004
+ return `Hello, ${name}!`;
1005
+ },
1006
+ name: "countryPoem",
989
1007
  });
990
1008
 
991
1009
  return server;
992
1010
  },
1011
+ });
1012
+ });
1013
+
1014
+ test("adds automatic prompt argument completion when enum is provided", async () => {
1015
+ await runWithTestServer({
993
1016
  run: async ({ client }) => {
994
1017
  const response = await client.complete({
995
- ref: {
996
- type: "ref/prompt",
997
- name: "countryPoem",
998
- },
999
1018
  argument: {
1000
1019
  name: "name",
1001
1020
  value: "Germ",
1002
1021
  },
1022
+ ref: {
1023
+ name: "countryPoem",
1024
+ type: "ref/prompt",
1025
+ },
1003
1026
  });
1004
1027
 
1005
1028
  expect(response).toEqual({
1006
1029
  completion: {
1030
+ total: 1,
1007
1031
  values: ["Germany"],
1008
1032
  },
1009
1033
  });
1010
1034
  },
1011
- });
1012
- });
1013
-
1014
- test("adds automatic prompt argument completion when enum is provided", async () => {
1015
- await runWithTestServer({
1016
1035
  server: async () => {
1017
1036
  const server = new FastMCP({
1018
1037
  name: "Test",
@@ -1020,47 +1039,46 @@ test("adds automatic prompt argument completion when enum is provided", async ()
1020
1039
  });
1021
1040
 
1022
1041
  server.addPrompt({
1023
- name: "countryPoem",
1024
- description: "Writes a poem about a country",
1025
- load: async ({ name }) => {
1026
- return `Hello, ${name}!`;
1027
- },
1028
1042
  arguments: [
1029
1043
  {
1030
- name: "name",
1031
1044
  description: "Name of the country",
1032
- required: true,
1033
1045
  enum: ["Germany", "France", "Italy"],
1046
+ name: "name",
1047
+ required: true,
1034
1048
  },
1035
1049
  ],
1050
+ description: "Writes a poem about a country",
1051
+ load: async ({ name }) => {
1052
+ return `Hello, ${name}!`;
1053
+ },
1054
+ name: "countryPoem",
1036
1055
  });
1037
1056
 
1038
1057
  return server;
1039
1058
  },
1059
+ });
1060
+ });
1061
+
1062
+ test("completes template resource arguments", async () => {
1063
+ await runWithTestServer({
1040
1064
  run: async ({ client }) => {
1041
1065
  const response = await client.complete({
1042
- ref: {
1043
- type: "ref/prompt",
1044
- name: "countryPoem",
1066
+ argument: {
1067
+ name: "issueId",
1068
+ value: "123",
1045
1069
  },
1046
- argument: {
1047
- name: "name",
1048
- value: "Germ",
1070
+ ref: {
1071
+ type: "ref/resource",
1072
+ uri: "issue:///{issueId}",
1049
1073
  },
1050
1074
  });
1051
1075
 
1052
1076
  expect(response).toEqual({
1053
1077
  completion: {
1054
- values: ["Germany"],
1055
- total: 1,
1078
+ values: ["123456"],
1056
1079
  },
1057
1080
  });
1058
1081
  },
1059
- });
1060
- });
1061
-
1062
- test("completes template resource arguments", async () => {
1063
- await runWithTestServer({
1064
1082
  server: async () => {
1065
1083
  const server = new FastMCP({
1066
1084
  name: "Test",
@@ -1068,13 +1086,8 @@ test("completes template resource arguments", async () => {
1068
1086
  });
1069
1087
 
1070
1088
  server.addResourceTemplate({
1071
- uriTemplate: "issue:///{issueId}",
1072
- name: "Issue",
1073
- mimeType: "text/plain",
1074
1089
  arguments: [
1075
1090
  {
1076
- name: "issueId",
1077
- description: "ID of the issue",
1078
1091
  complete: async (value) => {
1079
1092
  if (value === "123") {
1080
1093
  return {
@@ -1086,6 +1099,8 @@ test("completes template resource arguments", async () => {
1086
1099
  values: [],
1087
1100
  };
1088
1101
  },
1102
+ description: "ID of the issue",
1103
+ name: "issueId",
1089
1104
  },
1090
1105
  ],
1091
1106
  load: async ({ issueId }) => {
@@ -1093,33 +1108,28 @@ test("completes template resource arguments", async () => {
1093
1108
  text: `Issue ${issueId}`,
1094
1109
  };
1095
1110
  },
1111
+ mimeType: "text/plain",
1112
+ name: "Issue",
1113
+ uriTemplate: "issue:///{issueId}",
1096
1114
  });
1097
1115
 
1098
1116
  return server;
1099
1117
  },
1100
- run: async ({ client }) => {
1101
- const response = await client.complete({
1102
- ref: {
1103
- type: "ref/resource",
1104
- uri: "issue:///{issueId}",
1105
- },
1106
- argument: {
1107
- name: "issueId",
1108
- value: "123",
1109
- },
1110
- });
1111
-
1112
- expect(response).toEqual({
1113
- completion: {
1114
- values: ["123456"],
1115
- },
1116
- });
1117
- },
1118
1118
  });
1119
1119
  });
1120
1120
 
1121
1121
  test("lists resource templates", async () => {
1122
1122
  await runWithTestServer({
1123
+ run: async ({ client }) => {
1124
+ expect(await client.listResourceTemplates()).toEqual({
1125
+ resourceTemplates: [
1126
+ {
1127
+ name: "Application Logs",
1128
+ uriTemplate: "file:///logs/{name}.log",
1129
+ },
1130
+ ],
1131
+ });
1132
+ },
1123
1133
  server: async () => {
1124
1134
  const server = new FastMCP({
1125
1135
  name: "Test",
@@ -1127,13 +1137,10 @@ test("lists resource templates", async () => {
1127
1137
  });
1128
1138
 
1129
1139
  server.addResourceTemplate({
1130
- uriTemplate: "file:///logs/{name}.log",
1131
- name: "Application Logs",
1132
- mimeType: "text/plain",
1133
1140
  arguments: [
1134
1141
  {
1135
- name: "name",
1136
1142
  description: "Name of the log",
1143
+ name: "name",
1137
1144
  required: true,
1138
1145
  },
1139
1146
  ],
@@ -1142,24 +1149,18 @@ test("lists resource templates", async () => {
1142
1149
  text: `Example log content for ${name}`,
1143
1150
  };
1144
1151
  },
1152
+ mimeType: "text/plain",
1153
+ name: "Application Logs",
1154
+ uriTemplate: "file:///logs/{name}.log",
1145
1155
  });
1146
1156
 
1147
1157
  return server;
1148
1158
  },
1149
- run: async ({ client }) => {
1150
- expect(await client.listResourceTemplates()).toEqual({
1151
- resourceTemplates: [
1152
- {
1153
- name: "Application Logs",
1154
- uriTemplate: "file:///logs/{name}.log",
1155
- },
1156
- ],
1157
- });
1158
- },
1159
1159
  });
1160
1160
  });
1161
1161
 
1162
1162
  test("clients reads a resource accessed via a resource template", async () => {
1163
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1163
1164
  const loadSpy = vi.fn((_args) => {
1164
1165
  return {
1165
1166
  text: "Example log content",
@@ -1167,6 +1168,26 @@ test("clients reads a resource accessed via a resource template", async () => {
1167
1168
  });
1168
1169
 
1169
1170
  await runWithTestServer({
1171
+ run: async ({ client }) => {
1172
+ expect(
1173
+ await client.readResource({
1174
+ uri: "file:///logs/app.log",
1175
+ }),
1176
+ ).toEqual({
1177
+ contents: [
1178
+ {
1179
+ mimeType: "text/plain",
1180
+ name: "Application Logs",
1181
+ text: "Example log content",
1182
+ uri: "file:///logs/app.log",
1183
+ },
1184
+ ],
1185
+ });
1186
+
1187
+ expect(loadSpy).toHaveBeenCalledWith({
1188
+ name: "app",
1189
+ });
1190
+ },
1170
1191
  server: async () => {
1171
1192
  const server = new FastMCP({
1172
1193
  name: "Test",
@@ -1174,54 +1195,34 @@ test("clients reads a resource accessed via a resource template", async () => {
1174
1195
  });
1175
1196
 
1176
1197
  server.addResourceTemplate({
1177
- uriTemplate: "file:///logs/{name}.log",
1178
- name: "Application Logs",
1179
- mimeType: "text/plain",
1180
1198
  arguments: [
1181
1199
  {
1182
- name: "name",
1183
1200
  description: "Name of the log",
1201
+ name: "name",
1184
1202
  },
1185
1203
  ],
1186
1204
  async load(args) {
1187
1205
  return loadSpy(args);
1188
1206
  },
1207
+ mimeType: "text/plain",
1208
+ name: "Application Logs",
1209
+ uriTemplate: "file:///logs/{name}.log",
1189
1210
  });
1190
1211
 
1191
1212
  return server;
1192
1213
  },
1193
- run: async ({ client }) => {
1194
- expect(
1195
- await client.readResource({
1196
- uri: "file:///logs/app.log",
1197
- }),
1198
- ).toEqual({
1199
- contents: [
1200
- {
1201
- uri: "file:///logs/app.log",
1202
- name: "Application Logs",
1203
- text: "Example log content",
1204
- mimeType: "text/plain",
1205
- },
1206
- ],
1207
- });
1208
-
1209
- expect(loadSpy).toHaveBeenCalledWith({
1210
- name: "app",
1211
- });
1212
- },
1213
1214
  });
1214
1215
  });
1215
1216
 
1216
1217
  test("makes a sampling request", async () => {
1217
1218
  const onMessageRequest = vi.fn(() => {
1218
1219
  return {
1219
- model: "gpt-3.5-turbo",
1220
- role: "assistant",
1221
1220
  content: {
1222
- type: "text",
1223
1221
  text: "The files are in the current directory.",
1222
+ type: "text",
1224
1223
  },
1224
+ model: "gpt-3.5-turbo",
1225
+ role: "assistant",
1225
1226
  };
1226
1227
  });
1227
1228
 
@@ -1244,27 +1245,27 @@ test("makes a sampling request", async () => {
1244
1245
  client.setRequestHandler(CreateMessageRequestSchema, onMessageRequest);
1245
1246
 
1246
1247
  const response = await session.requestSampling({
1248
+ includeContext: "thisServer",
1249
+ maxTokens: 100,
1247
1250
  messages: [
1248
1251
  {
1249
- role: "user",
1250
1252
  content: {
1251
- type: "text",
1252
1253
  text: "What files are in the current directory?",
1254
+ type: "text",
1253
1255
  },
1256
+ role: "user",
1254
1257
  },
1255
1258
  ],
1256
1259
  systemPrompt: "You are a helpful file system assistant.",
1257
- includeContext: "thisServer",
1258
- maxTokens: 100,
1259
1260
  });
1260
1261
 
1261
1262
  expect(response).toEqual({
1262
- model: "gpt-3.5-turbo",
1263
- role: "assistant",
1264
1263
  content: {
1265
- type: "text",
1266
1264
  text: "The files are in the current directory.",
1265
+ type: "text",
1267
1266
  },
1267
+ model: "gpt-3.5-turbo",
1268
+ role: "assistant",
1268
1269
  });
1269
1270
 
1270
1271
  expect(onMessageRequest).toHaveBeenCalledTimes(1);
@@ -1274,34 +1275,14 @@ test("makes a sampling request", async () => {
1274
1275
 
1275
1276
  test("throws ErrorCode.InvalidParams if tool parameters do not match zod schema", async () => {
1276
1277
  await runWithTestServer({
1277
- server: async () => {
1278
- const server = new FastMCP({
1279
- name: "Test",
1280
- version: "1.0.0",
1281
- });
1282
-
1283
- server.addTool({
1284
- name: "add",
1285
- description: "Add two numbers",
1286
- parameters: z.object({
1287
- a: z.number(),
1288
- b: z.number(),
1289
- }),
1290
- execute: async (args) => {
1291
- return String(args.a + args.b);
1292
- },
1293
- });
1294
-
1295
- return server;
1296
- },
1297
1278
  run: async ({ client }) => {
1298
1279
  try {
1299
1280
  await client.callTool({
1300
- name: "add",
1301
1281
  arguments: {
1302
1282
  a: 1,
1303
1283
  b: "invalid",
1304
1284
  },
1285
+ name: "add",
1305
1286
  });
1306
1287
  } catch (error) {
1307
1288
  expect(error).toBeInstanceOf(McpError);
@@ -1310,14 +1291,11 @@ test("throws ErrorCode.InvalidParams if tool parameters do not match zod schema"
1310
1291
  expect(error.code).toBe(ErrorCode.InvalidParams);
1311
1292
 
1312
1293
  // @ts-expect-error - we know that error is an McpError
1313
- expect(error.message).toBe("MCP error -32602: MCP error -32602: Invalid add parameters");
1294
+ expect(error.message).toBe(
1295
+ "MCP error -32602: MCP error -32602: Invalid add parameters",
1296
+ );
1314
1297
  }
1315
1298
  },
1316
- });
1317
- });
1318
-
1319
- test("server remains usable after InvalidParams error", async () => {
1320
- await runWithTestServer({
1321
1299
  server: async () => {
1322
1300
  const server = new FastMCP({
1323
1301
  name: "Test",
@@ -1325,27 +1303,32 @@ test("server remains usable after InvalidParams error", async () => {
1325
1303
  });
1326
1304
 
1327
1305
  server.addTool({
1328
- name: "add",
1329
1306
  description: "Add two numbers",
1307
+ execute: async (args) => {
1308
+ return String(args.a + args.b);
1309
+ },
1310
+ name: "add",
1330
1311
  parameters: z.object({
1331
1312
  a: z.number(),
1332
1313
  b: z.number(),
1333
1314
  }),
1334
- execute: async (args) => {
1335
- return String(args.a + args.b);
1336
- },
1337
1315
  });
1338
1316
 
1339
1317
  return server;
1340
1318
  },
1319
+ });
1320
+ });
1321
+
1322
+ test("server remains usable after InvalidParams error", async () => {
1323
+ await runWithTestServer({
1341
1324
  run: async ({ client }) => {
1342
1325
  try {
1343
1326
  await client.callTool({
1344
- name: "add",
1345
1327
  arguments: {
1346
1328
  a: 1,
1347
1329
  b: "invalid",
1348
1330
  },
1331
+ name: "add",
1349
1332
  });
1350
1333
  } catch (error) {
1351
1334
  expect(error).toBeInstanceOf(McpError);
@@ -1354,20 +1337,42 @@ test("server remains usable after InvalidParams error", async () => {
1354
1337
  expect(error.code).toBe(ErrorCode.InvalidParams);
1355
1338
 
1356
1339
  // @ts-expect-error - we know that error is an McpError
1357
- expect(error.message).toBe("MCP error -32602: MCP error -32602: Invalid add parameters");
1340
+ expect(error.message).toBe(
1341
+ "MCP error -32602: MCP error -32602: Invalid add parameters",
1342
+ );
1358
1343
  }
1359
1344
 
1360
1345
  expect(
1361
1346
  await client.callTool({
1362
- name: "add",
1363
1347
  arguments: {
1364
1348
  a: 1,
1365
1349
  b: 2,
1366
1350
  },
1351
+ name: "add",
1367
1352
  }),
1368
1353
  ).toEqual({
1369
- content: [{ type: "text", text: "3" }],
1354
+ content: [{ text: "3", type: "text" }],
1355
+ });
1356
+ },
1357
+ server: async () => {
1358
+ const server = new FastMCP({
1359
+ name: "Test",
1360
+ version: "1.0.0",
1361
+ });
1362
+
1363
+ server.addTool({
1364
+ description: "Add two numbers",
1365
+ execute: async (args) => {
1366
+ return String(args.a + args.b);
1367
+ },
1368
+ name: "add",
1369
+ parameters: z.object({
1370
+ a: z.number(),
1371
+ b: z.number(),
1372
+ }),
1370
1373
  });
1374
+
1375
+ return server;
1371
1376
  },
1372
1377
  });
1373
1378
  });
@@ -1381,23 +1386,23 @@ test("allows new clients to connect after a client disconnects", async () => {
1381
1386
  });
1382
1387
 
1383
1388
  server.addTool({
1384
- name: "add",
1385
1389
  description: "Add two numbers",
1390
+ execute: async (args) => {
1391
+ return String(args.a + args.b);
1392
+ },
1393
+ name: "add",
1386
1394
  parameters: z.object({
1387
1395
  a: z.number(),
1388
1396
  b: z.number(),
1389
1397
  }),
1390
- execute: async (args) => {
1391
- return String(args.a + args.b);
1392
- },
1393
1398
  });
1394
1399
 
1395
1400
  await server.start({
1396
- transportType: "sse",
1397
1401
  sse: {
1398
1402
  endpoint: "/sse",
1399
1403
  port,
1400
1404
  },
1405
+ transportType: "sse",
1401
1406
  });
1402
1407
 
1403
1408
  const client1 = new Client(
@@ -1418,14 +1423,14 @@ test("allows new clients to connect after a client disconnects", async () => {
1418
1423
 
1419
1424
  expect(
1420
1425
  await client1.callTool({
1421
- name: "add",
1422
1426
  arguments: {
1423
1427
  a: 1,
1424
1428
  b: 2,
1425
1429
  },
1430
+ name: "add",
1426
1431
  }),
1427
1432
  ).toEqual({
1428
- content: [{ type: "text", text: "3" }],
1433
+ content: [{ text: "3", type: "text" }],
1429
1434
  });
1430
1435
 
1431
1436
  await client1.close();
@@ -1448,14 +1453,14 @@ test("allows new clients to connect after a client disconnects", async () => {
1448
1453
 
1449
1454
  expect(
1450
1455
  await client2.callTool({
1451
- name: "add",
1452
1456
  arguments: {
1453
1457
  a: 1,
1454
1458
  b: 2,
1455
1459
  },
1460
+ name: "add",
1456
1461
  }),
1457
1462
  ).toEqual({
1458
- content: [{ type: "text", text: "3" }],
1463
+ content: [{ text: "3", type: "text" }],
1459
1464
  });
1460
1465
 
1461
1466
  await client2.close();
@@ -1472,11 +1477,11 @@ test("able to close server immediately after starting it", async () => {
1472
1477
  });
1473
1478
 
1474
1479
  await server.start({
1475
- transportType: "sse",
1476
1480
  sse: {
1477
1481
  endpoint: "/sse",
1478
1482
  port,
1479
1483
  },
1484
+ transportType: "sse",
1480
1485
  });
1481
1486
 
1482
1487
  // We were previously not waiting for the server to start.
@@ -1493,32 +1498,32 @@ test("closing event source does not produce error", async () => {
1493
1498
  });
1494
1499
 
1495
1500
  server.addTool({
1496
- name: "add",
1497
1501
  description: "Add two numbers",
1502
+ execute: async (args) => {
1503
+ return String(args.a + args.b);
1504
+ },
1505
+ name: "add",
1498
1506
  parameters: z.object({
1499
1507
  a: z.number(),
1500
1508
  b: z.number(),
1501
1509
  }),
1502
- execute: async (args) => {
1503
- return String(args.a + args.b);
1504
- },
1505
1510
  });
1506
1511
 
1507
1512
  await server.start({
1508
- transportType: "sse",
1509
1513
  sse: {
1510
1514
  endpoint: "/sse",
1511
1515
  port,
1512
1516
  },
1517
+ transportType: "sse",
1513
1518
  });
1514
1519
 
1515
1520
  const eventSource = await new Promise<EventSourceClient>((onMessage) => {
1516
1521
  const eventSource = createEventSource({
1517
1522
  onConnect: () => {
1518
- console.info('connected');
1523
+ console.info("connected");
1519
1524
  },
1520
1525
  onDisconnect: () => {
1521
- console.info('disconnected');
1526
+ console.info("disconnected");
1522
1527
  },
1523
1528
  onMessage: () => {
1524
1529
  onMessage(eventSource);
@@ -1527,7 +1532,7 @@ test("closing event source does not produce error", async () => {
1527
1532
  });
1528
1533
  });
1529
1534
 
1530
- expect(eventSource.readyState).toBe('open');
1535
+ expect(eventSource.readyState).toBe("open");
1531
1536
 
1532
1537
  eventSource.close();
1533
1538
 
@@ -1547,10 +1552,10 @@ test("provides auth to tools", async () => {
1547
1552
  };
1548
1553
  });
1549
1554
 
1550
- const server = new FastMCP<{id: number}>({
1555
+ const server = new FastMCP<{ id: number }>({
1556
+ authenticate,
1551
1557
  name: "Test",
1552
1558
  version: "1.0.0",
1553
- authenticate,
1554
1559
  });
1555
1560
 
1556
1561
  const execute = vi.fn(async (args) => {
@@ -1558,21 +1563,21 @@ test("provides auth to tools", async () => {
1558
1563
  });
1559
1564
 
1560
1565
  server.addTool({
1561
- name: "add",
1562
1566
  description: "Add two numbers",
1567
+ execute,
1568
+ name: "add",
1563
1569
  parameters: z.object({
1564
1570
  a: z.number(),
1565
1571
  b: z.number(),
1566
1572
  }),
1567
- execute,
1568
1573
  });
1569
1574
 
1570
1575
  await server.start({
1571
- transportType: "sse",
1572
1576
  sse: {
1573
1577
  endpoint: "/sse",
1574
1578
  port,
1575
1579
  },
1580
+ transportType: "sse",
1576
1581
  });
1577
1582
 
1578
1583
  const client = new Client(
@@ -1604,57 +1609,63 @@ test("provides auth to tools", async () => {
1604
1609
 
1605
1610
  await client.connect(transport);
1606
1611
 
1607
- expect(authenticate, "authenticate should have been called").toHaveBeenCalledTimes(1);
1612
+ expect(
1613
+ authenticate,
1614
+ "authenticate should have been called",
1615
+ ).toHaveBeenCalledTimes(1);
1608
1616
 
1609
1617
  expect(
1610
1618
  await client.callTool({
1611
- name: "add",
1612
1619
  arguments: {
1613
1620
  a: 1,
1614
1621
  b: 2,
1615
1622
  },
1623
+ name: "add",
1616
1624
  }),
1617
1625
  ).toEqual({
1618
- content: [{ type: "text", text: "3" }],
1626
+ content: [{ text: "3", type: "text" }],
1619
1627
  });
1620
1628
 
1621
1629
  expect(execute, "execute should have been called").toHaveBeenCalledTimes(1);
1622
1630
 
1623
- expect(execute).toHaveBeenCalledWith({
1624
- a: 1,
1625
- b: 2,
1626
- }, {
1627
- log: {
1628
- debug: expect.any(Function),
1629
- error: expect.any(Function),
1630
- info: expect.any(Function),
1631
- warn: expect.any(Function),
1632
- },
1633
- reportProgress: expect.any(Function),
1634
- session: { id: 1 },
1635
- });
1631
+ expect(execute).toHaveBeenCalledWith(
1632
+ {
1633
+ a: 1,
1634
+ b: 2,
1635
+ },
1636
+ {
1637
+ log: {
1638
+ debug: expect.any(Function),
1639
+ error: expect.any(Function),
1640
+ info: expect.any(Function),
1641
+ warn: expect.any(Function),
1642
+ },
1643
+ reportProgress: expect.any(Function),
1644
+ session: { id: 1 },
1645
+ },
1646
+ );
1636
1647
  });
1637
1648
 
1638
1649
  test("blocks unauthorized requests", async () => {
1639
1650
  const port = await getRandomPort();
1640
1651
 
1641
- const server = new FastMCP<{id: number}>({
1642
- name: "Test",
1643
- version: "1.0.0",
1652
+ const server = new FastMCP<{ id: number }>({
1644
1653
  authenticate: async () => {
1645
1654
  throw new Response(null, {
1646
1655
  status: 401,
1647
1656
  statusText: "Unauthorized",
1648
1657
  });
1649
1658
  },
1659
+ name: "Test",
1660
+ version: "1.0.0",
1650
1661
  });
1651
1662
 
1652
1663
  await server.start({
1653
- transportType: "sse",
1654
1664
  sse: {
1655
1665
  endpoint: "/sse",
1656
1666
  port,
1657
1667
  },
1668
+ transportType: "sse",
1658
1669
  });
1659
1670
 
1660
1671
  const client = new Client(
@@ -1674,4 +1685,4 @@ test("blocks unauthorized requests", async () => {
1674
1685
  expect(async () => {
1675
1686
  await client.connect(transport);
1676
1687
  }).rejects.toThrow("SSE error: Non-200 status code (401)");
1677
- });
1688
+ });