fastmcp 4.21.1 → 4.21.2
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 +11 -4
- package/dist/FastMCP.cjs +3 -2
- package/dist/FastMCP.cjs.map +1 -1
- package/dist/FastMCP.d.cts +7 -1
- package/dist/FastMCP.d.ts +7 -1
- package/dist/FastMCP.js +2 -1
- package/dist/{chunk-IKH7YBYP.cjs → chunk-C5VOVQPC.cjs} +37 -28
- package/dist/chunk-C5VOVQPC.cjs.map +1 -0
- package/dist/chunk-O22SYZMC.cjs +22 -0
- package/dist/chunk-O22SYZMC.cjs.map +1 -0
- package/dist/{chunk-JNP6BG5L.js → chunk-QMRS4ZLD.js} +36 -27
- package/dist/chunk-QMRS4ZLD.js.map +1 -0
- package/dist/chunk-UMDUIBFW.js +22 -0
- package/dist/chunk-UMDUIBFW.js.map +1 -0
- package/dist/edge/index.cjs +7 -4
- package/dist/edge/index.cjs.map +1 -1
- package/dist/edge/index.js +6 -3
- package/dist/edge/index.js.map +1 -1
- package/dist/examples/custom-routes.cjs +3 -2
- package/dist/examples/custom-routes.cjs.map +1 -1
- package/dist/examples/custom-routes.js +2 -1
- package/dist/examples/custom-routes.js.map +1 -1
- package/dist/openapi/index.cjs +6 -5
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.js +2 -1
- package/dist/openapi/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-IKH7YBYP.cjs.map +0 -1
- package/dist/chunk-JNP6BG5L.js.map +0 -1
package/README.md
CHANGED
|
@@ -633,10 +633,12 @@ server.addTool({
|
|
|
633
633
|
|
|
634
634
|
Works for `outputSchema` too. Note that FastMCP advertises input schemas with
|
|
635
635
|
`additionalProperties: false`, whatever your schema said — the same treatment
|
|
636
|
-
Zod and Valibot schemas get. The exception is
|
|
637
|
-
|
|
638
|
-
keeps its value schema
|
|
639
|
-
|
|
636
|
+
Zod and Valibot schemas get. The exception is an object made only of
|
|
637
|
+
additional properties: a dictionary (no `properties` and an
|
|
638
|
+
`additionalProperties` schema, like `z.record()`) keeps its value schema, and a
|
|
639
|
+
free-form argument (`{ type: "object" }`, or `additionalProperties: true`)
|
|
640
|
+
stays open. Output schemas keep whatever additional-properties rule your schema
|
|
641
|
+
declared.
|
|
640
642
|
|
|
641
643
|
Unlike the schema libraries above, a plain JSON Schema carries no TypeScript
|
|
642
644
|
types, so `execute` receives `unknown` arguments. Cast or narrow them yourself.
|
|
@@ -750,6 +752,11 @@ server.addTool({
|
|
|
750
752
|
});
|
|
751
753
|
```
|
|
752
754
|
|
|
755
|
+
A server without an `authenticate` function has no auth to check, so every
|
|
756
|
+
session sees every tool. With one, a session that still ends up without auth —
|
|
757
|
+
on stdio, where the server carries on when `authenticate` throws or returns
|
|
758
|
+
nothing — sees none of the tools that have `canAccess`.
|
|
759
|
+
|
|
753
760
|
#### Returning a string
|
|
754
761
|
|
|
755
762
|
`execute` can return a string:
|
package/dist/FastMCP.cjs
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
var
|
|
14
|
+
var _chunkC5VOVQPCcjs = require('./chunk-C5VOVQPC.cjs');
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
|
|
@@ -25,6 +25,7 @@ var _chunkIKH7YBYPcjs = require('./chunk-IKH7YBYP.cjs');
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
var _chunkGTPK7A57cjs = require('./chunk-GTPK7A57.cjs');
|
|
28
|
+
require('./chunk-O22SYZMC.cjs');
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
|
|
@@ -49,5 +50,5 @@ var _chunkGTPK7A57cjs = require('./chunk-GTPK7A57.cjs');
|
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
|
|
52
|
-
exports.AuthProvider = _chunkGTPK7A57cjs.AuthProvider; exports.AzureProvider = _chunkGTPK7A57cjs.AzureProvider; exports.DiscoveryDocumentCache =
|
|
53
|
+
exports.AuthProvider = _chunkGTPK7A57cjs.AuthProvider; exports.AzureProvider = _chunkGTPK7A57cjs.AzureProvider; exports.DiscoveryDocumentCache = _chunkC5VOVQPCcjs.DiscoveryDocumentCache; exports.FastMCP = _chunkC5VOVQPCcjs.FastMCP; exports.FastMCPError = _chunkC5VOVQPCcjs.FastMCPError; exports.FastMCPSession = _chunkC5VOVQPCcjs.FastMCPSession; exports.GitHubProvider = _chunkGTPK7A57cjs.GitHubProvider; exports.GoogleProvider = _chunkGTPK7A57cjs.GoogleProvider; exports.MEDIA_FETCH_TIMEOUT_MS = _chunkC5VOVQPCcjs.MEDIA_FETCH_TIMEOUT_MS; exports.OAuthProvider = _chunkGTPK7A57cjs.OAuthProvider; exports.ServerState = _chunkC5VOVQPCcjs.ServerState; exports.SessionError = _chunkC5VOVQPCcjs.SessionError; exports.UnexpectedStateError = _chunkC5VOVQPCcjs.UnexpectedStateError; exports.UserError = _chunkC5VOVQPCcjs.UserError; exports.audioContent = _chunkC5VOVQPCcjs.audioContent; exports.getAuthSession = _chunkGTPK7A57cjs.getAuthSession; exports.imageContent = _chunkC5VOVQPCcjs.imageContent; exports.jsonSchemaAdapter = _chunkC5VOVQPCcjs.jsonSchemaAdapter; exports.requireAll = _chunkGTPK7A57cjs.requireAll; exports.requireAny = _chunkGTPK7A57cjs.requireAny; exports.requireAuth = _chunkGTPK7A57cjs.requireAuth; exports.requireRole = _chunkGTPK7A57cjs.requireRole; exports.requireScopes = _chunkGTPK7A57cjs.requireScopes;
|
|
53
54
|
//# sourceMappingURL=FastMCP.cjs.map
|
package/dist/FastMCP.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/runner/work/fastmcp/fastmcp/dist/FastMCP.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,0yCAAC","file":"/home/runner/work/fastmcp/fastmcp/dist/FastMCP.cjs"}
|
|
1
|
+
{"version":3,"sources":["/home/runner/work/fastmcp/fastmcp/dist/FastMCP.cjs"],"names":[],"mappings":"AAAA;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,0yCAAC","file":"/home/runner/work/fastmcp/fastmcp/dist/FastMCP.cjs"}
|
package/dist/FastMCP.d.cts
CHANGED
|
@@ -916,8 +916,14 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
|
|
|
916
916
|
*/
|
|
917
917
|
get sessionId(): string | undefined;
|
|
918
918
|
set sessionId(value: string | undefined);
|
|
919
|
-
constructor({ auth, hasTools, icons, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, title, tools, transportType, utils, version, websiteUrl, }: {
|
|
919
|
+
constructor({ auth, authRequired, hasTools, icons, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, title, tools, transportType, utils, version, websiteUrl, }: {
|
|
920
920
|
auth?: T;
|
|
921
|
+
/**
|
|
922
|
+
* Whether the server authenticates its sessions (`authenticate` is
|
|
923
|
+
* configured). A session that has no auth even so sees none of the tools
|
|
924
|
+
* gated by `canAccess` (see `toolsVisibleTo`).
|
|
925
|
+
*/
|
|
926
|
+
authRequired?: boolean;
|
|
921
927
|
/**
|
|
922
928
|
* Whether the server has any tools at all, including ones this session's
|
|
923
929
|
* `canAccess` filtering removed from `tools`. Defaults to `tools.length > 0`.
|
package/dist/FastMCP.d.ts
CHANGED
|
@@ -916,8 +916,14 @@ declare class FastMCPSession<T extends FastMCPSessionAuth = FastMCPSessionAuth>
|
|
|
916
916
|
*/
|
|
917
917
|
get sessionId(): string | undefined;
|
|
918
918
|
set sessionId(value: string | undefined);
|
|
919
|
-
constructor({ auth, hasTools, icons, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, title, tools, transportType, utils, version, websiteUrl, }: {
|
|
919
|
+
constructor({ auth, authRequired, hasTools, icons, instructions, logger, name, onToolCall, ping, prompts, resources, resourcesTemplates, roots, sessionId, stateless, streamKeepalive, title, tools, transportType, utils, version, websiteUrl, }: {
|
|
920
920
|
auth?: T;
|
|
921
|
+
/**
|
|
922
|
+
* Whether the server authenticates its sessions (`authenticate` is
|
|
923
|
+
* configured). A session that has no auth even so sees none of the tools
|
|
924
|
+
* gated by `canAccess` (see `toolsVisibleTo`).
|
|
925
|
+
*/
|
|
926
|
+
authRequired?: boolean;
|
|
921
927
|
/**
|
|
922
928
|
* Whether the server has any tools at all, including ones this session's
|
|
923
929
|
* `canAccess` filtering removed from `tools`. Defaults to `tools.length > 0`.
|
package/dist/FastMCP.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
audioContent,
|
|
12
12
|
imageContent,
|
|
13
13
|
jsonSchemaAdapter
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-QMRS4ZLD.js";
|
|
15
15
|
import {
|
|
16
16
|
AuthProvider,
|
|
17
17
|
AzureProvider,
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
requireRole,
|
|
26
26
|
requireScopes
|
|
27
27
|
} from "./chunk-AR3LVWUF.js";
|
|
28
|
+
import "./chunk-UMDUIBFW.js";
|
|
28
29
|
export {
|
|
29
30
|
AuthProvider,
|
|
30
31
|
AzureProvider,
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
var _chunkGTPK7A57cjs = require('./chunk-GTPK7A57.cjs');
|
|
4
4
|
|
|
5
|
+
|
|
6
|
+
var _chunkO22SYZMCcjs = require('./chunk-O22SYZMC.cjs');
|
|
7
|
+
|
|
5
8
|
// src/FastMCP.ts
|
|
6
9
|
var _indexjs = require('@modelcontextprotocol/sdk/server/index.js');
|
|
7
10
|
var _stdiojs = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
@@ -376,21 +379,6 @@ function assertToolSchemas(tool) {
|
|
|
376
379
|
assertStandardSchema(tool.name, "outputSchema", tool.outputSchema);
|
|
377
380
|
}
|
|
378
381
|
}
|
|
379
|
-
function strictInputSchema(schema) {
|
|
380
|
-
const isDictionary = typeof schema.additionalProperties === "object" && Object.keys(_nullishCoalesce(schema.properties, () => ( {}))).length === 0;
|
|
381
|
-
return {
|
|
382
|
-
...schema,
|
|
383
|
-
additionalProperties: isDictionary ? schema.additionalProperties : false,
|
|
384
|
-
...schema.properties && {
|
|
385
|
-
properties: Object.fromEntries(
|
|
386
|
-
Object.entries(schema.properties).map(([key, value]) => [
|
|
387
|
-
key,
|
|
388
|
-
typeof value === "object" && value.type === "object" ? strictInputSchema(value) : value
|
|
389
|
-
])
|
|
390
|
-
)
|
|
391
|
-
}
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
382
|
var STREAM_KEEPALIVE_LOGGER = "fastmcp-keepalive";
|
|
395
383
|
var STREAM_KEEPALIVE_DEFAULT_INTERVAL_MS = 2e4;
|
|
396
384
|
var TextContentZodSchema = _zod.z.object({
|
|
@@ -537,6 +525,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
537
525
|
*/
|
|
538
526
|
#abortController = new AbortController();
|
|
539
527
|
#auth;
|
|
528
|
+
#authRequired;
|
|
540
529
|
#capabilities = {};
|
|
541
530
|
#clientCapabilities;
|
|
542
531
|
#connectionState = "connecting";
|
|
@@ -575,6 +564,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
575
564
|
#utils;
|
|
576
565
|
constructor({
|
|
577
566
|
auth,
|
|
567
|
+
authRequired = false,
|
|
578
568
|
hasTools,
|
|
579
569
|
icons,
|
|
580
570
|
instructions,
|
|
@@ -598,6 +588,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
598
588
|
}) {
|
|
599
589
|
super();
|
|
600
590
|
this.#auth = auth;
|
|
591
|
+
this.#authRequired = authRequired;
|
|
601
592
|
this.#logger = logger;
|
|
602
593
|
this.#onToolCall = onToolCall;
|
|
603
594
|
this.#pingConfig = ping;
|
|
@@ -804,7 +795,9 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
804
795
|
}
|
|
805
796
|
}
|
|
806
797
|
toolsListChanged(tools) {
|
|
807
|
-
this.setupToolHandlers(
|
|
798
|
+
this.setupToolHandlers(
|
|
799
|
+
toolsVisibleTo(tools, this.#auth, this.#authRequired)
|
|
800
|
+
);
|
|
808
801
|
this.triggerListChangedNotification("notifications/tools/list_changed");
|
|
809
802
|
}
|
|
810
803
|
async triggerListChangedNotification(method) {
|
|
@@ -1067,9 +1060,10 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1067
1060
|
const ref = request.params.ref;
|
|
1068
1061
|
const prompt = "name" in ref && this.#prompts.get(ref.name);
|
|
1069
1062
|
if (!prompt) {
|
|
1070
|
-
throw new
|
|
1071
|
-
|
|
1072
|
-
|
|
1063
|
+
throw new (0, _typesjs.McpError)(
|
|
1064
|
+
_typesjs.ErrorCode.InvalidParams,
|
|
1065
|
+
`Unknown prompt: ${ref.name}`
|
|
1066
|
+
);
|
|
1073
1067
|
}
|
|
1074
1068
|
if (!prompt.complete) {
|
|
1075
1069
|
throw new UnexpectedStateError("Prompt does not support completion", {
|
|
@@ -1095,9 +1089,10 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1095
1089
|
(resource2) => resource2.uriTemplate === ref.uri
|
|
1096
1090
|
);
|
|
1097
1091
|
if (!resource) {
|
|
1098
|
-
throw new
|
|
1099
|
-
|
|
1100
|
-
|
|
1092
|
+
throw new (0, _typesjs.McpError)(
|
|
1093
|
+
_typesjs.ErrorCode.InvalidParams,
|
|
1094
|
+
`Unknown resource template: ${ref.uri}`
|
|
1095
|
+
);
|
|
1101
1096
|
}
|
|
1102
1097
|
if (!("uriTemplate" in resource)) {
|
|
1103
1098
|
throw new UnexpectedStateError("Unexpected resource");
|
|
@@ -1387,7 +1382,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1387
1382
|
return {
|
|
1388
1383
|
annotations: tool.annotations,
|
|
1389
1384
|
description: tool.description,
|
|
1390
|
-
inputSchema: tool.parameters ? strictInputSchema(await _xsschema.toJsonSchema.call(void 0, tool.parameters)) : {
|
|
1385
|
+
inputSchema: tool.parameters ? _chunkO22SYZMCcjs.strictInputSchema.call(void 0, await _xsschema.toJsonSchema.call(void 0, tool.parameters)) : {
|
|
1391
1386
|
additionalProperties: false,
|
|
1392
1387
|
properties: {},
|
|
1393
1388
|
type: "object"
|
|
@@ -1645,8 +1640,13 @@ function stripBasePath(path, basePath) {
|
|
|
1645
1640
|
}
|
|
1646
1641
|
return null;
|
|
1647
1642
|
}
|
|
1648
|
-
function toolsVisibleTo(tools, auth) {
|
|
1649
|
-
|
|
1643
|
+
function toolsVisibleTo(tools, auth, authRequired) {
|
|
1644
|
+
if (auth) {
|
|
1645
|
+
return tools.filter(
|
|
1646
|
+
(tool) => tool.canAccess ? tool.canAccess(auth) : true
|
|
1647
|
+
);
|
|
1648
|
+
}
|
|
1649
|
+
return authRequired ? tools.filter((tool) => !tool.canAccess) : tools;
|
|
1650
1650
|
}
|
|
1651
1651
|
var FastMCPEventEmitterBase = _events.EventEmitter;
|
|
1652
1652
|
var FastMCPEventEmitter = class extends FastMCPEventEmitterBase {
|
|
@@ -2027,6 +2027,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2027
2027
|
if (config.transportType === "stdio") {
|
|
2028
2028
|
const transport = new (0, _stdiojs.StdioServerTransport)();
|
|
2029
2029
|
let auth;
|
|
2030
|
+
const authRequired = this.#authenticate !== void 0;
|
|
2030
2031
|
if (this.#authenticate) {
|
|
2031
2032
|
try {
|
|
2032
2033
|
auth = await _asyncNullishCoalesce(await this.#authenticate(
|
|
@@ -2038,9 +2039,15 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2038
2039
|
error instanceof Error ? error.message : String(error)
|
|
2039
2040
|
);
|
|
2040
2041
|
}
|
|
2042
|
+
if (!auth && this.#tools.some((tool) => tool.canAccess)) {
|
|
2043
|
+
this.#logger.warn(
|
|
2044
|
+
"[FastMCP warning] The stdio session has no auth, so tools gated by canAccess are hidden from it."
|
|
2045
|
+
);
|
|
2046
|
+
}
|
|
2041
2047
|
}
|
|
2042
2048
|
const session = new FastMCPSession({
|
|
2043
2049
|
auth,
|
|
2050
|
+
authRequired,
|
|
2044
2051
|
hasTools: this.#tools.length > 0,
|
|
2045
2052
|
icons: this.#options.icons,
|
|
2046
2053
|
instructions: this.#options.instructions,
|
|
@@ -2054,7 +2061,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2054
2061
|
roots: this.#options.roots,
|
|
2055
2062
|
streamKeepalive: this.#options.streamKeepalive,
|
|
2056
2063
|
title: this.#options.title,
|
|
2057
|
-
tools: toolsVisibleTo(this.#tools, auth),
|
|
2064
|
+
tools: toolsVisibleTo(this.#tools, auth, authRequired),
|
|
2058
2065
|
transportType: "stdio",
|
|
2059
2066
|
utils: this.#options.utils,
|
|
2060
2067
|
version: this.#options.version,
|
|
@@ -2224,8 +2231,10 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2224
2231
|
const errorMessage = "error" in auth && typeof auth.error === "string" ? auth.error : "Authentication failed";
|
|
2225
2232
|
throw this.#createUnauthorizedResponse(errorMessage);
|
|
2226
2233
|
}
|
|
2234
|
+
const authRequired = this.#authenticate !== void 0;
|
|
2227
2235
|
return new FastMCPSession({
|
|
2228
2236
|
auth,
|
|
2237
|
+
authRequired,
|
|
2229
2238
|
hasTools: this.#tools.length > 0,
|
|
2230
2239
|
icons: this.#options.icons,
|
|
2231
2240
|
instructions: this.#options.instructions,
|
|
@@ -2241,7 +2250,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2241
2250
|
stateless,
|
|
2242
2251
|
streamKeepalive: this.#options.streamKeepalive,
|
|
2243
2252
|
title: this.#options.title,
|
|
2244
|
-
tools: toolsVisibleTo(this.#tools, auth),
|
|
2253
|
+
tools: toolsVisibleTo(this.#tools, auth, authRequired),
|
|
2245
2254
|
transportType: "httpStream",
|
|
2246
2255
|
utils: this.#options.utils,
|
|
2247
2256
|
version: this.#options.version,
|
|
@@ -2937,4 +2946,4 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2937
2946
|
|
|
2938
2947
|
|
|
2939
2948
|
exports.DiscoveryDocumentCache = DiscoveryDocumentCache; exports.jsonSchemaAdapter = jsonSchemaAdapter; exports.MEDIA_FETCH_TIMEOUT_MS = MEDIA_FETCH_TIMEOUT_MS; exports.imageContent = imageContent; exports.audioContent = audioContent; exports.FastMCPError = FastMCPError; exports.SessionError = SessionError; exports.UnexpectedStateError = UnexpectedStateError; exports.UserError = UserError; exports.ServerState = ServerState; exports.FastMCPSession = FastMCPSession; exports.FastMCP = FastMCP;
|
|
2940
|
-
//# sourceMappingURL=chunk-
|
|
2949
|
+
//# sourceMappingURL=chunk-C5VOVQPC.cjs.map
|