mcp-use 1.5.0-canary.5 → 1.5.0-canary.7

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.
@@ -1756,7 +1756,7 @@ if (container && Component) {
1756
1756
  });
1757
1757
  }
1758
1758
  /**
1759
- * Mount MCP server endpoints at /mcp
1759
+ * Mount MCP server endpoints at /mcp and /sse
1760
1760
  *
1761
1761
  * Sets up the HTTP transport layer for the MCP server, creating endpoints for
1762
1762
  * Server-Sent Events (SSE) streaming, POST message handling, and DELETE session cleanup.
@@ -1770,48 +1770,65 @@ if (container && Component) {
1770
1770
  *
1771
1771
  * @example
1772
1772
  * Endpoints created:
1773
- * - GET /mcp - SSE streaming endpoint for real-time communication
1774
- * - POST /mcp - Message handling endpoint for MCP protocol messages
1775
- * - DELETE /mcp - Session cleanup endpoint
1773
+ * - GET /mcp, GET /sse - SSE streaming endpoint for real-time communication
1774
+ * - POST /mcp, POST /sse - Message handling endpoint for MCP protocol messages
1775
+ * - DELETE /mcp, DELETE /sse - Session cleanup endpoint
1776
1776
  */
1777
1777
  async mountMcp() {
1778
1778
  if (this.mcpMounted) return;
1779
1779
  const { StreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/streamableHttp.js");
1780
- const endpoint = "/mcp";
1781
1780
  const idleTimeoutMs = this.config.sessionIdleTimeoutMs ?? 3e5;
1782
1781
  const getOrCreateTransport = /* @__PURE__ */ __name(async (sessionId, isInit = false) => {
1782
+ if (isInit) {
1783
+ if (sessionId && this.sessions.has(sessionId)) {
1784
+ try {
1785
+ this.sessions.get(sessionId).transport.close();
1786
+ } catch (error) {
1787
+ }
1788
+ this.sessions.delete(sessionId);
1789
+ }
1790
+ const isProduction = this.isProductionMode();
1791
+ let allowedOrigins = this.config.allowedOrigins;
1792
+ let enableDnsRebindingProtection = false;
1793
+ if (isProduction) {
1794
+ if (allowedOrigins !== void 0) {
1795
+ enableDnsRebindingProtection = allowedOrigins.length > 0;
1796
+ }
1797
+ } else {
1798
+ allowedOrigins = void 0;
1799
+ enableDnsRebindingProtection = false;
1800
+ }
1801
+ const transport = new StreamableHTTPServerTransport({
1802
+ sessionIdGenerator: /* @__PURE__ */ __name(() => generateUUID(), "sessionIdGenerator"),
1803
+ enableJsonResponse: true,
1804
+ allowedOrigins,
1805
+ enableDnsRebindingProtection,
1806
+ onsessioninitialized: /* @__PURE__ */ __name((id) => {
1807
+ if (id) {
1808
+ this.sessions.set(id, {
1809
+ transport,
1810
+ lastAccessedAt: Date.now()
1811
+ });
1812
+ }
1813
+ }, "onsessioninitialized"),
1814
+ onsessionclosed: /* @__PURE__ */ __name((id) => {
1815
+ if (id) {
1816
+ this.sessions.delete(id);
1817
+ }
1818
+ }, "onsessionclosed")
1819
+ });
1820
+ await this.server.connect(transport);
1821
+ return transport;
1822
+ }
1783
1823
  if (sessionId && this.sessions.has(sessionId)) {
1784
1824
  const session = this.sessions.get(sessionId);
1785
1825
  session.lastAccessedAt = Date.now();
1786
1826
  return session.transport;
1787
1827
  }
1788
- if (!isInit && sessionId) {
1828
+ if (sessionId) {
1789
1829
  return null;
1790
1830
  }
1791
- if (!isInit && !sessionId) {
1792
- return null;
1793
- }
1794
- const transport = new StreamableHTTPServerTransport({
1795
- sessionIdGenerator: /* @__PURE__ */ __name(() => generateUUID(), "sessionIdGenerator"),
1796
- enableJsonResponse: true,
1797
- allowedOrigins: this.config.allowedOrigins,
1798
- enableDnsRebindingProtection: this.config.allowedOrigins !== void 0 && this.config.allowedOrigins.length > 0,
1799
- onsessioninitialized: /* @__PURE__ */ __name((id) => {
1800
- if (id) {
1801
- this.sessions.set(id, {
1802
- transport,
1803
- lastAccessedAt: Date.now()
1804
- });
1805
- }
1806
- }, "onsessioninitialized"),
1807
- onsessionclosed: /* @__PURE__ */ __name((id) => {
1808
- if (id) {
1809
- this.sessions.delete(id);
1810
- }
1811
- }, "onsessionclosed")
1812
- });
1813
- await this.server.connect(transport);
1814
- return transport;
1831
+ return null;
1815
1832
  }, "getOrCreateTransport");
1816
1833
  if (idleTimeoutMs > 0 && !this.idleCleanupInterval) {
1817
1834
  this.idleCleanupInterval = setInterval(() => {
@@ -1934,245 +1951,250 @@ if (container && Component) {
1934
1951
  }, "getResponse")
1935
1952
  };
1936
1953
  }, "createExpressLikeObjects");
1937
- this.app.post(endpoint, async (c) => {
1938
- const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
1939
- let body = {};
1940
- try {
1941
- body = await c.req.json();
1942
- expressReq.body = body;
1943
- } catch {
1944
- expressReq.body = {};
1945
- }
1946
- const isInit = body?.method === "initialize";
1947
- const sessionId = c.req.header("mcp-session-id");
1948
- const transport = await getOrCreateTransport(sessionId, isInit);
1949
- if (!transport) {
1950
- if (sessionId) {
1951
- return c.json(
1952
- {
1953
- jsonrpc: "2.0",
1954
- error: {
1955
- code: -32e3,
1956
- message: "Session not found or expired"
1957
- },
1958
- id: null
1959
- },
1960
- 404
1961
- );
1962
- } else {
1963
- return c.json(
1964
- {
1965
- jsonrpc: "2.0",
1966
- error: {
1967
- code: -32e3,
1968
- message: "Bad Request: Mcp-Session-Id header is required"
1969
- },
1970
- id: null
1971
- },
1972
- 400
1973
- );
1954
+ const mountEndpoint = /* @__PURE__ */ __name((endpoint) => {
1955
+ this.app.post(endpoint, async (c) => {
1956
+ const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
1957
+ let body = {};
1958
+ try {
1959
+ body = await c.req.json();
1960
+ expressReq.body = body;
1961
+ } catch {
1962
+ expressReq.body = {};
1974
1963
  }
1975
- }
1976
- if (sessionId && this.sessions.has(sessionId)) {
1977
- this.sessions.get(sessionId).lastAccessedAt = Date.now();
1978
- }
1979
- if (expressRes._closeHandler) {
1980
- c.req.raw.signal?.addEventListener("abort", () => {
1981
- transport.close();
1982
- });
1983
- }
1984
- await this.waitForRequestComplete(
1985
- transport,
1986
- expressReq,
1987
- expressRes,
1988
- expressReq.body
1989
- );
1990
- const response = getResponse();
1991
- if (response) {
1992
- return response;
1993
- }
1994
- return c.text("", 200);
1995
- });
1996
- this.app.get(endpoint, async (c) => {
1997
- const sessionId = c.req.header("mcp-session-id");
1998
- const transport = await getOrCreateTransport(sessionId, false);
1999
- if (!transport) {
2000
- if (sessionId) {
2001
- return c.json(
2002
- {
2003
- jsonrpc: "2.0",
2004
- error: {
2005
- code: -32e3,
2006
- message: "Session not found or expired"
1964
+ const isInit = body?.method === "initialize";
1965
+ const sessionId = c.req.header("mcp-session-id");
1966
+ const transport = await getOrCreateTransport(sessionId, isInit);
1967
+ if (!transport) {
1968
+ if (sessionId) {
1969
+ return c.json(
1970
+ {
1971
+ jsonrpc: "2.0",
1972
+ error: {
1973
+ code: -32e3,
1974
+ message: "Session not found or expired"
1975
+ },
1976
+ // Notifications don't have an id, but we include null for consistency
1977
+ id: body?.id ?? null
2007
1978
  },
2008
- id: null
2009
- },
2010
- 404
2011
- );
2012
- } else {
2013
- return c.json(
2014
- {
2015
- jsonrpc: "2.0",
2016
- error: {
2017
- code: -32e3,
2018
- message: "Bad Request: Mcp-Session-Id header is required"
1979
+ 404
1980
+ );
1981
+ } else {
1982
+ return c.json(
1983
+ {
1984
+ jsonrpc: "2.0",
1985
+ error: {
1986
+ code: -32e3,
1987
+ message: "Bad Request: Mcp-Session-Id header is required"
1988
+ },
1989
+ id: body?.id ?? null
2019
1990
  },
2020
- id: null
2021
- },
2022
- 400
2023
- );
2024
- }
2025
- }
2026
- if (sessionId && this.sessions.has(sessionId)) {
2027
- this.sessions.get(sessionId).lastAccessedAt = Date.now();
2028
- }
2029
- c.req.raw.signal?.addEventListener("abort", () => {
2030
- transport.close();
2031
- });
2032
- const { readable, writable } = new globalThis.TransformStream();
2033
- const writer = writable.getWriter();
2034
- const encoder = new TextEncoder();
2035
- let resolveResponse;
2036
- const responsePromise = new Promise((resolve) => {
2037
- resolveResponse = resolve;
2038
- });
2039
- let headersSent = false;
2040
- const headers = {};
2041
- let statusCode = 200;
2042
- const expressRes = {
2043
- statusCode: 200,
2044
- headersSent: false,
2045
- status: /* @__PURE__ */ __name((code) => {
2046
- statusCode = code;
2047
- expressRes.statusCode = code;
2048
- return expressRes;
2049
- }, "status"),
2050
- setHeader: /* @__PURE__ */ __name((name, value) => {
2051
- if (!headersSent) {
2052
- headers[name] = Array.isArray(value) ? value.join(", ") : value;
2053
- }
2054
- }, "setHeader"),
2055
- getHeader: /* @__PURE__ */ __name((name) => headers[name], "getHeader"),
2056
- write: /* @__PURE__ */ __name((chunk) => {
2057
- if (!headersSent) {
2058
- headersSent = true;
2059
- resolveResponse(
2060
- new Response(readable, {
2061
- status: statusCode,
2062
- headers
2063
- })
1991
+ 400
2064
1992
  );
2065
1993
  }
2066
- const data = typeof chunk === "string" ? encoder.encode(chunk) : chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
2067
- writer.write(data);
2068
- return true;
2069
- }, "write"),
2070
- end: /* @__PURE__ */ __name((chunk) => {
2071
- if (chunk) {
2072
- expressRes.write(chunk);
2073
- }
2074
- if (!headersSent) {
2075
- headersSent = true;
2076
- resolveResponse(
2077
- new Response(null, {
2078
- status: statusCode,
2079
- headers
2080
- })
1994
+ }
1995
+ if (sessionId && this.sessions.has(sessionId)) {
1996
+ this.sessions.get(sessionId).lastAccessedAt = Date.now();
1997
+ }
1998
+ if (expressRes._closeHandler) {
1999
+ c.req.raw.signal?.addEventListener("abort", () => {
2000
+ transport.close();
2001
+ });
2002
+ }
2003
+ await this.waitForRequestComplete(
2004
+ transport,
2005
+ expressReq,
2006
+ expressRes,
2007
+ expressReq.body
2008
+ );
2009
+ const response = getResponse();
2010
+ if (response) {
2011
+ return response;
2012
+ }
2013
+ return c.text("", 200);
2014
+ });
2015
+ this.app.get(endpoint, async (c) => {
2016
+ const sessionId = c.req.header("mcp-session-id");
2017
+ const transport = await getOrCreateTransport(sessionId, false);
2018
+ if (!transport) {
2019
+ if (sessionId) {
2020
+ return c.json(
2021
+ {
2022
+ jsonrpc: "2.0",
2023
+ error: {
2024
+ code: -32e3,
2025
+ message: "Session not found or expired"
2026
+ },
2027
+ id: null
2028
+ },
2029
+ 404
2081
2030
  );
2082
- writer.close();
2083
2031
  } else {
2084
- writer.close();
2085
- }
2086
- }, "end"),
2087
- on: /* @__PURE__ */ __name((event, handler) => {
2088
- if (event === "close") {
2089
- expressRes._closeHandler = handler;
2090
- }
2091
- }, "on"),
2092
- once: /* @__PURE__ */ __name(() => {
2093
- }, "once"),
2094
- removeListener: /* @__PURE__ */ __name(() => {
2095
- }, "removeListener"),
2096
- writeHead: /* @__PURE__ */ __name((code, _headers) => {
2097
- statusCode = code;
2098
- expressRes.statusCode = code;
2099
- if (_headers) {
2100
- Object.assign(headers, _headers);
2101
- }
2102
- if (!headersSent) {
2103
- headersSent = true;
2104
- resolveResponse(
2105
- new Response(readable, {
2106
- status: statusCode,
2107
- headers
2108
- })
2032
+ return c.json(
2033
+ {
2034
+ jsonrpc: "2.0",
2035
+ error: {
2036
+ code: -32e3,
2037
+ message: "Bad Request: Mcp-Session-Id header is required"
2038
+ },
2039
+ id: null
2040
+ },
2041
+ 400
2109
2042
  );
2110
2043
  }
2111
- return expressRes;
2112
- }, "writeHead"),
2113
- flushHeaders: /* @__PURE__ */ __name(() => {
2114
- }, "flushHeaders")
2115
- };
2116
- const expressReq = {
2117
- ...c.req.raw,
2118
- url: new URL(c.req.url).pathname + new URL(c.req.url).search,
2119
- path: new URL(c.req.url).pathname,
2120
- query: Object.fromEntries(new URL(c.req.url).searchParams),
2121
- headers: c.req.header(),
2122
- method: c.req.method
2123
- };
2124
- transport.handleRequest(expressReq, expressRes).catch((err) => {
2125
- console.error("MCP Transport error:", err);
2126
- try {
2127
- writer.close();
2128
- } catch {
2129
2044
  }
2045
+ if (sessionId && this.sessions.has(sessionId)) {
2046
+ this.sessions.get(sessionId).lastAccessedAt = Date.now();
2047
+ }
2048
+ c.req.raw.signal?.addEventListener("abort", () => {
2049
+ transport.close();
2050
+ });
2051
+ const { readable, writable } = new globalThis.TransformStream();
2052
+ const writer = writable.getWriter();
2053
+ const encoder = new TextEncoder();
2054
+ let resolveResponse;
2055
+ const responsePromise = new Promise((resolve) => {
2056
+ resolveResponse = resolve;
2057
+ });
2058
+ let headersSent = false;
2059
+ const headers = {};
2060
+ let statusCode = 200;
2061
+ const expressRes = {
2062
+ statusCode: 200,
2063
+ headersSent: false,
2064
+ status: /* @__PURE__ */ __name((code) => {
2065
+ statusCode = code;
2066
+ expressRes.statusCode = code;
2067
+ return expressRes;
2068
+ }, "status"),
2069
+ setHeader: /* @__PURE__ */ __name((name, value) => {
2070
+ if (!headersSent) {
2071
+ headers[name] = Array.isArray(value) ? value.join(", ") : value;
2072
+ }
2073
+ }, "setHeader"),
2074
+ getHeader: /* @__PURE__ */ __name((name) => headers[name], "getHeader"),
2075
+ write: /* @__PURE__ */ __name((chunk) => {
2076
+ if (!headersSent) {
2077
+ headersSent = true;
2078
+ resolveResponse(
2079
+ new Response(readable, {
2080
+ status: statusCode,
2081
+ headers
2082
+ })
2083
+ );
2084
+ }
2085
+ const data = typeof chunk === "string" ? encoder.encode(chunk) : chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
2086
+ writer.write(data);
2087
+ return true;
2088
+ }, "write"),
2089
+ end: /* @__PURE__ */ __name((chunk) => {
2090
+ if (chunk) {
2091
+ expressRes.write(chunk);
2092
+ }
2093
+ if (!headersSent) {
2094
+ headersSent = true;
2095
+ resolveResponse(
2096
+ new Response(null, {
2097
+ status: statusCode,
2098
+ headers
2099
+ })
2100
+ );
2101
+ writer.close();
2102
+ } else {
2103
+ writer.close();
2104
+ }
2105
+ }, "end"),
2106
+ on: /* @__PURE__ */ __name((event, handler) => {
2107
+ if (event === "close") {
2108
+ expressRes._closeHandler = handler;
2109
+ }
2110
+ }, "on"),
2111
+ once: /* @__PURE__ */ __name(() => {
2112
+ }, "once"),
2113
+ removeListener: /* @__PURE__ */ __name(() => {
2114
+ }, "removeListener"),
2115
+ writeHead: /* @__PURE__ */ __name((code, _headers) => {
2116
+ statusCode = code;
2117
+ expressRes.statusCode = code;
2118
+ if (_headers) {
2119
+ Object.assign(headers, _headers);
2120
+ }
2121
+ if (!headersSent) {
2122
+ headersSent = true;
2123
+ resolveResponse(
2124
+ new Response(readable, {
2125
+ status: statusCode,
2126
+ headers
2127
+ })
2128
+ );
2129
+ }
2130
+ return expressRes;
2131
+ }, "writeHead"),
2132
+ flushHeaders: /* @__PURE__ */ __name(() => {
2133
+ }, "flushHeaders")
2134
+ };
2135
+ const expressReq = {
2136
+ ...c.req.raw,
2137
+ url: new URL(c.req.url).pathname + new URL(c.req.url).search,
2138
+ path: new URL(c.req.url).pathname,
2139
+ query: Object.fromEntries(new URL(c.req.url).searchParams),
2140
+ headers: c.req.header(),
2141
+ method: c.req.method
2142
+ };
2143
+ transport.handleRequest(expressReq, expressRes).catch((err) => {
2144
+ console.error("MCP Transport error:", err);
2145
+ try {
2146
+ writer.close();
2147
+ } catch {
2148
+ }
2149
+ });
2150
+ return responsePromise;
2130
2151
  });
2131
- return responsePromise;
2132
- });
2133
- this.app.delete(endpoint, async (c) => {
2134
- const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
2135
- const sessionId = c.req.header("mcp-session-id");
2136
- const transport = await getOrCreateTransport(sessionId, false);
2137
- if (!transport) {
2138
- if (sessionId) {
2139
- return c.json(
2140
- {
2141
- jsonrpc: "2.0",
2142
- error: {
2143
- code: -32e3,
2144
- message: "Session not found or expired"
2152
+ this.app.delete(endpoint, async (c) => {
2153
+ const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
2154
+ const sessionId = c.req.header("mcp-session-id");
2155
+ const transport = await getOrCreateTransport(sessionId, false);
2156
+ if (!transport) {
2157
+ if (sessionId) {
2158
+ return c.json(
2159
+ {
2160
+ jsonrpc: "2.0",
2161
+ error: {
2162
+ code: -32e3,
2163
+ message: "Session not found or expired"
2164
+ },
2165
+ id: null
2145
2166
  },
2146
- id: null
2147
- },
2148
- 404
2149
- );
2150
- } else {
2151
- return c.json(
2152
- {
2153
- jsonrpc: "2.0",
2154
- error: {
2155
- code: -32e3,
2156
- message: "Bad Request: Mcp-Session-Id header is required"
2167
+ 404
2168
+ );
2169
+ } else {
2170
+ return c.json(
2171
+ {
2172
+ jsonrpc: "2.0",
2173
+ error: {
2174
+ code: -32e3,
2175
+ message: "Bad Request: Mcp-Session-Id header is required"
2176
+ },
2177
+ id: null
2157
2178
  },
2158
- id: null
2159
- },
2160
- 400
2161
- );
2179
+ 400
2180
+ );
2181
+ }
2162
2182
  }
2163
- }
2164
- c.req.raw.signal?.addEventListener("abort", () => {
2165
- transport.close();
2183
+ c.req.raw.signal?.addEventListener("abort", () => {
2184
+ transport.close();
2185
+ });
2186
+ await this.waitForRequestComplete(transport, expressReq, expressRes);
2187
+ const response = getResponse();
2188
+ if (response) {
2189
+ return response;
2190
+ }
2191
+ return c.text("", 200);
2166
2192
  });
2167
- await this.waitForRequestComplete(transport, expressReq, expressRes);
2168
- const response = getResponse();
2169
- if (response) {
2170
- return response;
2171
- }
2172
- return c.text("", 200);
2173
- });
2193
+ }, "mountEndpoint");
2194
+ mountEndpoint("/mcp");
2195
+ mountEndpoint("/sse");
2174
2196
  this.mcpMounted = true;
2175
- console.log(`[MCP] Server mounted at ${endpoint}`);
2197
+ console.log(`[MCP] Server mounted at /mcp and /sse`);
2176
2198
  }
2177
2199
  /**
2178
2200
  * Start the Hono server with MCP endpoints
@@ -2181,7 +2203,7 @@ if (container && Component) {
2181
2203
  * the inspector UI (if available), and starting the server to listen
2182
2204
  * for incoming connections. This is the main entry point for running the server.
2183
2205
  *
2184
- * The server will be accessible at the specified port with MCP endpoints at /mcp
2206
+ * The server will be accessible at the specified port with MCP endpoints at /mcp and /sse
2185
2207
  * and inspector UI at /inspector (if the inspector package is installed).
2186
2208
  *
2187
2209
  * @param port - Port number to listen on (defaults to 3001 if not specified)
@@ -2191,7 +2213,7 @@ if (container && Component) {
2191
2213
  * ```typescript
2192
2214
  * await server.listen(8080)
2193
2215
  * // Server now running at http://localhost:8080 (or configured host)
2194
- * // MCP endpoints: http://localhost:8080/mcp
2216
+ * // MCP endpoints: http://localhost:8080/mcp and http://localhost:8080/sse
2195
2217
  * // Inspector UI: http://localhost:8080/inspector
2196
2218
  * ```
2197
2219
  */
@@ -2295,7 +2317,7 @@ if (container && Component) {
2295
2317
  `[SERVER] Listening on http://${this.serverHost}:${this.serverPort}`
2296
2318
  );
2297
2319
  console.log(
2298
- `[MCP] Endpoints: http://${this.serverHost}:${this.serverPort}/mcp`
2320
+ `[MCP] Endpoints: http://${this.serverHost}:${this.serverPort}/mcp and http://${this.serverHost}:${this.serverPort}/sse`
2299
2321
  );
2300
2322
  }
2301
2323
  );
@@ -2581,7 +2603,7 @@ if (container && Component) {
2581
2603
  * @example
2582
2604
  * If @mcp-use/inspector is installed:
2583
2605
  * - Inspector UI available at http://localhost:PORT/inspector
2584
- * - Automatically connects to http://localhost:PORT/mcp
2606
+ * - Automatically connects to http://localhost:PORT/mcp (or /sse)
2585
2607
  *
2586
2608
  * If not installed:
2587
2609
  * - Server continues to function normally
@@ -2931,7 +2953,9 @@ function createMCPServer(name, config = {}) {
2931
2953
  version: config.version || "1.0.0",
2932
2954
  description: config.description,
2933
2955
  host: config.host,
2934
- baseUrl: config.baseUrl
2956
+ baseUrl: config.baseUrl,
2957
+ allowedOrigins: config.allowedOrigins,
2958
+ sessionIdleTimeoutMs: config.sessionIdleTimeoutMs
2935
2959
  });
2936
2960
  return instance;
2937
2961
  }