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.
@@ -1794,7 +1794,7 @@ if (container && Component) {
1794
1794
  });
1795
1795
  }
1796
1796
  /**
1797
- * Mount MCP server endpoints at /mcp
1797
+ * Mount MCP server endpoints at /mcp and /sse
1798
1798
  *
1799
1799
  * Sets up the HTTP transport layer for the MCP server, creating endpoints for
1800
1800
  * Server-Sent Events (SSE) streaming, POST message handling, and DELETE session cleanup.
@@ -1808,48 +1808,65 @@ if (container && Component) {
1808
1808
  *
1809
1809
  * @example
1810
1810
  * Endpoints created:
1811
- * - GET /mcp - SSE streaming endpoint for real-time communication
1812
- * - POST /mcp - Message handling endpoint for MCP protocol messages
1813
- * - DELETE /mcp - Session cleanup endpoint
1811
+ * - GET /mcp, GET /sse - SSE streaming endpoint for real-time communication
1812
+ * - POST /mcp, POST /sse - Message handling endpoint for MCP protocol messages
1813
+ * - DELETE /mcp, DELETE /sse - Session cleanup endpoint
1814
1814
  */
1815
1815
  async mountMcp() {
1816
1816
  if (this.mcpMounted) return;
1817
1817
  const { StreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/streamableHttp.js");
1818
- const endpoint = "/mcp";
1819
1818
  const idleTimeoutMs = this.config.sessionIdleTimeoutMs ?? 3e5;
1820
1819
  const getOrCreateTransport = /* @__PURE__ */ __name(async (sessionId, isInit = false) => {
1820
+ if (isInit) {
1821
+ if (sessionId && this.sessions.has(sessionId)) {
1822
+ try {
1823
+ this.sessions.get(sessionId).transport.close();
1824
+ } catch (error) {
1825
+ }
1826
+ this.sessions.delete(sessionId);
1827
+ }
1828
+ const isProduction = this.isProductionMode();
1829
+ let allowedOrigins = this.config.allowedOrigins;
1830
+ let enableDnsRebindingProtection = false;
1831
+ if (isProduction) {
1832
+ if (allowedOrigins !== void 0) {
1833
+ enableDnsRebindingProtection = allowedOrigins.length > 0;
1834
+ }
1835
+ } else {
1836
+ allowedOrigins = void 0;
1837
+ enableDnsRebindingProtection = false;
1838
+ }
1839
+ const transport = new StreamableHTTPServerTransport({
1840
+ sessionIdGenerator: /* @__PURE__ */ __name(() => generateUUID(), "sessionIdGenerator"),
1841
+ enableJsonResponse: true,
1842
+ allowedOrigins,
1843
+ enableDnsRebindingProtection,
1844
+ onsessioninitialized: /* @__PURE__ */ __name((id) => {
1845
+ if (id) {
1846
+ this.sessions.set(id, {
1847
+ transport,
1848
+ lastAccessedAt: Date.now()
1849
+ });
1850
+ }
1851
+ }, "onsessioninitialized"),
1852
+ onsessionclosed: /* @__PURE__ */ __name((id) => {
1853
+ if (id) {
1854
+ this.sessions.delete(id);
1855
+ }
1856
+ }, "onsessionclosed")
1857
+ });
1858
+ await this.server.connect(transport);
1859
+ return transport;
1860
+ }
1821
1861
  if (sessionId && this.sessions.has(sessionId)) {
1822
1862
  const session = this.sessions.get(sessionId);
1823
1863
  session.lastAccessedAt = Date.now();
1824
1864
  return session.transport;
1825
1865
  }
1826
- if (!isInit && sessionId) {
1866
+ if (sessionId) {
1827
1867
  return null;
1828
1868
  }
1829
- if (!isInit && !sessionId) {
1830
- return null;
1831
- }
1832
- const transport = new StreamableHTTPServerTransport({
1833
- sessionIdGenerator: /* @__PURE__ */ __name(() => generateUUID(), "sessionIdGenerator"),
1834
- enableJsonResponse: true,
1835
- allowedOrigins: this.config.allowedOrigins,
1836
- enableDnsRebindingProtection: this.config.allowedOrigins !== void 0 && this.config.allowedOrigins.length > 0,
1837
- onsessioninitialized: /* @__PURE__ */ __name((id) => {
1838
- if (id) {
1839
- this.sessions.set(id, {
1840
- transport,
1841
- lastAccessedAt: Date.now()
1842
- });
1843
- }
1844
- }, "onsessioninitialized"),
1845
- onsessionclosed: /* @__PURE__ */ __name((id) => {
1846
- if (id) {
1847
- this.sessions.delete(id);
1848
- }
1849
- }, "onsessionclosed")
1850
- });
1851
- await this.server.connect(transport);
1852
- return transport;
1869
+ return null;
1853
1870
  }, "getOrCreateTransport");
1854
1871
  if (idleTimeoutMs > 0 && !this.idleCleanupInterval) {
1855
1872
  this.idleCleanupInterval = setInterval(() => {
@@ -1972,245 +1989,250 @@ if (container && Component) {
1972
1989
  }, "getResponse")
1973
1990
  };
1974
1991
  }, "createExpressLikeObjects");
1975
- this.app.post(endpoint, async (c) => {
1976
- const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
1977
- let body = {};
1978
- try {
1979
- body = await c.req.json();
1980
- expressReq.body = body;
1981
- } catch {
1982
- expressReq.body = {};
1983
- }
1984
- const isInit = body?.method === "initialize";
1985
- const sessionId = c.req.header("mcp-session-id");
1986
- const transport = await getOrCreateTransport(sessionId, isInit);
1987
- if (!transport) {
1988
- if (sessionId) {
1989
- return c.json(
1990
- {
1991
- jsonrpc: "2.0",
1992
- error: {
1993
- code: -32e3,
1994
- message: "Session not found or expired"
1995
- },
1996
- id: null
1997
- },
1998
- 404
1999
- );
2000
- } else {
2001
- return c.json(
2002
- {
2003
- jsonrpc: "2.0",
2004
- error: {
2005
- code: -32e3,
2006
- message: "Bad Request: Mcp-Session-Id header is required"
2007
- },
2008
- id: null
2009
- },
2010
- 400
2011
- );
1992
+ const mountEndpoint = /* @__PURE__ */ __name((endpoint) => {
1993
+ this.app.post(endpoint, async (c) => {
1994
+ const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
1995
+ let body = {};
1996
+ try {
1997
+ body = await c.req.json();
1998
+ expressReq.body = body;
1999
+ } catch {
2000
+ expressReq.body = {};
2012
2001
  }
2013
- }
2014
- if (sessionId && this.sessions.has(sessionId)) {
2015
- this.sessions.get(sessionId).lastAccessedAt = Date.now();
2016
- }
2017
- if (expressRes._closeHandler) {
2018
- c.req.raw.signal?.addEventListener("abort", () => {
2019
- transport.close();
2020
- });
2021
- }
2022
- await this.waitForRequestComplete(
2023
- transport,
2024
- expressReq,
2025
- expressRes,
2026
- expressReq.body
2027
- );
2028
- const response = getResponse();
2029
- if (response) {
2030
- return response;
2031
- }
2032
- return c.text("", 200);
2033
- });
2034
- this.app.get(endpoint, async (c) => {
2035
- const sessionId = c.req.header("mcp-session-id");
2036
- const transport = await getOrCreateTransport(sessionId, false);
2037
- if (!transport) {
2038
- if (sessionId) {
2039
- return c.json(
2040
- {
2041
- jsonrpc: "2.0",
2042
- error: {
2043
- code: -32e3,
2044
- message: "Session not found or expired"
2002
+ const isInit = body?.method === "initialize";
2003
+ const sessionId = c.req.header("mcp-session-id");
2004
+ const transport = await getOrCreateTransport(sessionId, isInit);
2005
+ if (!transport) {
2006
+ if (sessionId) {
2007
+ return c.json(
2008
+ {
2009
+ jsonrpc: "2.0",
2010
+ error: {
2011
+ code: -32e3,
2012
+ message: "Session not found or expired"
2013
+ },
2014
+ // Notifications don't have an id, but we include null for consistency
2015
+ id: body?.id ?? null
2045
2016
  },
2046
- id: null
2047
- },
2048
- 404
2049
- );
2050
- } else {
2051
- return c.json(
2052
- {
2053
- jsonrpc: "2.0",
2054
- error: {
2055
- code: -32e3,
2056
- message: "Bad Request: Mcp-Session-Id header is required"
2017
+ 404
2018
+ );
2019
+ } else {
2020
+ return c.json(
2021
+ {
2022
+ jsonrpc: "2.0",
2023
+ error: {
2024
+ code: -32e3,
2025
+ message: "Bad Request: Mcp-Session-Id header is required"
2026
+ },
2027
+ id: body?.id ?? null
2057
2028
  },
2058
- id: null
2059
- },
2060
- 400
2061
- );
2062
- }
2063
- }
2064
- if (sessionId && this.sessions.has(sessionId)) {
2065
- this.sessions.get(sessionId).lastAccessedAt = Date.now();
2066
- }
2067
- c.req.raw.signal?.addEventListener("abort", () => {
2068
- transport.close();
2069
- });
2070
- const { readable, writable } = new globalThis.TransformStream();
2071
- const writer = writable.getWriter();
2072
- const encoder = new TextEncoder();
2073
- let resolveResponse;
2074
- const responsePromise = new Promise((resolve) => {
2075
- resolveResponse = resolve;
2076
- });
2077
- let headersSent = false;
2078
- const headers = {};
2079
- let statusCode = 200;
2080
- const expressRes = {
2081
- statusCode: 200,
2082
- headersSent: false,
2083
- status: /* @__PURE__ */ __name((code) => {
2084
- statusCode = code;
2085
- expressRes.statusCode = code;
2086
- return expressRes;
2087
- }, "status"),
2088
- setHeader: /* @__PURE__ */ __name((name, value) => {
2089
- if (!headersSent) {
2090
- headers[name] = Array.isArray(value) ? value.join(", ") : value;
2091
- }
2092
- }, "setHeader"),
2093
- getHeader: /* @__PURE__ */ __name((name) => headers[name], "getHeader"),
2094
- write: /* @__PURE__ */ __name((chunk) => {
2095
- if (!headersSent) {
2096
- headersSent = true;
2097
- resolveResponse(
2098
- new Response(readable, {
2099
- status: statusCode,
2100
- headers
2101
- })
2029
+ 400
2102
2030
  );
2103
2031
  }
2104
- const data = typeof chunk === "string" ? encoder.encode(chunk) : chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
2105
- writer.write(data);
2106
- return true;
2107
- }, "write"),
2108
- end: /* @__PURE__ */ __name((chunk) => {
2109
- if (chunk) {
2110
- expressRes.write(chunk);
2111
- }
2112
- if (!headersSent) {
2113
- headersSent = true;
2114
- resolveResponse(
2115
- new Response(null, {
2116
- status: statusCode,
2117
- headers
2118
- })
2032
+ }
2033
+ if (sessionId && this.sessions.has(sessionId)) {
2034
+ this.sessions.get(sessionId).lastAccessedAt = Date.now();
2035
+ }
2036
+ if (expressRes._closeHandler) {
2037
+ c.req.raw.signal?.addEventListener("abort", () => {
2038
+ transport.close();
2039
+ });
2040
+ }
2041
+ await this.waitForRequestComplete(
2042
+ transport,
2043
+ expressReq,
2044
+ expressRes,
2045
+ expressReq.body
2046
+ );
2047
+ const response = getResponse();
2048
+ if (response) {
2049
+ return response;
2050
+ }
2051
+ return c.text("", 200);
2052
+ });
2053
+ this.app.get(endpoint, async (c) => {
2054
+ const sessionId = c.req.header("mcp-session-id");
2055
+ const transport = await getOrCreateTransport(sessionId, false);
2056
+ if (!transport) {
2057
+ if (sessionId) {
2058
+ return c.json(
2059
+ {
2060
+ jsonrpc: "2.0",
2061
+ error: {
2062
+ code: -32e3,
2063
+ message: "Session not found or expired"
2064
+ },
2065
+ id: null
2066
+ },
2067
+ 404
2119
2068
  );
2120
- writer.close();
2121
2069
  } else {
2122
- writer.close();
2123
- }
2124
- }, "end"),
2125
- on: /* @__PURE__ */ __name((event, handler) => {
2126
- if (event === "close") {
2127
- expressRes._closeHandler = handler;
2128
- }
2129
- }, "on"),
2130
- once: /* @__PURE__ */ __name(() => {
2131
- }, "once"),
2132
- removeListener: /* @__PURE__ */ __name(() => {
2133
- }, "removeListener"),
2134
- writeHead: /* @__PURE__ */ __name((code, _headers) => {
2135
- statusCode = code;
2136
- expressRes.statusCode = code;
2137
- if (_headers) {
2138
- Object.assign(headers, _headers);
2139
- }
2140
- if (!headersSent) {
2141
- headersSent = true;
2142
- resolveResponse(
2143
- new Response(readable, {
2144
- status: statusCode,
2145
- headers
2146
- })
2070
+ return c.json(
2071
+ {
2072
+ jsonrpc: "2.0",
2073
+ error: {
2074
+ code: -32e3,
2075
+ message: "Bad Request: Mcp-Session-Id header is required"
2076
+ },
2077
+ id: null
2078
+ },
2079
+ 400
2147
2080
  );
2148
2081
  }
2149
- return expressRes;
2150
- }, "writeHead"),
2151
- flushHeaders: /* @__PURE__ */ __name(() => {
2152
- }, "flushHeaders")
2153
- };
2154
- const expressReq = {
2155
- ...c.req.raw,
2156
- url: new URL(c.req.url).pathname + new URL(c.req.url).search,
2157
- path: new URL(c.req.url).pathname,
2158
- query: Object.fromEntries(new URL(c.req.url).searchParams),
2159
- headers: c.req.header(),
2160
- method: c.req.method
2161
- };
2162
- transport.handleRequest(expressReq, expressRes).catch((err) => {
2163
- console.error("MCP Transport error:", err);
2164
- try {
2165
- writer.close();
2166
- } catch {
2167
2082
  }
2083
+ if (sessionId && this.sessions.has(sessionId)) {
2084
+ this.sessions.get(sessionId).lastAccessedAt = Date.now();
2085
+ }
2086
+ c.req.raw.signal?.addEventListener("abort", () => {
2087
+ transport.close();
2088
+ });
2089
+ const { readable, writable } = new globalThis.TransformStream();
2090
+ const writer = writable.getWriter();
2091
+ const encoder = new TextEncoder();
2092
+ let resolveResponse;
2093
+ const responsePromise = new Promise((resolve) => {
2094
+ resolveResponse = resolve;
2095
+ });
2096
+ let headersSent = false;
2097
+ const headers = {};
2098
+ let statusCode = 200;
2099
+ const expressRes = {
2100
+ statusCode: 200,
2101
+ headersSent: false,
2102
+ status: /* @__PURE__ */ __name((code) => {
2103
+ statusCode = code;
2104
+ expressRes.statusCode = code;
2105
+ return expressRes;
2106
+ }, "status"),
2107
+ setHeader: /* @__PURE__ */ __name((name, value) => {
2108
+ if (!headersSent) {
2109
+ headers[name] = Array.isArray(value) ? value.join(", ") : value;
2110
+ }
2111
+ }, "setHeader"),
2112
+ getHeader: /* @__PURE__ */ __name((name) => headers[name], "getHeader"),
2113
+ write: /* @__PURE__ */ __name((chunk) => {
2114
+ if (!headersSent) {
2115
+ headersSent = true;
2116
+ resolveResponse(
2117
+ new Response(readable, {
2118
+ status: statusCode,
2119
+ headers
2120
+ })
2121
+ );
2122
+ }
2123
+ const data = typeof chunk === "string" ? encoder.encode(chunk) : chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
2124
+ writer.write(data);
2125
+ return true;
2126
+ }, "write"),
2127
+ end: /* @__PURE__ */ __name((chunk) => {
2128
+ if (chunk) {
2129
+ expressRes.write(chunk);
2130
+ }
2131
+ if (!headersSent) {
2132
+ headersSent = true;
2133
+ resolveResponse(
2134
+ new Response(null, {
2135
+ status: statusCode,
2136
+ headers
2137
+ })
2138
+ );
2139
+ writer.close();
2140
+ } else {
2141
+ writer.close();
2142
+ }
2143
+ }, "end"),
2144
+ on: /* @__PURE__ */ __name((event, handler) => {
2145
+ if (event === "close") {
2146
+ expressRes._closeHandler = handler;
2147
+ }
2148
+ }, "on"),
2149
+ once: /* @__PURE__ */ __name(() => {
2150
+ }, "once"),
2151
+ removeListener: /* @__PURE__ */ __name(() => {
2152
+ }, "removeListener"),
2153
+ writeHead: /* @__PURE__ */ __name((code, _headers) => {
2154
+ statusCode = code;
2155
+ expressRes.statusCode = code;
2156
+ if (_headers) {
2157
+ Object.assign(headers, _headers);
2158
+ }
2159
+ if (!headersSent) {
2160
+ headersSent = true;
2161
+ resolveResponse(
2162
+ new Response(readable, {
2163
+ status: statusCode,
2164
+ headers
2165
+ })
2166
+ );
2167
+ }
2168
+ return expressRes;
2169
+ }, "writeHead"),
2170
+ flushHeaders: /* @__PURE__ */ __name(() => {
2171
+ }, "flushHeaders")
2172
+ };
2173
+ const expressReq = {
2174
+ ...c.req.raw,
2175
+ url: new URL(c.req.url).pathname + new URL(c.req.url).search,
2176
+ path: new URL(c.req.url).pathname,
2177
+ query: Object.fromEntries(new URL(c.req.url).searchParams),
2178
+ headers: c.req.header(),
2179
+ method: c.req.method
2180
+ };
2181
+ transport.handleRequest(expressReq, expressRes).catch((err) => {
2182
+ console.error("MCP Transport error:", err);
2183
+ try {
2184
+ writer.close();
2185
+ } catch {
2186
+ }
2187
+ });
2188
+ return responsePromise;
2168
2189
  });
2169
- return responsePromise;
2170
- });
2171
- this.app.delete(endpoint, async (c) => {
2172
- const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
2173
- const sessionId = c.req.header("mcp-session-id");
2174
- const transport = await getOrCreateTransport(sessionId, false);
2175
- if (!transport) {
2176
- if (sessionId) {
2177
- return c.json(
2178
- {
2179
- jsonrpc: "2.0",
2180
- error: {
2181
- code: -32e3,
2182
- message: "Session not found or expired"
2190
+ this.app.delete(endpoint, async (c) => {
2191
+ const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
2192
+ const sessionId = c.req.header("mcp-session-id");
2193
+ const transport = await getOrCreateTransport(sessionId, false);
2194
+ if (!transport) {
2195
+ if (sessionId) {
2196
+ return c.json(
2197
+ {
2198
+ jsonrpc: "2.0",
2199
+ error: {
2200
+ code: -32e3,
2201
+ message: "Session not found or expired"
2202
+ },
2203
+ id: null
2183
2204
  },
2184
- id: null
2185
- },
2186
- 404
2187
- );
2188
- } else {
2189
- return c.json(
2190
- {
2191
- jsonrpc: "2.0",
2192
- error: {
2193
- code: -32e3,
2194
- message: "Bad Request: Mcp-Session-Id header is required"
2205
+ 404
2206
+ );
2207
+ } else {
2208
+ return c.json(
2209
+ {
2210
+ jsonrpc: "2.0",
2211
+ error: {
2212
+ code: -32e3,
2213
+ message: "Bad Request: Mcp-Session-Id header is required"
2214
+ },
2215
+ id: null
2195
2216
  },
2196
- id: null
2197
- },
2198
- 400
2199
- );
2217
+ 400
2218
+ );
2219
+ }
2200
2220
  }
2201
- }
2202
- c.req.raw.signal?.addEventListener("abort", () => {
2203
- transport.close();
2221
+ c.req.raw.signal?.addEventListener("abort", () => {
2222
+ transport.close();
2223
+ });
2224
+ await this.waitForRequestComplete(transport, expressReq, expressRes);
2225
+ const response = getResponse();
2226
+ if (response) {
2227
+ return response;
2228
+ }
2229
+ return c.text("", 200);
2204
2230
  });
2205
- await this.waitForRequestComplete(transport, expressReq, expressRes);
2206
- const response = getResponse();
2207
- if (response) {
2208
- return response;
2209
- }
2210
- return c.text("", 200);
2211
- });
2231
+ }, "mountEndpoint");
2232
+ mountEndpoint("/mcp");
2233
+ mountEndpoint("/sse");
2212
2234
  this.mcpMounted = true;
2213
- console.log(`[MCP] Server mounted at ${endpoint}`);
2235
+ console.log(`[MCP] Server mounted at /mcp and /sse`);
2214
2236
  }
2215
2237
  /**
2216
2238
  * Start the Hono server with MCP endpoints
@@ -2219,7 +2241,7 @@ if (container && Component) {
2219
2241
  * the inspector UI (if available), and starting the server to listen
2220
2242
  * for incoming connections. This is the main entry point for running the server.
2221
2243
  *
2222
- * The server will be accessible at the specified port with MCP endpoints at /mcp
2244
+ * The server will be accessible at the specified port with MCP endpoints at /mcp and /sse
2223
2245
  * and inspector UI at /inspector (if the inspector package is installed).
2224
2246
  *
2225
2247
  * @param port - Port number to listen on (defaults to 3001 if not specified)
@@ -2229,7 +2251,7 @@ if (container && Component) {
2229
2251
  * ```typescript
2230
2252
  * await server.listen(8080)
2231
2253
  * // Server now running at http://localhost:8080 (or configured host)
2232
- * // MCP endpoints: http://localhost:8080/mcp
2254
+ * // MCP endpoints: http://localhost:8080/mcp and http://localhost:8080/sse
2233
2255
  * // Inspector UI: http://localhost:8080/inspector
2234
2256
  * ```
2235
2257
  */
@@ -2333,7 +2355,7 @@ if (container && Component) {
2333
2355
  `[SERVER] Listening on http://${this.serverHost}:${this.serverPort}`
2334
2356
  );
2335
2357
  console.log(
2336
- `[MCP] Endpoints: http://${this.serverHost}:${this.serverPort}/mcp`
2358
+ `[MCP] Endpoints: http://${this.serverHost}:${this.serverPort}/mcp and http://${this.serverHost}:${this.serverPort}/sse`
2337
2359
  );
2338
2360
  }
2339
2361
  );
@@ -2619,7 +2641,7 @@ if (container && Component) {
2619
2641
  * @example
2620
2642
  * If @mcp-use/inspector is installed:
2621
2643
  * - Inspector UI available at http://localhost:PORT/inspector
2622
- * - Automatically connects to http://localhost:PORT/mcp
2644
+ * - Automatically connects to http://localhost:PORT/mcp (or /sse)
2623
2645
  *
2624
2646
  * If not installed:
2625
2647
  * - Server continues to function normally
@@ -2969,7 +2991,9 @@ function createMCPServer(name, config = {}) {
2969
2991
  version: config.version || "1.0.0",
2970
2992
  description: config.description,
2971
2993
  host: config.host,
2972
- baseUrl: config.baseUrl
2994
+ baseUrl: config.baseUrl,
2995
+ allowedOrigins: config.allowedOrigins,
2996
+ sessionIdleTimeoutMs: config.sessionIdleTimeoutMs
2973
2997
  });
2974
2998
  return instance;
2975
2999
  }