fastmcp 4.23.14 → 4.24.0
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 +34 -1
- package/dist/FastMCP.cjs +2 -2
- package/dist/FastMCP.d.cts +31 -1
- package/dist/FastMCP.d.ts +31 -1
- package/dist/FastMCP.js +1 -1
- package/dist/{chunk-UUZLMH5M.js → chunk-5JRRZ7MN.js} +122 -1
- package/dist/chunk-5JRRZ7MN.js.map +1 -0
- package/dist/{chunk-7USB5QLH.cjs → chunk-JMH7WDO2.cjs} +158 -37
- package/dist/chunk-JMH7WDO2.cjs.map +1 -0
- package/dist/examples/custom-routes.cjs +2 -2
- package/dist/examples/custom-routes.js +1 -1
- package/dist/openapi/index.cjs +6 -6
- package/dist/openapi/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7USB5QLH.cjs.map +0 -1
- package/dist/chunk-UUZLMH5M.js.map +0 -1
|
@@ -490,6 +490,8 @@ var LOGGING_LEVEL_SEVERITY = {
|
|
|
490
490
|
notice: 2,
|
|
491
491
|
warning: 3
|
|
492
492
|
};
|
|
493
|
+
var INSUFFICIENT_SCOPE_ERROR_CODE = -32001;
|
|
494
|
+
var SCOPE_TOKEN = /^[\x21\x23-\x5B\x5D-\x7E]+$/;
|
|
493
495
|
var FastMCPSessionEventEmitterBase = _events.EventEmitter;
|
|
494
496
|
var ServerState = /* @__PURE__ */ ((ServerState2) => {
|
|
495
497
|
ServerState2["Error"] = "error";
|
|
@@ -792,6 +794,24 @@ var FastMCPSession = class extends FastMCPSessionEventEmitter {
|
|
|
792
794
|
this.setupResourceTemplateHandlers();
|
|
793
795
|
this.triggerListChangedNotification("notifications/resources/list_changed");
|
|
794
796
|
}
|
|
797
|
+
/**
|
|
798
|
+
* The scope challenge one message a client sent would get, or `undefined` to
|
|
799
|
+
* let it through. FastMCP's HTTP transports ask before mcp-proxy dispatches
|
|
800
|
+
* each message, the last point at which the answer can still be a 403; the
|
|
801
|
+
* `tools/call` handler applies the same check on every transport.
|
|
802
|
+
*/
|
|
803
|
+
scopeChallengeFor(message) {
|
|
804
|
+
if (typeof message !== "object" || message === null) {
|
|
805
|
+
return void 0;
|
|
806
|
+
}
|
|
807
|
+
const { method, params } = message;
|
|
808
|
+
if (method !== "tools/call" || typeof params !== "object" || !params) {
|
|
809
|
+
return void 0;
|
|
810
|
+
}
|
|
811
|
+
const { name } = params;
|
|
812
|
+
const tool = this.#visibleTools.find((visible) => visible.name === name);
|
|
813
|
+
return tool ? this.#scopeChallenge(tool) : void 0;
|
|
814
|
+
}
|
|
795
815
|
/**
|
|
796
816
|
* Notifies the connected client that the contents of a resource have changed.
|
|
797
817
|
*
|
|
@@ -1030,6 +1050,27 @@ ${e instanceof Error ? e.stack : JSON.stringify(e)}`
|
|
|
1030
1050
|
}
|
|
1031
1051
|
}
|
|
1032
1052
|
}
|
|
1053
|
+
/**
|
|
1054
|
+
* The challenge a call to `tool` gets while the session's token lacks the
|
|
1055
|
+
* tool's `scopes`, or `undefined` when it may run. Applied on the same terms
|
|
1056
|
+
* as `canAccess` (see `toolsVisibleTo`): never without auth on a server that
|
|
1057
|
+
* does not authenticate, and with nothing granted when a server that does
|
|
1058
|
+
* has no auth for this session.
|
|
1059
|
+
*/
|
|
1060
|
+
#scopeChallenge(tool) {
|
|
1061
|
+
if (!_optionalChain([tool, 'access', _41 => _41.scopes, 'optionalAccess', _42 => _42.length]) || !this.#auth && !this.#authRequired) {
|
|
1062
|
+
return void 0;
|
|
1063
|
+
}
|
|
1064
|
+
const granted = grantedScopes(this.#auth);
|
|
1065
|
+
const missing = tool.scopes.filter((scope) => !granted.includes(scope));
|
|
1066
|
+
if (missing.length === 0) {
|
|
1067
|
+
return void 0;
|
|
1068
|
+
}
|
|
1069
|
+
return {
|
|
1070
|
+
description: `Insufficient scope for tool '${tool.name}': requires ${missing.join(" ")}`,
|
|
1071
|
+
scopes: [.../* @__PURE__ */ new Set([...granted, ...tool.scopes])]
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1033
1074
|
/**
|
|
1034
1075
|
* Sending rejects once the client has hung up, and these four
|
|
1035
1076
|
* callers are synchronous, so the rejection has nowhere to go. Swallow it the
|
|
@@ -1141,7 +1182,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1141
1182
|
*/
|
|
1142
1183
|
#startStreamKeepalive(extra, toolName) {
|
|
1143
1184
|
const config = this.#streamKeepaliveConfig;
|
|
1144
|
-
if (!_optionalChain([config, 'optionalAccess',
|
|
1185
|
+
if (!_optionalChain([config, 'optionalAccess', _43 => _43.enabled]) || _optionalChain([extra, 'access', _44 => _44.signal, 'optionalAccess', _45 => _45.aborted])) {
|
|
1145
1186
|
return () => {
|
|
1146
1187
|
};
|
|
1147
1188
|
}
|
|
@@ -1161,12 +1202,12 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1161
1202
|
);
|
|
1162
1203
|
});
|
|
1163
1204
|
}, intervalMs);
|
|
1164
|
-
_optionalChain([timer, 'access',
|
|
1205
|
+
_optionalChain([timer, 'access', _46 => _46.unref, 'optionalCall', _47 => _47()]);
|
|
1165
1206
|
const stop = () => {
|
|
1166
1207
|
clearInterval(timer);
|
|
1167
|
-
_optionalChain([extra, 'access',
|
|
1208
|
+
_optionalChain([extra, 'access', _48 => _48.signal, 'optionalAccess', _49 => _49.removeEventListener, 'call', _50 => _50("abort", stop)]);
|
|
1168
1209
|
};
|
|
1169
|
-
_optionalChain([extra, 'access',
|
|
1210
|
+
_optionalChain([extra, 'access', _51 => _51.signal, 'optionalAccess', _52 => _52.addEventListener, 'call', _53 => _53("abort", stop, { once: true })]);
|
|
1170
1211
|
return stop;
|
|
1171
1212
|
}
|
|
1172
1213
|
async #validateStructuredContent(tool, value, toolName) {
|
|
@@ -1386,7 +1427,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1386
1427
|
_nullishCoalesce(args, () => ( {})),
|
|
1387
1428
|
this.#auth,
|
|
1388
1429
|
this.#createLoadContext(
|
|
1389
|
-
_optionalChain([request, 'access',
|
|
1430
|
+
_optionalChain([request, 'access', _54 => _54.params, 'optionalAccess', _55 => _55._meta]),
|
|
1390
1431
|
extra.sendNotification,
|
|
1391
1432
|
extra.requestId
|
|
1392
1433
|
)
|
|
@@ -1455,7 +1496,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1455
1496
|
match,
|
|
1456
1497
|
this.#auth,
|
|
1457
1498
|
this.#createLoadContext(
|
|
1458
|
-
_optionalChain([request, 'access',
|
|
1499
|
+
_optionalChain([request, 'access', _56 => _56.params, 'optionalAccess', _57 => _57._meta]),
|
|
1459
1500
|
extra.sendNotification,
|
|
1460
1501
|
extra.requestId
|
|
1461
1502
|
)
|
|
@@ -1487,7 +1528,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1487
1528
|
maybeArrayResult = await resource.load(
|
|
1488
1529
|
this.#auth,
|
|
1489
1530
|
this.#createLoadContext(
|
|
1490
|
-
_optionalChain([request, 'access',
|
|
1531
|
+
_optionalChain([request, 'access', _58 => _58.params, 'optionalAccess', _59 => _59._meta]),
|
|
1491
1532
|
extra.sendNotification,
|
|
1492
1533
|
extra.requestId
|
|
1493
1534
|
)
|
|
@@ -1553,7 +1594,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1553
1594
|
);
|
|
1554
1595
|
}
|
|
1555
1596
|
setupRootsHandlers() {
|
|
1556
|
-
if (_optionalChain([this, 'access',
|
|
1597
|
+
if (_optionalChain([this, 'access', _60 => _60.#rootsConfig, 'optionalAccess', _61 => _61.enabled]) === false) {
|
|
1557
1598
|
this.#logger.debug(
|
|
1558
1599
|
"[FastMCP debug] roots capability explicitly disabled via config"
|
|
1559
1600
|
);
|
|
@@ -1636,6 +1677,14 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1636
1677
|
`Unknown tool: ${request.params.name}`
|
|
1637
1678
|
);
|
|
1638
1679
|
}
|
|
1680
|
+
const challenge = this.#scopeChallenge(tool);
|
|
1681
|
+
if (challenge) {
|
|
1682
|
+
throw new (0, _typesjs.McpError)(
|
|
1683
|
+
INSUFFICIENT_SCOPE_ERROR_CODE,
|
|
1684
|
+
challenge.description,
|
|
1685
|
+
{ error: "insufficient_scope", required_scopes: challenge.scopes }
|
|
1686
|
+
);
|
|
1687
|
+
}
|
|
1639
1688
|
let args = void 0;
|
|
1640
1689
|
if (tool.parameters) {
|
|
1641
1690
|
const parsed = await tool.parameters["~standard"].validate(
|
|
@@ -1650,7 +1699,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1650
1699
|
}
|
|
1651
1700
|
args = parsed.value;
|
|
1652
1701
|
}
|
|
1653
|
-
const progressToken = _optionalChain([request, 'access',
|
|
1702
|
+
const progressToken = _optionalChain([request, 'access', _62 => _62.params, 'optionalAccess', _63 => _63._meta, 'optionalAccess', _64 => _64.progressToken]);
|
|
1654
1703
|
let result;
|
|
1655
1704
|
const timeoutAbort = new AbortController();
|
|
1656
1705
|
const signal = AbortSignal.any([
|
|
@@ -1730,7 +1779,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
|
|
|
1730
1779
|
elicit: this.#createElicit(extra.requestId),
|
|
1731
1780
|
log,
|
|
1732
1781
|
reportProgress,
|
|
1733
|
-
requestId: typeof _optionalChain([request, 'access',
|
|
1782
|
+
requestId: typeof _optionalChain([request, 'access', _65 => _65.params, 'optionalAccess', _66 => _66._meta, 'optionalAccess', _67 => _67.requestId]) === "string" ? request.params._meta.requestId : void 0,
|
|
1734
1783
|
session: this.#auth,
|
|
1735
1784
|
sessionId: this.sessionId,
|
|
1736
1785
|
signal,
|
|
@@ -1914,7 +1963,7 @@ function normalizePath(path) {
|
|
|
1914
1963
|
return path.startsWith("/") ? path : `/${path}`;
|
|
1915
1964
|
}
|
|
1916
1965
|
function parseBasicAuthHeader(authHeader) {
|
|
1917
|
-
const basicMatch = _optionalChain([authHeader, 'optionalAccess',
|
|
1966
|
+
const basicMatch = _optionalChain([authHeader, 'optionalAccess', _68 => _68.match, 'call', _69 => _69(/^Basic\s+(.*)$/i)]);
|
|
1918
1967
|
if (!basicMatch) return null;
|
|
1919
1968
|
const credentials = Buffer.from(basicMatch[1].trim(), "base64").toString(
|
|
1920
1969
|
"utf-8"
|
|
@@ -1980,6 +2029,11 @@ var OAUTH_INVALID_CLIENT_RESPONSE_HEADERS = {
|
|
|
1980
2029
|
...OAUTH_CREDENTIAL_RESPONSE_HEADERS,
|
|
1981
2030
|
"WWW-Authenticate": 'Basic realm="oauth", charset="UTF-8"'
|
|
1982
2031
|
};
|
|
2032
|
+
function grantedScopes(auth) {
|
|
2033
|
+
const scopes = _optionalChain([auth, 'optionalAccess', _70 => _70.scopes]);
|
|
2034
|
+
const values = Array.isArray(scopes) ? scopes : scopes instanceof Set ? [...scopes] : [];
|
|
2035
|
+
return values.filter((scope) => typeof scope === "string");
|
|
2036
|
+
}
|
|
1983
2037
|
function stripBasePath(path, basePath) {
|
|
1984
2038
|
if (!basePath) {
|
|
1985
2039
|
return path;
|
|
@@ -2464,6 +2518,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2464
2518
|
const authenticate = this.#authenticate ? this.#memoizedAuthenticate() : void 0;
|
|
2465
2519
|
this.#httpStreamServer = await _mcpproxy.startHTTPServer.call(void 0, {
|
|
2466
2520
|
...authenticate ? { authenticate } : {},
|
|
2521
|
+
beforeDispatch: ({ message, server }) => this.#answerScopeChallenge(message, server),
|
|
2467
2522
|
cors: httpConfig.cors,
|
|
2468
2523
|
createServer: async (request) => {
|
|
2469
2524
|
let auth;
|
|
@@ -2511,6 +2566,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2511
2566
|
const authenticate = this.#authenticate ? this.#memoizedAuthenticate() : void 0;
|
|
2512
2567
|
this.#httpStreamServer = await _mcpproxy.startHTTPServer.call(void 0, {
|
|
2513
2568
|
...authenticate ? { authenticate } : {},
|
|
2569
|
+
beforeDispatch: ({ message, server }) => this.#answerScopeChallenge(message, server),
|
|
2514
2570
|
cors: httpConfig.cors,
|
|
2515
2571
|
createServer: async (request) => {
|
|
2516
2572
|
let auth;
|
|
@@ -2583,6 +2639,23 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2583
2639
|
}
|
|
2584
2640
|
this.#serverState = "stopped" /* Stopped */;
|
|
2585
2641
|
}
|
|
2642
|
+
/**
|
|
2643
|
+
* mcp-proxy's `beforeDispatch`: answers a `tools/call` the session's token
|
|
2644
|
+
* lacks scopes for with MCP's 403 scope challenge. It runs for every message
|
|
2645
|
+
* POSTed over HTTP, after `authenticate` and `updateAuth`, because once a
|
|
2646
|
+
* message is dispatched the SDK answers it on a 200.
|
|
2647
|
+
*/
|
|
2648
|
+
#answerScopeChallenge(message, session) {
|
|
2649
|
+
const challenge = session.scopeChallengeFor(message);
|
|
2650
|
+
if (!challenge) {
|
|
2651
|
+
return void 0;
|
|
2652
|
+
}
|
|
2653
|
+
const { id } = message;
|
|
2654
|
+
return this.#createInsufficientScopeResponse(
|
|
2655
|
+
challenge,
|
|
2656
|
+
typeof id === "number" || typeof id === "string" ? id : null
|
|
2657
|
+
);
|
|
2658
|
+
}
|
|
2586
2659
|
/**
|
|
2587
2660
|
* Connects `session` to `transport` and lists it in `sessions` until the
|
|
2588
2661
|
* transport closes. The close is watched from before the session connects,
|
|
@@ -2593,9 +2666,9 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2593
2666
|
const originalOnClose = transport.onclose;
|
|
2594
2667
|
transport.onclose = () => {
|
|
2595
2668
|
closed = true;
|
|
2596
|
-
_optionalChain([onClose, 'optionalCall',
|
|
2669
|
+
_optionalChain([onClose, 'optionalCall', _71 => _71()]);
|
|
2597
2670
|
this.#removeSession(session);
|
|
2598
|
-
_optionalChain([originalOnClose, 'optionalCall',
|
|
2671
|
+
_optionalChain([originalOnClose, 'optionalCall', _72 => _72()]);
|
|
2599
2672
|
};
|
|
2600
2673
|
await session.connect(transport);
|
|
2601
2674
|
if (closed) {
|
|
@@ -2609,6 +2682,54 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2609
2682
|
session
|
|
2610
2683
|
});
|
|
2611
2684
|
}
|
|
2685
|
+
/**
|
|
2686
|
+
* Builds MCP's 403 `insufficient_scope` challenge (2025-11-25, Scope
|
|
2687
|
+
* Challenge Handling). `scope` lists what the client should re-authorize
|
|
2688
|
+
* for, and `resource_metadata` is added on the same terms as on the 401 (see
|
|
2689
|
+
* `#createUnauthorizedResponse`).
|
|
2690
|
+
*
|
|
2691
|
+
* Clients such as the MCP SDK pick each parameter out with a simple pattern:
|
|
2692
|
+
* the first match wins and a quoted value ends at the first quote. So the
|
|
2693
|
+
* parameters come first, the description comes last, and it keeps only the
|
|
2694
|
+
* characters RFC 6750 allows in it.
|
|
2695
|
+
*/
|
|
2696
|
+
#createInsufficientScopeResponse(challenge, id) {
|
|
2697
|
+
const oauth = this.#options.oauth;
|
|
2698
|
+
const resource = _optionalChain([oauth, 'optionalAccess', _73 => _73.enabled]) ? _optionalChain([oauth, 'access', _74 => _74.protectedResource, 'optionalAccess', _75 => _75.resource]) : void 0;
|
|
2699
|
+
const wwwAuthenticateParts = [
|
|
2700
|
+
'error="insufficient_scope"',
|
|
2701
|
+
`scope="${challenge.scopes.filter((scope) => SCOPE_TOKEN.test(scope)).join(" ")}"`
|
|
2702
|
+
];
|
|
2703
|
+
if (resource) {
|
|
2704
|
+
wwwAuthenticateParts.push(
|
|
2705
|
+
`resource_metadata="${protectedResourceMetadataUrl(resource)}"`
|
|
2706
|
+
);
|
|
2707
|
+
}
|
|
2708
|
+
wwwAuthenticateParts.push(
|
|
2709
|
+
`error_description="${challenge.description.replace(/[^\x20\x21\x23-\x5B\x5D-\x7E]/g, "")}"`
|
|
2710
|
+
);
|
|
2711
|
+
return new Response(
|
|
2712
|
+
JSON.stringify({
|
|
2713
|
+
error: {
|
|
2714
|
+
code: INSUFFICIENT_SCOPE_ERROR_CODE,
|
|
2715
|
+
data: {
|
|
2716
|
+
error: "insufficient_scope",
|
|
2717
|
+
required_scopes: challenge.scopes
|
|
2718
|
+
},
|
|
2719
|
+
message: challenge.description
|
|
2720
|
+
},
|
|
2721
|
+
id,
|
|
2722
|
+
jsonrpc: "2.0"
|
|
2723
|
+
}),
|
|
2724
|
+
{
|
|
2725
|
+
headers: {
|
|
2726
|
+
"Content-Type": "application/json",
|
|
2727
|
+
"WWW-Authenticate": `Bearer ${wwwAuthenticateParts.join(", ")}`
|
|
2728
|
+
},
|
|
2729
|
+
status: 403
|
|
2730
|
+
}
|
|
2731
|
+
);
|
|
2732
|
+
}
|
|
2612
2733
|
/**
|
|
2613
2734
|
* Creates a new FastMCPSession instance with the current configuration.
|
|
2614
2735
|
* Used both for regular sessions and stateless requests.
|
|
@@ -2660,7 +2781,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2660
2781
|
*/
|
|
2661
2782
|
#createUnauthorizedResponse(message) {
|
|
2662
2783
|
const oauth = this.#options.oauth;
|
|
2663
|
-
const resource = _optionalChain([oauth, 'optionalAccess',
|
|
2784
|
+
const resource = _optionalChain([oauth, 'optionalAccess', _76 => _76.enabled]) ? _optionalChain([oauth, 'access', _77 => _77.protectedResource, 'optionalAccess', _78 => _78.resource]) : void 0;
|
|
2664
2785
|
const wwwAuthenticateParts = [
|
|
2665
2786
|
'error="invalid_token"',
|
|
2666
2787
|
`error_description="${message.replace(/"/g, '\\"')}"`
|
|
@@ -2799,7 +2920,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2799
2920
|
}
|
|
2800
2921
|
}
|
|
2801
2922
|
const oauthConfig = this.#options.oauth;
|
|
2802
|
-
if (_optionalChain([oauthConfig, 'optionalAccess',
|
|
2923
|
+
if (_optionalChain([oauthConfig, 'optionalAccess', _79 => _79.enabled]) && req.method === "GET") {
|
|
2803
2924
|
const url2 = new URL(req.url || "", `http://${host}`);
|
|
2804
2925
|
const authorizationServerMetadataPath = joinPaths(
|
|
2805
2926
|
"",
|
|
@@ -2833,8 +2954,8 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2833
2954
|
}
|
|
2834
2955
|
}
|
|
2835
2956
|
}
|
|
2836
|
-
const oauthProxy = _optionalChain([oauthConfig, 'optionalAccess',
|
|
2837
|
-
if (oauthProxy && _optionalChain([oauthConfig, 'optionalAccess',
|
|
2957
|
+
const oauthProxy = _optionalChain([oauthConfig, 'optionalAccess', _80 => _80.proxy]);
|
|
2958
|
+
if (oauthProxy && _optionalChain([oauthConfig, 'optionalAccess', _81 => _81.enabled])) {
|
|
2838
2959
|
const url2 = new URL(req.url || "", `http://${host}`);
|
|
2839
2960
|
const oauthPath = basePathRelativePath;
|
|
2840
2961
|
try {
|
|
@@ -2887,7 +3008,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2887
3008
|
const statusCode = error.statusCode || 400;
|
|
2888
3009
|
res.writeHead(statusCode, OAUTH_CREDENTIAL_RESPONSE_HEADERS).end(
|
|
2889
3010
|
JSON.stringify(
|
|
2890
|
-
_optionalChain([error, 'access',
|
|
3011
|
+
_optionalChain([error, 'access', _82 => _82.toJSON, 'optionalCall', _83 => _83()]) || {
|
|
2891
3012
|
error: "invalid_request"
|
|
2892
3013
|
}
|
|
2893
3014
|
)
|
|
@@ -2914,7 +3035,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2914
3035
|
} catch (error) {
|
|
2915
3036
|
res.writeHead(400, { "Content-Type": "application/json" }).end(
|
|
2916
3037
|
JSON.stringify(
|
|
2917
|
-
_optionalChain([error, 'access',
|
|
3038
|
+
_optionalChain([error, 'access', _84 => _84.toJSON, 'optionalCall', _85 => _85()]) || {
|
|
2918
3039
|
error: "invalid_request"
|
|
2919
3040
|
}
|
|
2920
3041
|
)
|
|
@@ -2936,7 +3057,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
2936
3057
|
} catch (error) {
|
|
2937
3058
|
res.writeHead(400, { "Content-Type": "application/json" }).end(
|
|
2938
3059
|
JSON.stringify(
|
|
2939
|
-
_optionalChain([error, 'access',
|
|
3060
|
+
_optionalChain([error, 'access', _86 => _86.toJSON, 'optionalCall', _87 => _87()]) || {
|
|
2940
3061
|
error: "server_error"
|
|
2941
3062
|
}
|
|
2942
3063
|
)
|
|
@@ -3005,7 +3126,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
3005
3126
|
} catch (error) {
|
|
3006
3127
|
res.writeHead(400, { "Content-Type": "application/json" }).end(
|
|
3007
3128
|
JSON.stringify(
|
|
3008
|
-
_optionalChain([error, 'access',
|
|
3129
|
+
_optionalChain([error, 'access', _88 => _88.toJSON, 'optionalCall', _89 => _89()]) || {
|
|
3009
3130
|
error: "server_error"
|
|
3010
3131
|
}
|
|
3011
3132
|
)
|
|
@@ -3120,7 +3241,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
3120
3241
|
}
|
|
3121
3242
|
res.writeHead(200, OAUTH_CREDENTIAL_RESPONSE_HEADERS).end(JSON.stringify(response));
|
|
3122
3243
|
} catch (error) {
|
|
3123
|
-
const body = _optionalChain([error, 'access',
|
|
3244
|
+
const body = _optionalChain([error, 'access', _90 => _90.toJSON, 'optionalCall', _91 => _91()]) || {
|
|
3124
3245
|
error: "invalid_request"
|
|
3125
3246
|
};
|
|
3126
3247
|
if (body.error === "invalid_client") {
|
|
@@ -3150,7 +3271,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
3150
3271
|
* regardless (RFC 7235), so no config is needed just to get the header.
|
|
3151
3272
|
*/
|
|
3152
3273
|
#httpStreamOAuthConfig() {
|
|
3153
|
-
const resource = _optionalChain([this, 'access',
|
|
3274
|
+
const resource = _optionalChain([this, 'access', _92 => _92.#options, 'access', _93 => _93.oauth, 'optionalAccess', _94 => _94.enabled]) ? _optionalChain([this, 'access', _95 => _95.#options, 'access', _96 => _96.oauth, 'access', _97 => _97.protectedResource, 'optionalAccess', _98 => _98.resource]) : void 0;
|
|
3154
3275
|
if (!resource) {
|
|
3155
3276
|
return {};
|
|
3156
3277
|
}
|
|
@@ -3256,24 +3377,24 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
3256
3377
|
const envBasePath = process.env.FASTMCP_BASE_PATH;
|
|
3257
3378
|
const envStateless = process.env.FASTMCP_STATELESS;
|
|
3258
3379
|
const envHost = process.env.FASTMCP_HOST;
|
|
3259
|
-
const transportType = _optionalChain([overrides, 'optionalAccess',
|
|
3380
|
+
const transportType = _optionalChain([overrides, 'optionalAccess', _99 => _99.transportType]) || parseTransportSetting(transportArg, "--transport") || parseTransportSetting(envTransport, "FASTMCP_TRANSPORT") || "stdio";
|
|
3260
3381
|
if (transportType === "httpStream") {
|
|
3261
3382
|
const port = parseInt(
|
|
3262
|
-
_optionalChain([overrides, 'optionalAccess',
|
|
3383
|
+
_optionalChain([overrides, 'optionalAccess', _100 => _100.httpStream, 'optionalAccess', _101 => _101.port, 'optionalAccess', _102 => _102.toString, 'call', _103 => _103()]) || portArg || envPort || "8080"
|
|
3263
3384
|
);
|
|
3264
|
-
const host = _optionalChain([overrides, 'optionalAccess',
|
|
3265
|
-
const endpoint = _optionalChain([overrides, 'optionalAccess',
|
|
3385
|
+
const host = _optionalChain([overrides, 'optionalAccess', _104 => _104.httpStream, 'optionalAccess', _105 => _105.host]) || hostArg || envHost || "localhost";
|
|
3386
|
+
const endpoint = _optionalChain([overrides, 'optionalAccess', _106 => _106.httpStream, 'optionalAccess', _107 => _107.endpoint]) || endpointArg || envEndpoint || "/mcp";
|
|
3266
3387
|
const basePath = normalizeBasePath(
|
|
3267
|
-
_optionalChain([overrides, 'optionalAccess',
|
|
3388
|
+
_optionalChain([overrides, 'optionalAccess', _108 => _108.httpStream, 'optionalAccess', _109 => _109.basePath]) || basePathArg || envBasePath
|
|
3268
3389
|
);
|
|
3269
|
-
const enableJsonResponse = _optionalChain([overrides, 'optionalAccess',
|
|
3270
|
-
const stateless = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([overrides, 'optionalAccess',
|
|
3390
|
+
const enableJsonResponse = _optionalChain([overrides, 'optionalAccess', _110 => _110.httpStream, 'optionalAccess', _111 => _111.enableJsonResponse]) || false;
|
|
3391
|
+
const stateless = _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(_optionalChain([overrides, 'optionalAccess', _112 => _112.httpStream, 'optionalAccess', _113 => _113.stateless]), () => ( // A bare `--stateless` means `--stateless true`.
|
|
3271
3392
|
(statelessArg === "" ? true : parseBooleanSetting(statelessArg, "--stateless")))), () => ( parseBooleanSetting(envStateless, "FASTMCP_STATELESS"))), () => ( false));
|
|
3272
|
-
const cors = _optionalChain([overrides, 'optionalAccess',
|
|
3273
|
-
const eventStore = _optionalChain([overrides, 'optionalAccess',
|
|
3274
|
-
const sslCa = _optionalChain([overrides, 'optionalAccess',
|
|
3275
|
-
const sslCert = _optionalChain([overrides, 'optionalAccess',
|
|
3276
|
-
const sslKey = _optionalChain([overrides, 'optionalAccess',
|
|
3393
|
+
const cors = _optionalChain([overrides, 'optionalAccess', _114 => _114.httpStream, 'optionalAccess', _115 => _115.cors]);
|
|
3394
|
+
const eventStore = _optionalChain([overrides, 'optionalAccess', _116 => _116.httpStream, 'optionalAccess', _117 => _117.eventStore]);
|
|
3395
|
+
const sslCa = _optionalChain([overrides, 'optionalAccess', _118 => _118.httpStream, 'optionalAccess', _119 => _119.sslCa]);
|
|
3396
|
+
const sslCert = _optionalChain([overrides, 'optionalAccess', _120 => _120.httpStream, 'optionalAccess', _121 => _121.sslCert]);
|
|
3397
|
+
const sslKey = _optionalChain([overrides, 'optionalAccess', _122 => _122.httpStream, 'optionalAccess', _123 => _123.sslKey]);
|
|
3277
3398
|
return {
|
|
3278
3399
|
httpStream: {
|
|
3279
3400
|
basePath,
|
|
@@ -3364,7 +3485,7 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
3364
3485
|
*/
|
|
3365
3486
|
#useEndpointAsResource(endpoint) {
|
|
3366
3487
|
const oauth = this.#options.oauth;
|
|
3367
|
-
if (this.#providerResourceBase === void 0 || !_optionalChain([oauth, 'optionalAccess',
|
|
3488
|
+
if (this.#providerResourceBase === void 0 || !_optionalChain([oauth, 'optionalAccess', _124 => _124.protectedResource]))
|
|
3368
3489
|
return;
|
|
3369
3490
|
this.#options = {
|
|
3370
3491
|
...this.#options,
|
|
@@ -3393,4 +3514,4 @@ var FastMCP = class extends FastMCPEventEmitter {
|
|
|
3393
3514
|
|
|
3394
3515
|
|
|
3395
3516
|
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;
|
|
3396
|
-
//# sourceMappingURL=chunk-
|
|
3517
|
+
//# sourceMappingURL=chunk-JMH7WDO2.cjs.map
|