fastmcp 1.27.0 → 1.27.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.
@@ -33,5 +33,7 @@ jobs:
33
33
  cache-dependency-path: "**/pnpm-lock.yaml"
34
34
  - name: Install dependencies
35
35
  run: pnpm install
36
+ - name: Run lint
37
+ run: pnpm lint
36
38
  - name: Run tests
37
39
  run: pnpm test
@@ -37,6 +37,8 @@ jobs:
37
37
  cache-dependency-path: "**/pnpm-lock.yaml"
38
38
  - name: Install dependencies
39
39
  run: pnpm install
40
+ - name: Run lint
41
+ run: pnpm lint
40
42
  - name: Run tests
41
43
  run: pnpm test
42
44
  - name: Build
package/README.md CHANGED
@@ -81,6 +81,8 @@ npx fastmcp dev src/examples/addition.ts
81
81
  npx fastmcp inspect src/examples/addition.ts
82
82
  ```
83
83
 
84
+ If you are looking for a boilerplate repository to build your own MCP server, check out [fastmcp-boilerplate](https://github.com/punkpeye/fastmcp-boilerplate).
85
+
84
86
  ### Remote Server Options
85
87
 
86
88
  FastMCP supports multiple transport options for remote communication, allowing an MCP hosted on a remote machine to be accessed over the network.
@@ -158,7 +160,9 @@ const client = new Client(
158
160
  },
159
161
  );
160
162
 
161
- const transport = new StreamableHTTPClientTransport(new URL(`http://localhost:8080/stream`));
163
+ const transport = new StreamableHTTPClientTransport(
164
+ new URL(`http://localhost:8080/stream`),
165
+ );
162
166
 
163
167
  await client.connect(transport);
164
168
  ```
@@ -368,12 +372,13 @@ const server = new FastMCP({
368
372
  // Configure ping interval in milliseconds (default: 5000ms)
369
373
  intervalMs: 10000,
370
374
  // Set log level for ping-related messages (default: 'debug')
371
- logLevel: 'debug'
372
- }
375
+ logLevel: "debug",
376
+ },
373
377
  });
374
378
  ```
375
379
 
376
380
  By default, ping behavior is optimized for each transport type:
381
+
377
382
  - Enabled for SSE and HTTP streaming connections (which benefit from keep-alive)
378
383
  - Disabled for `stdio` connections (where pings are typically unnecessary)
379
384
 
@@ -391,11 +396,12 @@ const server = new FastMCP({
391
396
  // Set to false to explicitly disable roots support
392
397
  enabled: false,
393
398
  // By default, roots support is enabled (true)
394
- }
399
+ },
395
400
  });
396
401
  ```
397
402
 
398
403
  This provides the following benefits:
404
+
399
405
  - Better compatibility with different clients that may not support Roots
400
406
  - Reduced error logs when connecting to clients that don't implement roots capability
401
407
  - More explicit control over MCP server capabilities
@@ -406,10 +412,10 @@ You can listen for root changes in your server:
406
412
  ```ts
