fastmcp 4.3.2 → 4.5.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.
@@ -599,9 +599,70 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
599
599
  });
600
600
  });
601
601
  }
602
+ /**
603
+ * Builds the context object passed as the third argument to
604
+ * `resource.load` / `resourceTemplate.load` / `prompt.load`.
605
+ *
606
+ * This mirrors the `client`, `log`, `requestId`, `session`, and
607
+ * `sessionId` fields available to `tool.execute` via {@link Context}.
608
+ * `reportProgress` and `streamContent` are intentionally omitted: they
609
+ * are tied to a tool call's progress token / streaming notification,
610
+ * which resource and prompt reads do not have.
611
+ */
612
+ #createLoadContext(meta) {
613
+ return {
614
+ client: {
615
+ version: this.#server.getClientVersion()
616
+ },
617
+ log: this.#createLog(),
618
+ requestId: typeof _optionalChain([meta, 'optionalAccess', _12 => _12.requestId]) === "string" ? meta.requestId : void 0,
619
+ session: this.#auth,
620
+ sessionId: this.#sessionId
621
+ };
622
+ }
623
+ #createLog() {
624
+ return {
625
+ debug: (message, context) => {
626
+ this.#server.sendLoggingMessage({
627
+ data: {
628
+ context,
629
+ message
630
+ },
631
+ level: "debug"
632
+ });
633
+ },
634
+ error: (message, context) => {
635
+ this.#server.sendLoggingMessage({
636
+ data: {
637
+ context,
638
+ message
639
+ },
640
+ level: "error"
641
+ });
642
+ },
643
+ info: (message, context) => {
644
+ this.#server.sendLoggingMessage({
645
+ data: {
646
+ context,
647
+ message
648
+ },
649
+ level: "info"
650
+ });
651
+ },
652
+ warn: (message, context) => {
653
+ this.#server.sendLoggingMessage({
654
+ data: {
655
+ context,
656
+ message
657
+ },
658
+ level: "warning"
659
+ });
660
+ }
661
+ };
662
+ }
602
663
  #formatSchemaIssues(issues) {
