fastmcp 4.23.6 → 4.23.8
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/dist/FastMCP.cjs +4 -4
- package/dist/FastMCP.d.cts +3 -2
- package/dist/FastMCP.d.ts +3 -2
- package/dist/FastMCP.js +3 -3
- package/dist/auth/index.cjs +2 -2
- package/dist/auth/index.js +1 -1
- package/dist/bin/fastmcp.cjs +7 -1
- package/dist/bin/fastmcp.cjs.map +1 -1
- package/dist/bin/fastmcp.js +7 -1
- package/dist/bin/fastmcp.js.map +1 -1
- package/dist/{chunk-C7TBI7A5.cjs → chunk-AJRXMUZR.cjs} +8 -4
- package/dist/chunk-AJRXMUZR.cjs.map +1 -0
- package/dist/chunk-F76U45MT.js +44 -0
- package/dist/chunk-F76U45MT.js.map +1 -0
- package/dist/{chunk-5QKBH7JC.js → chunk-PLUAEIWE.js} +87 -30
- package/dist/chunk-PLUAEIWE.js.map +1 -0
- package/dist/chunk-T2F3RYH2.cjs +44 -0
- package/dist/chunk-T2F3RYH2.cjs.map +1 -0
- package/dist/{chunk-CA2EPNZF.js → chunk-UY253ACS.js} +8 -4
- package/dist/chunk-UY253ACS.js.map +1 -0
- package/dist/{chunk-2PXF6JQB.cjs → chunk-XEP3OP7Q.cjs} +141 -84
- package/dist/chunk-XEP3OP7Q.cjs.map +1 -0
- package/dist/edge/index.cjs +9 -5
- package/dist/edge/index.cjs.map +1 -1
- package/dist/edge/index.js +9 -5
- package/dist/edge/index.js.map +1 -1
- package/dist/examples/custom-routes.cjs +4 -4
- package/dist/examples/custom-routes.js +3 -3
- package/dist/openapi/index.cjs +17 -12
- package/dist/openapi/index.cjs.map +1 -1
- package/dist/openapi/index.js +12 -7
- package/dist/openapi/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-2PXF6JQB.cjs.map +0 -1
- package/dist/chunk-5QKBH7JC.js.map +0 -1
- package/dist/chunk-C7TBI7A5.cjs.map +0 -1
- package/dist/chunk-CA2EPNZF.js.map +0 -1
- package/dist/chunk-O22SYZMC.cjs +0 -22
- package/dist/chunk-O22SYZMC.cjs.map +0 -1
- package/dist/chunk-UMDUIBFW.js +0 -22
- package/dist/chunk-UMDUIBFW.js.map +0 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
cancelResponseBody
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-UY253ACS.js";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
objectRootSchema,
|
|
6
|
+
strictInputSchema,
|
|
7
|
+
zodInputSchema
|
|
8
|
+
} from "./chunk-F76U45MT.js";
|
|
7
9
|
|
|
8
10
|
// src/FastMCP.ts
|
|
9
11
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -185,9 +187,11 @@ function jsonSchemaAdapter(schema) {
|
|
|
185
187
|
};
|
|
186
188
|
}
|
|
187
189
|
async function compileSchema(schema) {
|
|
190
|
+
const dialect = schema.$schema?.replace(/^http:\/\//, "https://").replace(/#$/, "");
|
|
191
|
+
const isDraft2020 = dialect === "https://json-schema.org/draft/2020-12/schema";
|
|
188
192
|
let ajvModule;
|
|
189
193
|
try {
|
|
190
|
-
ajvModule = await import("ajv");
|
|
194
|
+
ajvModule = isDraft2020 ? await import("ajv/dist/2020.js") : await import("ajv");
|
|
191
195
|
} catch {
|
|
192
196
|
throw new Error(
|
|
193
197
|
'The "ajv" package is required to validate JSON Schema tool parameters. Install it with: npm install ajv'
|
|
@@ -203,7 +207,7 @@ async function compileSchema(schema) {
|
|
|
203
207
|
addFormats(ajv);
|
|
204
208
|
} catch {
|
|
205
209
|
}
|
|
206
|
-
return ajv.compile(schema);
|
|
210
|
+
return ajv.compile(isDraft2020 ? { ...schema, $schema: dialect } : schema);
|
|
207
211
|
}
|
|
208
212
|
function toIssue(error) {
|
|
209
213
|
const path = error.instancePath.split("/").slice(1).map((segment) => segment.replaceAll("~1", "/").replaceAll("~0", "~")).map((segment) => {
|
|
@@ -542,6 +546,8 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
542
546
|
#capabilities = {};
|
|
543
547
|
#clientCapabilities;
|
|
544
548
|
#connectionState = "connecting";
|
|
549
|
+
// Caller-supplied transports leave the response mode unspecified.
|
|
550
|
+
#enableJsonResponse;
|
|
545
551
|
#logger;
|
|
546
552
|
/**
|
|
547
553
|
* The minimum level the client asked for with `logging/setLevel`, or
|
|
@@ -590,6 +596,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
590
596
|
constructor({
|
|
591
597
|
auth,
|
|
592
598
|
authRequired = false,
|
|
599
|
+
enableJsonResponse,
|
|
593
600
|
hasTools,
|
|
594
601
|
icons,
|
|
595
602
|
instructions,
|
|
@@ -614,6 +621,7 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
614
621
|
super();
|
|
615
622
|
this.#auth = auth;
|
|
616
623
|
this.#authRequired = authRequired;
|
|
624
|
+
this.#enableJsonResponse = enableJsonResponse;
|
|
617
625
|
this.#logger = logger;
|
|
618
626
|
this.#onToolCall = onToolCall;
|
|
619
627
|
this.#pingConfig = ping;
|
|
@@ -875,6 +883,19 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
875
883
|
}
|
|
876
884
|
return false;
|
|
877
885
|
}
|
|
886
|
+
/**
|
|
887
|
+
* When `start()` streams responses, an elicitation goes out on its request's
|
|
888
|
+
* own SSE stream, as the SDK's `extra.sendRequest` does, so it reaches a
|
|
889
|
+
* client that never opened the optional standalone GET stream. A JSON
|
|
890
|
+
* response cannot carry it, and a transport passed to `connect()` does not
|
|
891
|
+
* say which mode it uses, so those keep the session's standalone stream.
|
|
892
|
+
*/
|
|
893
|
+
#createElicit(requestId) {
|
|
894
|
+
return (params, options) => this.#server.elicitInput(
|
|
895
|
+
params,
|
|
896
|
+
this.#enableJsonResponse === false ? { ...options, relatedRequestId: requestId } : options
|
|
897
|
+
);
|
|
898
|
+
}
|
|
878
899
|
/**
|
|
879
900
|
* Builds the context object passed as the third argument to
|
|
880
901
|
* `resource.load` / `resourceTemplate.load` / `prompt.load`.
|
|
@@ -885,12 +906,12 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
885
906
|
* are tied to a tool call's progress token / streaming notification,
|
|
886
907
|
* which resource and prompt reads do not have.
|
|
887
908
|
*/
|
|
888
|
-
#createLoadContext(meta, sendNotification) {
|
|
909
|
+
#createLoadContext(meta, sendNotification, requestId) {
|
|
889
910
|
return {
|
|
890
911
|
client: {
|
|
891
912
|
version: this.#server.getClientVersion()
|
|
892
913
|
},
|
|
893
|
-
elicit:
|
|
914
|
+
elicit: this.#createElicit(requestId),
|
|
894
915
|
log: this.#createLog(sendNotification),
|
|
895
916
|
requestId: typeof meta?.requestId === "string" ? meta.requestId : void 0,
|
|
896
917
|
session: this.#auth,
|
|
@@ -1328,7 +1349,8 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1328
1349
|
this.#auth,
|
|
1329
1350
|
this.#createLoadContext(
|
|
1330
1351
|
request.params?._meta,
|
|
1331
|
-
extra.sendNotification
|
|
1352
|
+
extra.sendNotification,
|
|
1353
|
+
extra.requestId
|
|
1332
1354
|
)
|
|
1333
1355
|
);
|
|
1334
1356
|
} catch (error) {
|
|
@@ -1397,7 +1419,8 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1397
1419
|
this.#auth,
|
|
1398
1420
|
this.#createLoadContext(
|
|
1399
1421
|
request.params?._meta,
|
|
1400
|
-
extra.sendNotification
|
|
1422
|
+
extra.sendNotification,
|
|
1423
|
+
extra.requestId
|
|
1401
1424
|
)
|
|
1402
1425
|
);
|
|
1403
1426
|
const resources = Array.isArray(result) ? result : [result];
|
|
@@ -1426,7 +1449,8 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1426
1449
|
this.#auth,
|
|
1427
1450
|
this.#createLoadContext(
|
|
1428
1451
|
request.params?._meta,
|
|
1429
|
-
extra.sendNotification
|
|
1452
|
+
extra.sendNotification,
|
|
1453
|
+
extra.requestId
|
|
1430
1454
|
)
|
|
1431
1455
|
);
|
|
1432
1456
|
} catch (error) {
|
|
@@ -1541,15 +1565,17 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1541
1565
|
return {
|
|
1542
1566
|
annotations: tool.annotations,
|
|
1543
1567
|
description: tool.description,
|
|
1544
|
-
inputSchema: tool.parameters ? strictInputSchema(
|
|
1568
|
+
inputSchema: tool.parameters ? strictInputSchema(
|
|
1569
|
+
tool.parameters["~standard"].vendor === "zod" && "_zod" in tool.parameters ? zodInputSchema(tool.parameters, "draft-7") : await toJsonSchema(tool.parameters)
|
|
1570
|
+
) : {
|
|
1545
1571
|
additionalProperties: false,
|
|
1546
1572
|
properties: {},
|
|
1547
1573
|
type: "object"
|
|
1548
1574
|
},
|
|
1549
1575
|
name: tool.name,
|
|
1550
1576
|
...tool.outputSchema && {
|
|
1551
|
-
outputSchema:
|
|
1552
|
-
tool.outputSchema
|
|
1577
|
+
outputSchema: objectRootSchema(
|
|
1578
|
+
await toJsonSchema(tool.outputSchema)
|
|
1553
1579
|
)
|
|
1554
1580
|
},
|
|
1555
1581
|
// Pass through _meta for MCP ext-apps UI support (issue #229)
|
|
@@ -1650,7 +1676,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1650
1676
|
client: {
|
|
1651
1677
|
version: this.#server.getClientVersion()
|
|
1652
1678
|
},
|
|
1653
|
-
elicit:
|
|
1679
|
+
elicit: this.#createElicit(extra.requestId),
|
|
1654
1680
|
log,
|
|
1655
1681
|
reportProgress,
|
|
1656
1682
|
requestId: typeof request.params?._meta?.requestId === "string" ? request.params._meta.requestId : void 0,
|
|
@@ -1722,10 +1748,22 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1722
1748
|
}
|
|
1723
1749
|
} catch (error) {
|
|
1724
1750
|
if (error instanceof UserError) {
|
|
1751
|
+
let structuredContent = error.extras;
|
|
1752
|
+
if (structuredContent && tool.outputSchema) {
|
|
1753
|
+
try {
|
|
1754
|
+
structuredContent = await this.#validateStructuredContent(
|
|
1755
|
+
tool,
|
|
1756
|
+
structuredContent,
|
|
1757
|
+
request.params.name
|
|
1758
|
+
);
|
|
1759
|
+
} catch {
|
|
1760
|
+
structuredContent = void 0;
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1725
1763
|
return {
|
|
1726
1764
|
content: [{ text: error.message, type: "text" }],
|
|
1727
1765
|
isError: true,
|
|
1728
|
-
...
|
|
1766
|
+
...structuredContent ? { structuredContent } : {}
|
|
1729
1767
|
};
|
|
1730
1768
|
}
|
|
1731
1769
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -1941,7 +1979,9 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
1941
1979
|
* Adds a resource to the server.
|
|
1942
1980
|
*/
|
|
1943
1981
|
addResource(resource) {
|
|
1944
|
-
this.#resources = this.#resources.filter(
|
|
1982
|
+
this.#resources = this.#resources.filter(
|
|
1983
|
+
(r) => r.name !== resource.name && r.uri !== resource.uri
|
|
1984
|
+
);
|
|
1945
1985
|
this.#resources.push(resource);
|
|
1946
1986
|
if (this.#serverState === "running" /* Running */) {
|
|
1947
1987
|
this.#resourcesListChanged(this.#resources);
|
|
@@ -1951,13 +1991,12 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
1951
1991
|
* Adds resources to the server.
|
|
1952
1992
|
*/
|
|
1953
1993
|
addResources(resources) {
|
|
1954
|
-
const
|
|
1955
|
-
resources
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
this.#resources.push(...resources);
|
|
1994
|
+
for (const resource of resources) {
|
|
1995
|
+
this.#resources = this.#resources.filter(
|
|
1996
|
+
(r) => r.name !== resource.name && r.uri !== resource.uri
|
|
1997
|
+
);
|
|
1998
|
+
this.#resources.push(resource);
|
|
1999
|
+
}
|
|
1961
2000
|
if (this.#serverState === "running" /* Running */) {
|
|
1962
2001
|
this.#resourcesListChanged(this.#resources);
|
|
1963
2002
|
}
|
|
@@ -2005,9 +2044,12 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2005
2044
|
*/
|
|
2006
2045
|
addTools(tools) {
|
|
2007
2046
|
tools.forEach(assertToolSchemas);
|
|
2008
|
-
const
|
|
2009
|
-
|
|
2010
|
-
|
|
2047
|
+
const toolsByName = new Map(this.#tools.map((tool) => [tool.name, tool]));
|
|
2048
|
+
for (const tool of tools) {
|
|
2049
|
+
toolsByName.delete(tool.name);
|
|
2050
|
+
toolsByName.set(tool.name, tool);
|
|
2051
|
+
}
|
|
2052
|
+
this.#tools = Array.from(toolsByName.values());
|
|
2011
2053
|
if (this.#serverState === "running" /* Running */) {
|
|
2012
2054
|
this.#toolsListChanged(this.#tools);
|
|
2013
2055
|
}
|
|
@@ -2309,6 +2351,9 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2309
2351
|
this.#serverState = "running" /* Running */;
|
|
2310
2352
|
}
|
|
2311
2353
|
} else if (config.transportType === "httpStream") {
|
|
2354
|
+
if (this.#httpStreamServer) {
|
|
2355
|
+
throw new Error("HTTP server is already running");
|
|
2356
|
+
}
|
|
2312
2357
|
const httpConfig = config.httpStream;
|
|
2313
2358
|
const protocol = httpConfig.sslCert || httpConfig.sslKey ? "https" : "http";
|
|
2314
2359
|
const streamEndpoint = joinPaths(
|
|
@@ -2330,7 +2375,12 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2330
2375
|
auth = this.#requireAuthenticated(await authenticate(request));
|
|
2331
2376
|
}
|
|
2332
2377
|
const sessionId = Array.isArray(request.headers["mcp-session-id"]) ? request.headers["mcp-session-id"][0] : request.headers["mcp-session-id"];
|
|
2333
|
-
return this.#createSession(
|
|
2378
|
+
return this.#createSession(
|
|
2379
|
+
auth,
|
|
2380
|
+
sessionId,
|
|
2381
|
+
true,
|
|
2382
|
+
httpConfig.enableJsonResponse
|
|
2383
|
+
);
|
|
2334
2384
|
},
|
|
2335
2385
|
enableJsonResponse: httpConfig.enableJsonResponse,
|
|
2336
2386
|
eventStore: httpConfig.eventStore,
|
|
@@ -2372,7 +2422,12 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2372
2422
|
auth = this.#requireAuthenticated(await authenticate(request));
|
|
2373
2423
|
}
|
|
2374
2424
|
const sessionId = Array.isArray(request.headers["mcp-session-id"]) ? request.headers["mcp-session-id"][0] : request.headers["mcp-session-id"];
|
|
2375
|
-
return this.#createSession(
|
|
2425
|
+
return this.#createSession(
|
|
2426
|
+
auth,
|
|
2427
|
+
sessionId,
|
|
2428
|
+
false,
|
|
2429
|
+
httpConfig.enableJsonResponse
|
|
2430
|
+
);
|
|
2376
2431
|
},
|
|
2377
2432
|
enableJsonResponse: httpConfig.enableJsonResponse,
|
|
2378
2433
|
eventStore: httpConfig.eventStore,
|
|
@@ -2428,6 +2483,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2428
2483
|
);
|
|
2429
2484
|
if (this.#httpStreamServer) {
|
|
2430
2485
|
await this.#httpStreamServer.close();
|
|
2486
|
+
this.#httpStreamServer = null;
|
|
2431
2487
|
}
|
|
2432
2488
|
this.#serverState = "stopped" /* Stopped */;
|
|
2433
2489
|
}
|
|
@@ -2461,7 +2517,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2461
2517
|
* Creates a new FastMCPSession instance with the current configuration.
|
|
2462
2518
|
* Used both for regular sessions and stateless requests.
|
|
2463
2519
|
*/
|
|
2464
|
-
#createSession(auth, sessionId, stateless = false) {
|
|
2520
|
+
#createSession(auth, sessionId, stateless = false, enableJsonResponse) {
|
|
2465
2521
|
if (auth && typeof auth === "object" && "authenticated" in auth && !auth.authenticated) {
|
|
2466
2522
|
const errorMessage = "error" in auth && typeof auth.error === "string" ? auth.error : "Authentication failed";
|
|
2467
2523
|
throw this.#createUnauthorizedResponse(errorMessage);
|
|
@@ -2470,6 +2526,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2470
2526
|
return new FastMCPSession({
|
|
2471
2527
|
auth,
|
|
2472
2528
|
authRequired,
|
|
2529
|
+
enableJsonResponse,
|
|
2473
2530
|
hasTools: this.#tools.length > 0,
|
|
2474
2531
|
icons: this.#options.icons,
|
|
2475
2532
|
instructions: this.#options.instructions,
|
|
@@ -3213,4 +3270,4 @@ export {
|
|
|
3213
3270
|
FastMCPSession,
|
|
3214
3271
|
FastMCP
|
|
3215
3272
|
};
|
|
3216
|
-
//# sourceMappingURL=chunk-
|
|
3273
|
+
//# sourceMappingURL=chunk-PLUAEIWE.js.map
|