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.
- package/.github/workflows/feature.yaml +2 -0
- package/.github/workflows/main.yaml +2 -0
- package/README.md +16 -6
- package/dist/bin/fastmcp.js +2 -2
- package/dist/bin/fastmcp.js.map +1 -1
- package/eslint.config.ts +3 -3
- package/jsr.json +1 -1
- package/package.json +3 -2
- package/src/FastMCP.test.ts +13 -13
- package/src/bin/fastmcp.ts +2 -2
- package/src/examples/addition.ts +6 -0
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(
|
|
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:
|
|
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
|
package/dist/bin/fastmcp.js
CHANGED
|
@@ -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:",
|
package/dist/bin/fastmcp.js.map
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastmcp",
|
|
3
|
-
"version": "1.27.
|
|
3
|
+
"version": "1.27.1",
|
|
4
4
|
"main": "dist/FastMCP.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "tsup",
|
|
7
|
-
"
|
|
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": {
|
package/src/FastMCP.test.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
package/src/bin/fastmcp.ts
CHANGED
|
@@ -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:",
|
package/src/examples/addition.ts
CHANGED
|
@@ -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";
|