407
413
  server.on("connect", (event) => {
408
414
  const session = event.session;
409
-
415
+
410
416
  // Access the current roots
411
417
  console.log("Initial roots:", session.roots);
412
-
418
+
413
419
  // Listen for changes to the roots
414
420
  session.on("rootsChanged", (event) => {
415
421
  console.log("Roots changed:", event.roots);
@@ -1041,6 +1047,10 @@ Follow the guide https://modelcontextprotocol.io/quickstart/user and add the fol
1041
1047
  >
1042
1048
  > If you've developed a server using FastMCP, please [submit a PR](https://github.com/punkpeye/fastmcp) to showcase it here!
1043
1049
 
1050
+ > [!NOTE]
1051
+ >
1052
+ > If you are looking for a boilerplate repository to build your own MCP server, check out [fastmcp-boilerplate](https://github.com/punkpeye/fastmcp-boilerplate).
1053
+
1044
1054
  - [apinetwork/piapi-mcp-server](https://github.com/apinetwork/piapi-mcp-server) - generate media using Midjourney/Flux/Kling/LumaLabs/Udio/Chrip/Trellis
1045
1055
  - [domdomegg/computer-use-mcp](https://github.com/domdomegg/computer-use-mcp) - controls your computer
1046
1056
  - [LiterallyBlah/Dradis-MCP](https://github.com/LiterallyBlah/Dradis-MCP) – manages projects and vulnerabilities in Dradis
@@ -20,7 +20,7 @@ await yargs(hideBin(process.argv)).scriptName("fastmcp").command(
20
20
  stderr: "inherit",
21
21
  stdin: "inherit",
22
22
  stdout: "inherit"
23
- })`npx @wong2/mcp-cli npx tsx ${argv.file}`;
23
+ })`npx -y @wong2/mcp-cli npx -y tsx ${argv.file}`;
24
24
  } catch (error) {
25
25
  console.error(
26
26
  "[FastMCP Error] Failed to start development server:",
@@ -44,7 +44,7 @@ await yargs(hideBin(process.argv)).scriptName("fastmcp").command(
44
44
  await execa({
45
45
  stderr: "inherit",
46
46
  stdout: "inherit"
47
- })`npx @modelcontextprotocol/inspector npx tsx ${argv.file}`;
47
+ })`npx -y @modelcontextprotocol/inspector npx -y tsx ${argv.file}`;
48
48
  } catch (error) {
49
49
  console.error(
50
50
  "[FastMCP Error] Failed to inspect server:",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/fastmcp.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { execa } from \"execa\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nawait yargs(hideBin(process.argv))\n .scriptName(\"fastmcp\")\n .command(\n \"dev <file>\",\n \"Start a development server\",\n (yargs) => {\n return yargs.positional(\"file\", {\n demandOption: true,\n describe: \"The path to the server file\",\n type: \"string\",\n });\n },\n async (argv) => {\n try {\n await execa({\n stderr: \"inherit\",\n stdin: \"inherit\",\n stdout: \"inherit\",\n })`npx @wong2/mcp-cli npx tsx ${argv.file}`;\n } catch (error) {\n console.error(\n \"[FastMCP Error] Failed to start development server:\",\n error instanceof Error ? error.message : String(error),\n );\n process.exit(1);\n }\n },\n )\n .command(\n \"inspect <file>\",\n \"Inspect a server file\",\n (yargs) => {\n return yargs.positional(\"file\", {\n demandOption: true,\n describe: \"The path to the server file\",\n type: \"string\",\n });\n },\n async (argv) => {\n try {\n await execa({\n stderr: \"inherit\",\n stdout: \"inherit\",\n })`npx @modelcontextprotocol/inspector npx tsx ${argv.file}`;\n } catch (error) {\n console.error(\n \"[FastMCP Error] Failed to inspect server:\",\n error instanceof Error ? error.message : String(error),\n );\n process.exit(1);\n }\n },\n )\n .help()\n .parseAsync();\n"],"mappings":";;;AAEA,SAAS,aAAa;AACtB,OAAO,WAAW;AAClB,SAAS,eAAe;AAExB,MAAM,MAAM,QAAQ,QAAQ,IAAI,CAAC,EAC9B,WAAW,SAAS,EACpB;AAAA,EACC;AAAA,EACA;AAAA,EACA,CAACA,WAAU;AACT,WAAOA,OAAM,WAAW,QAAQ;AAAA,MAC9B,cAAc;AAAA,MACd,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EACA,OAAO,SAAS;AACd,QAAI;AACF,YAAM,MAAM;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,QAAQ;AAAA,MACV,CAAC,+BAA+B,KAAK,IAAI;AAAA,IAC3C,SAAS,OAAO;AACd,cAAQ;AAAA,QACN;AAAA,QACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACvD;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,EACC;AAAA,EACC;AAAA,EACA;AAAA,EACA,CAACA,WAAU;AACT,WAAOA,OAAM,WAAW,QAAQ;AAAA,MAC9B,cAAc;AAAA,MACd,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EACA,OAAO,SAAS;AACd,QAAI;AACF,YAAM,MAAM;AAAA,QACV,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC,gDAAgD,KAAK,IAAI;AAAA,IAC5D,SAAS,OAAO;AACd,cAAQ;AAAA,QACN;AAAA,QACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACvD;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,EACC,KAAK,EACL,WAAW;","names":["yargs"]}
1
+ {"version":3,"sources":["../../src/bin/fastmcp.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { execa } from \"execa\";\nimport yargs from \"yargs\";\nimport { hideBin } from \"yargs/helpers\";\n\nawait yargs(hideBin(process.argv))\n .scriptName(\"fastmcp\")\n .command(\n \"dev <file>\",\n \"Start a development server\",\n (yargs) => {\n return yargs.positional(\"file\", {\n demandOption: true,\n describe: \"The path to the server file\",\n type: \"string\",\n });\n },\n async (argv) => {\n try {\n await execa({\n stderr: \"inherit\",\n stdin: \"inherit\",\n stdout: \"inherit\",\n })`npx -y @wong2/mcp-cli npx -y tsx ${argv.file}`;\n } catch (error) {\n console.error(\n \"[FastMCP Error] Failed to start development server:\",\n error instanceof Error ? error.message : String(error),\n );\n process.exit(1);\n }\n },\n )\n .command(\n \"inspect <file>\",\n \"Inspect a server file\",\n (yargs) => {\n return yargs.positional(\"file\", {\n demandOption: true,\n describe: \"The path to the server file\",\n type: \"string\",\n });\n },\n async (argv) => {\n try {\n await execa({\n stderr: \"inherit\",\n stdout: \"inherit\",\n })`npx -y @modelcontextprotocol/inspector npx -y tsx ${argv.file}`;\n } catch (error) {\n console.error(\n \"[FastMCP Error] Failed to inspect server:\",\n error instanceof Error ? error.message : String(error),\n );\n process.exit(1);\n }\n },\n )\n .help()\n .parseAsync();\n"],"mappings":";;;AAEA,SAAS,aAAa;AACtB,OAAO,WAAW;AAClB,SAAS,eAAe;AAExB,MAAM,MAAM,QAAQ,QAAQ,IAAI,CAAC,EAC9B,WAAW,SAAS,EACpB;AAAA,EACC;AAAA,EACA;AAAA,EACA,CAACA,WAAU;AACT,WAAOA,OAAM,WAAW,QAAQ;AAAA,MAC9B,cAAc;AAAA,MACd,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EACA,OAAO,SAAS;AACd,QAAI;AACF,YAAM,MAAM;AAAA,QACV,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,QAAQ;AAAA,MACV,CAAC,qCAAqC,KAAK,IAAI;AAAA,IACjD,SAAS,OAAO;AACd,cAAQ;AAAA,QACN;AAAA,QACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACvD;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,EACC;AAAA,EACC;AAAA,EACA;AAAA,EACA,CAACA,WAAU;AACT,WAAOA,OAAM,WAAW,QAAQ;AAAA,MAC9B,cAAc;AAAA,MACd,UAAU;AAAA,MACV,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAAA,EACA,OAAO,SAAS;AACd,QAAI;AACF,YAAM,MAAM;AAAA,QACV,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV,CAAC,sDAAsD,KAAK,IAAI;AAAA,IAClE,SAAS,OAAO;AACd,cAAQ;AAAA,QACN;AAAA,QACA,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAAA,MACvD;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF,EACC,KAAK,EACL,WAAW;","names":["yargs"]}
package/eslint.config.ts CHANGED
@@ -1,7 +1,7 @@
1
- import eslint from '@eslint/js';
1
+ import eslint from "@eslint/js";
2
2
  import eslintConfigPrettier from "eslint-config-prettier/flat";
3
3
  import perfectionist from "eslint-plugin-perfectionist";
4
- import tseslint from 'typescript-eslint';
4
+ import tseslint from "typescript-eslint";
5
5
 
6
6
  export default tseslint.config(
7
7
  eslint.configs.recommended,
@@ -10,5 +10,5 @@ export default tseslint.config(
10
10
  eslintConfigPrettier,
11
11
  {
12
12
  ignores: ["**/*.js"],
13
- }
13
+ },
14
14
  );
package/jsr.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glama/fastmcp",
3
- "version": "1.27.0",
3
+ "version": "1.27.1",
4
4
  "exports": "./src/FastMCP.ts",
5
5
  "include": ["src/FastMCP.ts", "src/bin/fastmcp.ts"]
6
6
  }
package/package.json CHANGED
@@ -1,10 +1,11 @@
1
1
  {
2
2
  "name": "fastmcp",
3
- "version": "1.27.0",
3
+ "version": "1.27.1",
4
4
  "main": "dist/FastMCP.js",
5
5
  "scripts": {
6
6
  "build": "tsup",
7
- "test": "vitest run && tsc && jsr publish --dry-run",
7
+ "lint": "prettier --check . && eslint . && tsc --noEmit && jsr publish --dry-run",
8
+ "test": "vitest run",
8
9
  "format": "prettier --write . && eslint --fix ."
9
10
  },
10
11
  "bin": {
@@ -17,12 +17,12 @@ import { expect, test, vi } from "vitest";
17
17
  import { z } from "zod";
18
18
 
19
19
  import {
20
+ type ContentResult,
20
21
  FastMCP,
21
22
  FastMCPSession,
22
23
  imageContent,
23
- UserError,
24
24
  type TextContent,
25
- type ContentResult,
25
+ UserError,
26
26
  } from "./FastMCP.js";
27
27
 
28
28
  const runWithTestServer = async ({
@@ -1004,17 +1004,6 @@ test("session listens to roots changes", async () => {
1004
1004
 
1005
1005
  test("session sends pings to the client", async () => {
1006
1006
  await runWithTestServer({
1007
- server: async () => {
1008
- const server = new FastMCP({
1009
- name: "Test",
1010
- version: "1.0.0",
1011
- ping: {
1012
- enabled: true,
1013
- intervalMs: 1000,
1014
- },
1015
- });
1016
- return server;
1017
- },
1018
1007
  run: async ({ client }) => {
1019
1008
  const onPing = vi.fn().mockReturnValue({});
1020
1009
 
@@ -1025,6 +1014,17 @@ test("session sends pings to the client", async () => {
1025
1014
  expect(onPing.mock.calls.length).toBeGreaterThanOrEqual(1);
1026
1015
  expect(onPing.mock.calls.length).toBeLessThanOrEqual(3);
1027
1016
  },
1017
+ server: async () => {
1018
+ const server = new FastMCP({
1019
+ name: "Test",
1020
+ ping: {
1021
+ enabled: true,
1022
+ intervalMs: 1000,
1023
+ },
1024
+ version: "1.0.0",
1025
+ });
1026
+ return server;
1027
+ },
1028
1028
  });
1029
1029
  });
1030
1030
 
@@ -22,7 +22,7 @@ await yargs(hideBin(process.argv))
22
22
  stderr: "inherit",
23
23
  stdin: "inherit",
24
24
  stdout: "inherit",
25
- })`npx @wong2/mcp-cli npx tsx ${argv.file}`;
25
+ })`npx -y @wong2/mcp-cli npx -y tsx ${argv.file}`;
26
26
  } catch (error) {
27
27
  console.error(
28
28
  "[FastMCP Error] Failed to start development server:",
@@ -47,7 +47,7 @@ await yargs(hideBin(process.argv))
47
47
  await execa({
48
48
  stderr: "inherit",
49
49
  stdout: "inherit",
50
- })`npx @modelcontextprotocol/inspector npx tsx ${argv.file}`;
50
+ })`npx -y @modelcontextprotocol/inspector npx -y tsx ${argv.file}`;
51
51
  } catch (error) {
52
52
  console.error(
53
53
  "[FastMCP Error] Failed to inspect server:",
@@ -1,3 +1,9 @@
1
+ /**
2
+ * This is an example of a FastMCP server that adds two numbers.
3
+ *
4
+ * If you are looking for a complete example of an MCP server repository,
5
+ * see https://github.com/punkpeye/fastmcp-boilerplate
6
+ */
1
7
  import { type } from "arktype";
2
8
  import * as v from "valibot";
3
9
  import { z } from "zod";