603
- return _optionalChain([this, 'access', _12 => _12.#utils, 'optionalAccess', _13 => _13.formatInvalidParamsErrorMessage]) ? this.#utils.formatInvalidParamsErrorMessage(issues) : issues.map((issue) => {
604
- const path = _optionalChain([issue, 'access', _14 => _14.path, 'optionalAccess', _15 => _15.join, 'call', _16 => _16(".")]) || "root";
664
+ return _optionalChain([this, 'access', _13 => _13.#utils, 'optionalAccess', _14 => _14.formatInvalidParamsErrorMessage]) ? this.#utils.formatInvalidParamsErrorMessage(issues) : issues.map((issue) => {
665
+ const path = _optionalChain([issue, 'access', _15 => _15.path, 'optionalAccess', _16 => _16.join, 'call', _17 => _17(".")]) || "root";
605
666
  return `${path}: ${issue.message}`;
606
667
  }).join(", ");
607
668
  }
@@ -812,7 +873,8 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
812
873
  try {
813
874
  result = await prompt.load(
814
875
  args,
815
- this.#auth
876
+ this.#auth,
877
+ this.#createLoadContext(_optionalChain([request, 'access', _18 => _18.params, 'optionalAccess', _19 => _19._meta]))
816
878
  );
817
879
  } catch (error) {
818
880
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -874,7 +936,11 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
874
936
  continue;
875
937
  }
876
938
  const uri = uriTemplate.fill(match);
877
- const result = await resourceTemplate.load(match, this.#auth);
939
+ const result = await resourceTemplate.load(
940
+ match,
941
+ this.#auth,
942
+ this.#createLoadContext(_optionalChain([request, 'access', _20 => _20.params, 'optionalAccess', _21 => _21._meta]))
943
+ );
878
944
  const resources = Array.isArray(result) ? result : [result];
879
945
  return {
880
946
  contents: resources.map((resource2) => ({
@@ -896,7 +962,10 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
896
962
  }
897
963
  let maybeArrayResult;
898
964
  try {
899
- maybeArrayResult = await resource.load(this.#auth);
965
+ maybeArrayResult = await resource.load(
966
+ this.#auth,
967
+ this.#createLoadContext(_optionalChain([request, 'access', _22 => _22.params, 'optionalAccess', _23 => _23._meta]))
968
+ );
900
969
  } catch (error) {
901
970
  const errorMessage = error instanceof Error ? error.message : String(error);
902
971
  throw new (0, _typesjs.McpError)(
@@ -948,7 +1017,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
948
1017
  );
949
1018
  }
950
1019
  setupRootsHandlers() {
951
- if (_optionalChain([this, 'access', _17 => _17.#rootsConfig, 'optionalAccess', _18 => _18.enabled]) === false) {
1020
+ if (_optionalChain([this, 'access', _24 => _24.#rootsConfig, 'optionalAccess', _25 => _25.enabled]) === false) {
952
1021
  this.#logger.debug(
953
1022
  "[FastMCP debug] roots capability explicitly disabled via config"
954
1023
  );
@@ -1040,7 +1109,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1040
1109
  }
1041
1110
  args = parsed.value;
1042
1111
  }
1043
- const progressToken = _optionalChain([request, 'access', _19 => _19.params, 'optionalAccess', _20 => _20._meta, 'optionalAccess', _21 => _21.progressToken]);
1112
+ const progressToken = _optionalChain([request, 'access', _26 => _26.params, 'optionalAccess', _27 => _27._meta, 'optionalAccess', _28 => _28.progressToken]);
1044
1113
  let result;
1045
1114
  try {
1046
1115
  const reportProgress = async (progress) => {
@@ -1065,44 +1134,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1065
1134
  );
1066
1135
  }
1067
1136
  };
1068
- const log = {
1069
- debug: (message, context) => {
1070
- this.#server.sendLoggingMessage({
1071
- data: {
1072
- context,
1073
- message
1074
- },
1075
- level: "debug"
1076
- });
1077
- },
1078
- error: (message, context) => {
1079
- this.#server.sendLoggingMessage({
1080
- data: {
1081
- context,
1082
- message
1083
- },
1084
- level: "error"
1085
- });
1086
- },
1087
- info: (message, context) => {
1088
- this.#server.sendLoggingMessage({
1089
- data: {
1090
- context,
1091
- message
1092
- },
1093
- level: "info"
1094
- });
1095
- },
1096
- warn: (message, context) => {
1097
- this.#server.sendLoggingMessage({
1098
- data: {
1099
- context,
1100
- message
1101
- },
1102
- level: "warning"
1103
- });
1104
- }
1105
- };
1137
+ const log = this.#createLog();
1106
1138
  const streamContent = async (content) => {
1107
1139
  const contentArray = Array.isArray(content) ? content : [content];
1108
1140
  try {
@@ -1135,7 +1167,7 @@ ${error instanceof Error ? error.stack : JSON.stringify(error)}`
1135
1167
  },
1136
1168
  log,
1137
1169
  reportProgress,
1138
- requestId: typeof _optionalChain([request, 'access', _22 => _22.params, 'optionalAccess', _23 => _23._meta, 'optionalAccess', _24 => _24.requestId]) === "string" ? request.params._meta.requestId : void 0,
1170
+ requestId: typeof _optionalChain([request, 'access', _29 => _29.params, 'optionalAccess', _30 => _30._meta, 'optionalAccess', _31 => _31.requestId]) === "string" ? request.params._meta.requestId : void 0,
1139
1171
  session: this.#auth,
1140
1172
  sessionId: this.#sessionId,
1141
1173
  streamContent
@@ -1230,8 +1262,22 @@ function convertObjectToSnakeCase(obj) {
1230
1262
  }
1231
1263
  return result;
1232
1264
  }
1265
+ function joinPaths(basePath, path) {
1266
+ return `${basePath}${normalizePath(path)}`;
1267
+ }
1268
+ function normalizeBasePath(path) {
1269
+ if (!path || path === "/") {
1270
+ return "";
1271
+ }
1272
+ const withLeadingSlash = path.startsWith("/") ? path : `/${path}`;
1273
+ const withoutTrailingSlash = withLeadingSlash.replace(/\/+$/, "");
1274
+ return withoutTrailingSlash ? withoutTrailingSlash : "";
1275
+ }
1276
+ function normalizePath(path) {
1277
+ return path.startsWith("/") ? path : `/${path}`;
1278
+ }
1233
1279
  function parseBasicAuthHeader(authHeader) {
1234
- const basicMatch = _optionalChain([authHeader, 'optionalAccess', _25 => _25.match, 'call', _26 => _26(/^Basic\s+(.+)$/)]);
1280
+ const basicMatch = _optionalChain([authHeader, 'optionalAccess', _32 => _32.match, 'call', _33 => _33(/^Basic\s+(.+)$/)]);
1235
1281
  if (!basicMatch) return null;
1236
1282
  try {
1237
1283
  const credentials = Buffer.from(basicMatch[1], "base64").toString("utf-8");
@@ -1242,6 +1288,18 @@ function parseBasicAuthHeader(authHeader) {
1242
1288
  return null;
1243
1289
  }
1244
1290
  }
1291
+ function stripBasePath(path, basePath) {
1292
+ if (!basePath) {
1293
+ return path;
1294
+ }
1295
+ if (path === basePath) {
1296
+ return "/";
1297
+ }
1298
+ if (path.startsWith(`${basePath}/`)) {
1299
+ return path.slice(basePath.length);
1300
+ }
1301
+ return null;
1302
+ }
1245
1303
  var FastMCPEventEmitterBase = _events.EventEmitter;
1246
1304
  var FastMCPEventEmitter = class extends FastMCPEventEmitterBase {
1247
1305
  };
@@ -1596,9 +1654,13 @@ var FastMCP = class extends FastMCPEventEmitter {
1596
1654
  } else if (config.transportType === "httpStream") {
1597
1655
  const httpConfig = config.httpStream;
1598
1656
  const protocol = httpConfig.sslCert || httpConfig.sslKey ? "https" : "http";
1657
+ const streamEndpoint = joinPaths(
1658
+ httpConfig.basePath,
1659
+ httpConfig.endpoint
1660
+ );
1599
1661
  if (httpConfig.stateless) {
1600
1662
  this.#logger.info(
1601
- `[FastMCP info] Starting server in stateless mode on HTTP Stream at ${protocol}://${httpConfig.host}:${httpConfig.port}${httpConfig.endpoint}`
1663
+ `[FastMCP info] Starting server in stateless mode on HTTP Stream at ${protocol}://${httpConfig.host}:${httpConfig.port}${streamEndpoint}`
1602
1664
  );
1603
1665
  this.#httpStreamServer = await _mcpproxy.startHTTPServer.call(void 0, {
1604
1666
  ...this.#authenticate ? { authenticate: this.#authenticate } : {},
@@ -1617,7 +1679,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1617
1679
  enableJsonResponse: httpConfig.enableJsonResponse,
1618
1680
  eventStore: httpConfig.eventStore,
1619
1681
  host: httpConfig.host,
1620
- ..._optionalChain([this, 'access', _27 => _27.#options, 'access', _28 => _28.oauth, 'optionalAccess', _29 => _29.enabled]) && _optionalChain([this, 'access', _30 => _30.#options, 'access', _31 => _31.oauth, 'access', _32 => _32.protectedResource, 'optionalAccess', _33 => _33.resource]) ? {
1682
+ ..._optionalChain([this, 'access', _34 => _34.#options, 'access', _35 => _35.oauth, 'optionalAccess', _36 => _36.enabled]) && _optionalChain([this, 'access', _37 => _37.#options, 'access', _38 => _38.oauth, 'access', _39 => _39.protectedResource, 'optionalAccess', _40 => _40.resource]) ? {
1621
1683
  oauth: {
1622
1684
  protectedResource: {
1623
1685
  resource: this.#options.oauth.protectedResource.resource
@@ -1638,7 +1700,8 @@ var FastMCP = class extends FastMCPEventEmitter {
1638
1700
  res,
1639
1701
  true,
1640
1702
  httpConfig.host,
1641
- httpConfig.endpoint
1703
+ streamEndpoint,
1704
+ httpConfig.basePath
1642
1705
  );
1643
1706
  },
1644
1707
  port: httpConfig.port,
@@ -1646,7 +1709,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1646
1709
  sslCert: httpConfig.sslCert,
1647
1710
  sslKey: httpConfig.sslKey,
1648
1711
  stateless: true,
1649
- streamEndpoint: httpConfig.endpoint
1712
+ streamEndpoint
1650
1713
  });
1651
1714
  } else {
1652
1715
  this.#httpStreamServer = await _mcpproxy.startHTTPServer.call(void 0, {
@@ -1663,7 +1726,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1663
1726
  enableJsonResponse: httpConfig.enableJsonResponse,
1664
1727
  eventStore: httpConfig.eventStore,
1665
1728
  host: httpConfig.host,
1666
- ..._optionalChain([this, 'access', _34 => _34.#options, 'access', _35 => _35.oauth, 'optionalAccess', _36 => _36.enabled]) && _optionalChain([this, 'access', _37 => _37.#options, 'access', _38 => _38.oauth, 'access', _39 => _39.protectedResource, 'optionalAccess', _40 => _40.resource]) ? {
1729
+ ..._optionalChain([this, 'access', _41 => _41.#options, 'access', _42 => _42.oauth, 'optionalAccess', _43 => _43.enabled]) && _optionalChain([this, 'access', _44 => _44.#options, 'access', _45 => _45.oauth, 'access', _46 => _46.protectedResource, 'optionalAccess', _47 => _47.resource]) ? {
1667
1730
  oauth: {
1668
1731
  protectedResource: {
1669
1732
  resource: this.#options.oauth.protectedResource.resource
@@ -1690,7 +1753,8 @@ var FastMCP = class extends FastMCPEventEmitter {
1690
1753
  res,
1691
1754
  false,
1692
1755
  httpConfig.host,
1693
- httpConfig.endpoint
1756
+ streamEndpoint,
1757
+ httpConfig.basePath
1694
1758
  );
1695
1759
  },
1696
1760
  port: httpConfig.port,
@@ -1698,10 +1762,10 @@ var FastMCP = class extends FastMCPEventEmitter {
1698
1762
  sslCert: httpConfig.sslCert,
1699
1763
  sslKey: httpConfig.sslKey,
1700
1764
  stateless: httpConfig.stateless,
1701
- streamEndpoint: httpConfig.endpoint
1765
+ streamEndpoint
1702
1766
  });
1703
1767
  this.#logger.info(
1704
- `[FastMCP info] server is running on HTTP Stream at ${protocol}://${httpConfig.host}:${httpConfig.port}${httpConfig.endpoint}`
1768
+ `[FastMCP info] server is running on HTTP Stream at ${protocol}://${httpConfig.host}:${httpConfig.port}${streamEndpoint}`
1705
1769
  );
1706
1770
  }
1707
1771
  this.#serverState = "running" /* Running */;
@@ -1751,8 +1815,9 @@ var FastMCP = class extends FastMCPEventEmitter {
1751
1815
  /**
1752
1816
  * Handles unhandled HTTP requests with health, readiness, OAuth endpoints, and custom routes
1753
1817
  */
1754
- #handleUnhandledRequest = async (req, res, isStateless = false, host, streamEndpoint) => {
1818
+ #handleUnhandledRequest = async (req, res, isStateless = false, host, streamEndpoint, basePath = "") => {
1755
1819
  const url = new URL(req.url || "", `http://${host}`);
1820
+ const basePathRelativePath = stripBasePath(url.pathname, basePath);
1756
1821
  try {
1757
1822
  const webRequest = this.#nodeRequestToWebRequest(req, url);
1758
1823
  const honoResponse = await this.#honoApp.fetch(webRequest, {
@@ -1788,9 +1853,8 @@ var FastMCP = class extends FastMCPEventEmitter {
1788
1853
  const enabled = healthConfig.enabled === void 0 ? true : healthConfig.enabled;
1789
1854
  if (enabled) {
1790
1855
  const path = _nullishCoalesce(healthConfig.path, () => ( "/health"));
1791
- const url2 = new URL(req.url || "", `http://${host}`);
1792
1856
  try {
1793
- if ((req.method === "GET" || req.method === "HEAD") && url2.pathname === path) {
1857
+ if ((req.method === "GET" || req.method === "HEAD") && url.pathname === joinPaths(basePath, path)) {
1794
1858
  res.writeHead(_nullishCoalesce(healthConfig.status, () => ( 200)), {
1795
1859
  "Content-Type": "text/plain"
1796
1860
  }).end(
@@ -1798,7 +1862,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1798
1862
  );
1799
1863
  return;
1800
1864
  }
1801
- if ((req.method === "GET" || req.method === "HEAD") && url2.pathname === "/ready") {
1865
+ if ((req.method === "GET" || req.method === "HEAD") && url.pathname === joinPaths(basePath, "/ready")) {
1802
1866
  if (isStateless) {
1803
1867
  const response = {
1804
1868
  mode: "stateless",
@@ -1835,9 +1899,13 @@ var FastMCP = class extends FastMCPEventEmitter {
1835
1899
  }
1836
1900
  }
1837
1901
  const oauthConfig = this.#options.oauth;
1838
- if (_optionalChain([oauthConfig, 'optionalAccess', _41 => _41.enabled]) && req.method === "GET") {
1902
+ if (_optionalChain([oauthConfig, 'optionalAccess', _48 => _48.enabled]) && req.method === "GET") {
1839
1903
  const url2 = new URL(req.url || "", `http://${host}`);
1840
- if (url2.pathname === "/.well-known/oauth-authorization-server" && oauthConfig.authorizationServer) {
1904
+ const authorizationServerMetadataPath = joinPaths(
1905
+ "",
1906
+ `/.well-known/oauth-authorization-server${basePath}`
1907
+ );
1908
+ if (url2.pathname === authorizationServerMetadataPath && oauthConfig.authorizationServer) {
1841
1909
  const metadata = convertObjectToSnakeCase(
1842
1910
  oauthConfig.authorizationServer
1843
1911
  );
@@ -1865,11 +1933,12 @@ var FastMCP = class extends FastMCPEventEmitter {
1865
1933
  }
1866
1934
  }
1867
1935
  }
1868
- const oauthProxy = _optionalChain([oauthConfig, 'optionalAccess', _42 => _42.proxy]);
1869
- if (oauthProxy && _optionalChain([oauthConfig, 'optionalAccess', _43 => _43.enabled])) {
1936
+ const oauthProxy = _optionalChain([oauthConfig, 'optionalAccess', _49 => _49.proxy]);
1937
+ if (oauthProxy && _optionalChain([oauthConfig, 'optionalAccess', _50 => _50.enabled])) {
1870
1938
  const url2 = new URL(req.url || "", `http://${host}`);
1939
+ const oauthPath = basePathRelativePath;
1871
1940
  try {
1872
- if (req.method === "POST" && url2.pathname === "/oauth/register") {
1941
+ if (req.method === "POST" && oauthPath === "/oauth/register") {
1873
1942
  await new Promise((resolve) => {
1874
1943
  let body = "";
1875
1944
  req.on("data", (chunk) => body += chunk);
@@ -1882,7 +1951,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1882
1951
  const statusCode = error.statusCode || 400;
1883
1952
  res.writeHead(statusCode, { "Content-Type": "application/json" }).end(
1884
1953
  JSON.stringify(
1885
- _optionalChain([error, 'access', _44 => _44.toJSON, 'optionalCall', _45 => _45()]) || {
1954
+ _optionalChain([error, 'access', _51 => _51.toJSON, 'optionalCall', _52 => _52()]) || {
1886
1955
  error: "invalid_request"
1887
1956
  }
1888
1957
  )
@@ -1893,7 +1962,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1893
1962
  });
1894
1963
  return;
1895
1964
  }
1896
- if (req.method === "GET" && url2.pathname === "/oauth/authorize") {
1965
+ if (req.method === "GET" && oauthPath === "/oauth/authorize") {
1897
1966
  try {
1898
1967
  const params = Object.fromEntries(url2.searchParams.entries());
1899
1968
  const response = await oauthProxy.authorize(
@@ -1909,7 +1978,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1909
1978
  } catch (error) {
1910
1979
  res.writeHead(400, { "Content-Type": "application/json" }).end(
1911
1980
  JSON.stringify(
1912
- _optionalChain([error, 'access', _46 => _46.toJSON, 'optionalCall', _47 => _47()]) || {
1981
+ _optionalChain([error, 'access', _53 => _53.toJSON, 'optionalCall', _54 => _54()]) || {
1913
1982
  error: "invalid_request"
1914
1983
  }
1915
1984
  )
@@ -1917,7 +1986,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1917
1986
  }
1918
1987
  return;
1919
1988
  }
1920
- if (req.method === "GET" && url2.pathname === "/oauth/callback") {
1989
+ if (req.method === "GET" && oauthPath === "/oauth/callback") {
1921
1990
  try {
1922
1991
  const mockRequest = new Request(`http://${host}${req.url}`);
1923
1992
  const response = await oauthProxy.handleCallback(mockRequest);
@@ -1931,7 +2000,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1931
2000
  } catch (error) {
1932
2001
  res.writeHead(400, { "Content-Type": "application/json" }).end(
1933
2002
  JSON.stringify(
1934
- _optionalChain([error, 'access', _48 => _48.toJSON, 'optionalCall', _49 => _49()]) || {
2003
+ _optionalChain([error, 'access', _55 => _55.toJSON, 'optionalCall', _56 => _56()]) || {
1935
2004
  error: "server_error"
1936
2005
  }
1937
2006
  )
@@ -1939,14 +2008,14 @@ var FastMCP = class extends FastMCPEventEmitter {
1939
2008
  }
1940
2009
  return;
1941
2010
  }
1942
- if (req.method === "POST" && url2.pathname === "/oauth/consent") {
2011
+ if (req.method === "POST" && oauthPath === "/oauth/consent") {
1943
2012
  await new Promise((resolve) => {
1944
2013
  let body = "";
1945
2014
  req.on("data", (chunk) => body += chunk);
1946
2015
  req.on("end", async () => {
1947
2016
  try {
1948
2017
  const mockRequest = new Request(
1949
- `http://${host}/oauth/consent`,
2018
+ `http://${host}${url2.pathname}${url2.search}`,
1950
2019
  {
1951
2020
  body,
1952
2021
  headers: {
@@ -1966,7 +2035,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1966
2035
  } catch (error) {
1967
2036
  res.writeHead(400, { "Content-Type": "application/json" }).end(
1968
2037
  JSON.stringify(
1969
- _optionalChain([error, 'access', _50 => _50.toJSON, 'optionalCall', _51 => _51()]) || {
2038
+ _optionalChain([error, 'access', _57 => _57.toJSON, 'optionalCall', _58 => _58()]) || {
1970
2039
  error: "server_error"
1971
2040
  }
1972
2041
  )
@@ -1977,7 +2046,7 @@ var FastMCP = class extends FastMCPEventEmitter {
1977
2046
  });
1978
2047
  return;
1979
2048
  }
1980
- if (req.method === "POST" && url2.pathname === "/oauth/token") {
2049
+ if (req.method === "POST" && oauthPath === "/oauth/token") {
1981
2050
  await new Promise((resolve) => {
1982
2051
  let body = "";
1983
2052
  req.on("data", (chunk) => body += chunk);
@@ -1988,8 +2057,8 @@ var FastMCP = class extends FastMCPEventEmitter {
1988
2057
  const basicAuth = parseBasicAuthHeader(
1989
2058
  req.headers.authorization
1990
2059
  );
1991
- const clientId = _optionalChain([basicAuth, 'optionalAccess', _52 => _52.clientId]) || params.get("client_id") || "";
1992
- const clientSecret = _nullishCoalesce(_nullishCoalesce(_optionalChain([basicAuth, 'optionalAccess', _53 => _53.clientSecret]), () => ( params.get("client_secret"))), () => ( void 0));
2060
+ const clientId = _optionalChain([basicAuth, 'optionalAccess', _59 => _59.clientId]) || params.get("client_id") || "";
2061
+ const clientSecret = _nullishCoalesce(_nullishCoalesce(_optionalChain([basicAuth, 'optionalAccess', _60 => _60.clientSecret]), () => ( params.get("client_secret"))), () => ( void 0));
1993
2062
  let response;
1994
2063
  if (grantType === "authorization_code") {
1995
2064
  response = await oauthProxy.exchangeAuthorizationCode({
@@ -2019,7 +2088,7 @@ var FastMCP = class extends FastMCPEventEmitter {
2019
2088
  const statusCode = error.statusCode || 400;
2020
2089
  res.writeHead(statusCode, { "Content-Type": "application/json" }).end(
2021
2090
  JSON.stringify(
2022
- _optionalChain([error, 'access', _54 => _54.toJSON, 'optionalCall', _55 => _55()]) || {
2091
+ _optionalChain([error, 'access', _61 => _61.toJSON, 'optionalCall', _62 => _62()]) || {
2023
2092
  error: "invalid_request"
2024
2093
  }
2025
2094
  )
@@ -2081,29 +2150,35 @@ var FastMCP = class extends FastMCPEventEmitter {
2081
2150
  const transportArg = getArg("transport");
2082
2151
  const portArg = getArg("port");
2083
2152
  const endpointArg = getArg("endpoint");
2153
+ const basePathArg = getArg("base-path");
2084
2154
  const statelessArg = getArg("stateless");
2085
2155
  const hostArg = getArg("host");
2086
2156
  const envTransport = process.env.FASTMCP_TRANSPORT;
2087
2157
  const envPort = process.env.FASTMCP_PORT;
2088
2158
  const envEndpoint = process.env.FASTMCP_ENDPOINT;
2159
+ const envBasePath = process.env.FASTMCP_BASE_PATH;
2089
2160
  const envStateless = process.env.FASTMCP_STATELESS;
2090
2161
  const envHost = process.env.FASTMCP_HOST;
2091
- const transportType = _optionalChain([overrides, 'optionalAccess', _56 => _56.transportType]) || (transportArg === "http-stream" ? "httpStream" : transportArg) || envTransport || "stdio";
2162
+ const transportType = _optionalChain([overrides, 'optionalAccess', _63 => _63.transportType]) || (transportArg === "http-stream" ? "httpStream" : transportArg) || envTransport || "stdio";
2092
2163
  if (transportType === "httpStream") {
2093
2164
  const port = parseInt(
2094
- _optionalChain([overrides, 'optionalAccess', _57 => _57.httpStream, 'optionalAccess', _58 => _58.port, 'optionalAccess', _59 => _59.toString, 'call', _60 => _60()]) || portArg || envPort || "8080"
2165
+ _optionalChain([overrides, 'optionalAccess', _64 => _64.httpStream, 'optionalAccess', _65 => _65.port, 'optionalAccess', _66 => _66.toString, 'call', _67 => _67()]) || portArg || envPort || "8080"
2166
+ );
2167
+ const host = _optionalChain([overrides, 'optionalAccess', _68 => _68.httpStream, 'optionalAccess', _69 => _69.host]) || hostArg || envHost || "localhost";
2168
+ const endpoint = _optionalChain([overrides, 'optionalAccess', _70 => _70.httpStream, 'optionalAccess', _71 => _71.endpoint]) || endpointArg || envEndpoint || "/mcp";
2169
+ const basePath = normalizeBasePath(
2170
+ _optionalChain([overrides, 'optionalAccess', _72 => _72.httpStream, 'optionalAccess', _73 => _73.basePath]) || basePathArg || envBasePath
2095
2171
  );
2096
- const host = _optionalChain([overrides, 'optionalAccess', _61 => _61.httpStream, 'optionalAccess', _62 => _62.host]) || hostArg || envHost || "localhost";
2097
- const endpoint = _optionalChain([overrides, 'optionalAccess', _63 => _63.httpStream, 'optionalAccess', _64 => _64.endpoint]) || endpointArg || envEndpoint || "/mcp";
2098
- const enableJsonResponse = _optionalChain([overrides, 'optionalAccess', _65 => _65.httpStream, 'optionalAccess', _66 => _66.enableJsonResponse]) || false;
2099
- const stateless = _optionalChain([overrides, 'optionalAccess', _67 => _67.httpStream, 'optionalAccess', _68 => _68.stateless]) || statelessArg === "true" || envStateless === "true" || false;
2100
- const cors = _optionalChain([overrides, 'optionalAccess', _69 => _69.httpStream, 'optionalAccess', _70 => _70.cors]);
2101
- const eventStore = _optionalChain([overrides, 'optionalAccess', _71 => _71.httpStream, 'optionalAccess', _72 => _72.eventStore]);
2102
- const sslCa = _optionalChain([overrides, 'optionalAccess', _73 => _73.httpStream, 'optionalAccess', _74 => _74.sslCa]);
2103
- const sslCert = _optionalChain([overrides, 'optionalAccess', _75 => _75.httpStream, 'optionalAccess', _76 => _76.sslCert]);
2104
- const sslKey = _optionalChain([overrides, 'optionalAccess', _77 => _77.httpStream, 'optionalAccess', _78 => _78.sslKey]);
2172
+ const enableJsonResponse = _optionalChain([overrides, 'optionalAccess', _74 => _74.httpStream, 'optionalAccess', _75 => _75.enableJsonResponse]) || false;
2173
+ const stateless = _optionalChain([overrides, 'optionalAccess', _76 => _76.httpStream, 'optionalAccess', _77 => _77.stateless]) || statelessArg === "true" || envStateless === "true" || false;
2174
+ const cors = _optionalChain([overrides, 'optionalAccess', _78 => _78.httpStream, 'optionalAccess', _79 => _79.cors]);
2175
+ const eventStore = _optionalChain([overrides, 'optionalAccess', _80 => _80.httpStream, 'optionalAccess', _81 => _81.eventStore]);
2176
+ const sslCa = _optionalChain([overrides, 'optionalAccess', _82 => _82.httpStream, 'optionalAccess', _83 => _83.sslCa]);
2177
+ const sslCert = _optionalChain([overrides, 'optionalAccess', _84 => _84.httpStream, 'optionalAccess', _85 => _85.sslCert]);
2178
+ const sslKey = _optionalChain([overrides, 'optionalAccess', _86 => _86.httpStream, 'optionalAccess', _87 => _87.sslKey]);
2105
2179
  return {
2106
2180
  httpStream: {
2181
+ basePath,
2107
2182
  cors,
2108
2183
  enableJsonResponse,
2109
2184
  endpoint,
@@ -2173,4 +2248,4 @@ var FastMCP = class extends FastMCPEventEmitter {
2173
2248
 
2174
2249
 
2175
2250
  exports.DiscoveryDocumentCache = DiscoveryDocumentCache; exports.imageContent = imageContent; exports.audioContent = audioContent; exports.UnexpectedStateError = UnexpectedStateError; exports.UserError = UserError; exports.ServerState = ServerState; exports.FastMCPSession = FastMCPSession; exports.FastMCP = FastMCP;
2176
- //# sourceMappingURL=chunk-UYG7NPM6.cjs.map
2251
+ //# sourceMappingURL=chunk-BJF2JTTE.cjs.map