mcp-use 1.7.2 → 1.8.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.
@@ -1148,39 +1148,45 @@ function createAppsSdkResource(uri, htmlTemplate, metadata) {
1148
1148
  };
1149
1149
  }
1150
1150
  __name(createAppsSdkResource, "createAppsSdkResource");
1151
- function createUIResourceFromDefinition(definition, params, config) {
1151
+ async function createUIResourceFromDefinition(definition, params, config) {
1152
1152
  const buildIdPart = config.buildId ? `-${config.buildId}` : "";
1153
1153
  const uri = definition.type === "appsSdk" ? `ui://widget/${definition.name}${buildIdPart}.html` : `ui://widget/${definition.name}${buildIdPart}`;
1154
1154
  const encoding = definition.encoding || "text";
1155
1155
  switch (definition.type) {
1156
1156
  case "externalUrl": {
1157
1157
  const widgetUrl = buildWidgetUrl(definition.widget, params, config);
1158
- return createExternalUrlResource(
1159
- uri,
1160
- widgetUrl,
1161
- encoding,
1162
- definition.adapters,
1163
- definition.appsSdkMetadata
1158
+ return await Promise.resolve(
1159
+ createExternalUrlResource(
1160
+ uri,
1161
+ widgetUrl,
1162
+ encoding,
1163
+ definition.adapters,
1164
+ definition.appsSdkMetadata
1165
+ )
1164
1166
  );
1165
1167
  }
1166
1168
  case "rawHtml": {
1167
- return createRawHtmlResource(
1168
- uri,
1169
- definition.htmlContent,
1170
- encoding,
1171
- definition.adapters,
1172
- definition.appsSdkMetadata
1169
+ return await Promise.resolve(
1170
+ createRawHtmlResource(
1171
+ uri,
1172
+ definition.htmlContent,
1173
+ encoding,
1174
+ definition.adapters,
1175
+ definition.appsSdkMetadata
1176
+ )
1173
1177
  );
1174
1178
  }
1175
1179
  case "remoteDom": {
1176
1180
  const framework = definition.framework || "react";
1177
- return createRemoteDomResource(
1178
- uri,
1179
- definition.script,
1180
- framework,
1181
- encoding,
1182
- definition.adapters,
1183
- definition.appsSdkMetadata
1181
+ return await Promise.resolve(
1182
+ createRemoteDomResource(
1183
+ uri,
1184
+ definition.script,
1185
+ framework,
1186
+ encoding,
1187
+ definition.adapters,
1188
+ definition.appsSdkMetadata
1189
+ )
1184
1190
  );
1185
1191
  }
1186
1192
  case "appsSdk": {
@@ -1819,7 +1825,32 @@ var McpServer = class {
1819
1825
  }
1820
1826
  }
1821
1827
  }
1822
- const progressToken = extra?._meta?.progressToken;
1828
+ let progressToken = extra?._meta?.progressToken;
1829
+ let sendNotification = extra?.sendNotification;
1830
+ if (!progressToken || !sendNotification) {
1831
+ let session;
1832
+ if (requestContext) {
1833
+ for (const [, s] of this.sessions.entries()) {
1834
+ if (s.context === requestContext) {
1835
+ session = s;
1836
+ break;
1837
+ }
1838
+ }
1839
+ } else {
1840
+ const firstSession = this.sessions.values().next().value;
1841
+ if (firstSession) {
1842
+ session = firstSession;
1843
+ }
1844
+ }
1845
+ if (session) {
1846
+ if (!progressToken && session.progressToken) {
1847
+ progressToken = session.progressToken;
1848
+ }
1849
+ if (!sendNotification && session.sendNotification) {
1850
+ sendNotification = session.sendNotification;
1851
+ }
1852
+ }
1853
+ }
1823
1854
  const enhancedContext = requestContext ? Object.create(requestContext) : {};
1824
1855
  enhancedContext.sample = async (sampleParams, options) => {
1825
1856
  const {
@@ -1830,7 +1861,7 @@ var McpServer = class {
1830
1861
  let progressCount = 0;
1831
1862
  let completed = false;
1832
1863
  let progressInterval = null;
1833
- if (progressToken && extra?.sendNotification) {
1864
+ if (progressToken && sendNotification) {
1834
1865
  progressInterval = setInterval(async () => {
1835
1866
  if (completed) return;
1836
1867
  progressCount++;
@@ -1846,21 +1877,26 @@ var McpServer = class {
1846
1877
  }
1847
1878
  }
1848
1879
  try {
1849
- await extra.sendNotification({
1850
- method: "notifications/progress",
1851
- params: {
1852
- progressToken,
1853
- progress: progressData.progress,
1854
- total: progressData.total,
1855
- message: progressData.message
1856
- }
1857
- });
1880
+ if (sendNotification) {
1881
+ await sendNotification({
1882
+ method: "notifications/progress",
1883
+ params: {
1884
+ progressToken,
1885
+ progress: progressData.progress,
1886
+ total: progressData.total,
1887
+ message: progressData.message
1888
+ }
1889
+ });
1890
+ }
1858
1891
  } catch {
1859
1892
  }
1860
1893
  }, progressIntervalMs);
1861
1894
  }
1862
1895
  try {
1863
- const samplePromise = this.createMessage(sampleParams);
1896
+ const sdkTimeout = timeout && timeout !== Infinity ? timeout : 2147483647;
1897
+ const samplePromise = this.createMessage(sampleParams, {
1898
+ timeout: sdkTimeout
1899
+ });
1864
1900
  if (timeout && timeout !== Infinity) {
1865
1901
  const timeoutPromise = new Promise((_, reject) => {
1866
1902
  setTimeout(
@@ -1878,16 +1914,18 @@ var McpServer = class {
1878
1914
  }
1879
1915
  }
1880
1916
  };
1881
- enhancedContext.reportProgress = progressToken && extra?.sendNotification ? async (progress, total, message) => {
1882
- await extra.sendNotification({
1883
- method: "notifications/progress",
1884
- params: {
1885
- progressToken,
1886
- progress,
1887
- total,
1888
- message
1889
- }
1890
- });
1917
+ enhancedContext.reportProgress = progressToken && sendNotification ? async (progress, total, message) => {
1918
+ if (sendNotification) {
1919
+ await sendNotification({
1920
+ method: "notifications/progress",
1921
+ params: {
1922
+ progressToken,
1923
+ progress,
1924
+ total,
1925
+ message
1926
+ }
1927
+ });
1928
+ }
1891
1929
  } : void 0;
1892
1930
  const executeCallback = /* @__PURE__ */ __name(async () => {
1893
1931
  if (actualCallback.length >= 2) {
@@ -1992,7 +2030,6 @@ var McpServer = class {
1992
2030
  * ```
1993
2031
  */
1994
2032
  async createMessage(params, options) {
1995
- console.log("createMessage", params, options);
1996
2033
  return await this.server.server.createMessage(params, options);
1997
2034
  }
1998
2035
  /**
@@ -2098,7 +2135,10 @@ var McpServer = class {
2098
2135
  annotations: definition.annotations,
2099
2136
  readCallback: /* @__PURE__ */ __name(async () => {
2100
2137
  const params = definition.type === "externalUrl" ? this.applyDefaultProps(definition.props) : {};
2101
- const uiResource = this.createWidgetUIResource(definition, params);
2138
+ const uiResource = await this.createWidgetUIResource(
2139
+ definition,
2140
+ params
2141
+ );
2102
2142
  uiResource.resource.uri = resourceUri;
2103
2143
  return {
2104
2144
  contents: [uiResource.resource]
@@ -2121,7 +2161,7 @@ var McpServer = class {
2121
2161
  description: definition.description,
2122
2162
  annotations: definition.annotations,
2123
2163
  readCallback: /* @__PURE__ */ __name(async (uri, params) => {
2124
- const uiResource = this.createWidgetUIResource(definition, {});
2164
+ const uiResource = await this.createWidgetUIResource(definition, {});
2125
2165
  uiResource.resource.uri = uri.toString();
2126
2166
  return {
2127
2167
  contents: [uiResource.resource]
@@ -2151,7 +2191,10 @@ var McpServer = class {
2151
2191
  inputs: this.convertPropsToInputs(definition.props),
2152
2192
  _meta: Object.keys(toolMetadata).length > 0 ? toolMetadata : void 0,
2153
2193
  cb: /* @__PURE__ */ __name(async (params) => {
2154
- const uiResource = this.createWidgetUIResource(definition, params);
2194
+ const uiResource = await this.createWidgetUIResource(
2195
+ definition,
2196
+ params
2197
+ );
2155
2198
  if (definition.type === "appsSdk") {
2156
2199
  const randomId = Math.random().toString(36).substring(2, 15);
2157
2200
  const uniqueUri = this.generateWidgetUri(
@@ -2201,7 +2244,7 @@ var McpServer = class {
2201
2244
  * @param params - Parameters to pass to the widget via URL
2202
2245
  * @returns UIResource object compatible with MCP-UI
2203
2246
  */
2204
- createWidgetUIResource(definition, params) {
2247
+ async createWidgetUIResource(definition, params) {
2205
2248
  let configBaseUrl = `http://${this.serverHost}`;
2206
2249
  let configPort = this.serverPort || 3001;
2207
2250
  if (this.serverBaseUrl) {
@@ -2218,7 +2261,7 @@ var McpServer = class {
2218
2261
  port: configPort,
2219
2262
  buildId: this.buildId
2220
2263
  };
2221
- const uiResource = createUIResourceFromDefinition(
2264
+ const uiResource = await createUIResourceFromDefinition(
2222
2265
  definition,
2223
2266
  params,
2224
2267
  urlConfig
@@ -2822,7 +2865,15 @@ if (container && Component) {
2822
2865
  html = await fsHelpers.readFileSync(indexPath, "utf8");
2823
2866
  const mcpUrl = this.getServerBaseUrl();
2824
2867
  if (mcpUrl && html) {
2825
- const htmlWithoutComments = html.replace(/<!--[\s\S]*?-->/g, "");
2868
+ let htmlWithoutComments = html;
2869
+ let prevHtmlWithoutComments;
2870
+ do {
2871
+ prevHtmlWithoutComments = htmlWithoutComments;
2872
+ htmlWithoutComments = htmlWithoutComments.replace(
2873
+ /<!--[\s\S]*?-->/g,
2874
+ ""
2875
+ );
2876
+ } while (prevHtmlWithoutComments !== htmlWithoutComments);
2826
2877
  const baseTagRegex = /<base\s+[^>]*\/?>/i;
2827
2878
  if (baseTagRegex.test(htmlWithoutComments)) {
2828
2879
  const actualBaseTagMatch = html.match(/<base\s+[^>]*\/?>/i);
@@ -2994,7 +3045,8 @@ if (container && Component) {
2994
3045
  const { allowedOrigins, enableDnsRebindingProtection } = getTransportConfig();
2995
3046
  const transport = new StreamableHTTPServerTransport({
2996
3047
  sessionIdGenerator: /* @__PURE__ */ __name(() => generateUUID(), "sessionIdGenerator"),
2997
- enableJsonResponse: true,
3048
+ enableJsonResponse: false,
3049
+ // Allow SSE streaming for progress notifications
2998
3050
  allowedOrigins,
2999
3051
  enableDnsRebindingProtection,
3000
3052
  onsessioninitialized: /* @__PURE__ */ __name((id) => {
@@ -3019,7 +3071,8 @@ if (container && Component) {
3019
3071
  const transport = new StreamableHTTPServerTransport({
3020
3072
  sessionIdGenerator: /* @__PURE__ */ __name(() => oldSessionId, "sessionIdGenerator"),
3021
3073
  // Reuse old session ID!
3022
- enableJsonResponse: true,
3074
+ enableJsonResponse: false,
3075
+ // Allow SSE streaming for progress notifications
3023
3076
  allowedOrigins,
3024
3077
  enableDnsRebindingProtection,
3025
3078
  // We'll manually store the session, so don't rely on onsessioninitialized
@@ -3132,6 +3185,13 @@ if (container && Component) {
3132
3185
  const headers = {};
3133
3186
  let ended = false;
3134
3187
  let headersSent = false;
3188
+ let isSSEStream = false;
3189
+ let streamWriter = null;
3190
+ let streamingResponse = null;
3191
+ let sseStreamReady = null;
3192
+ const sseStreamPromise = new Promise((resolve) => {
3193
+ sseStreamReady = resolve;
3194
+ });
3135
3195
  const expressReq = {
3136
3196
  ...req,
3137
3197
  url: new URL(req.url).pathname + new URL(req.url).search,
@@ -3154,14 +3214,33 @@ if (container && Component) {
3154
3214
  }, "status"),
3155
3215
  setHeader: /* @__PURE__ */ __name((name, value) => {
3156
3216
  if (!headersSent) {
3157
- headers[name] = Array.isArray(value) ? value.join(", ") : value;
3217
+ headers[name.toLowerCase()] = Array.isArray(value) ? value.join(", ") : value;
3218
+ if (name.toLowerCase() === "content-type" && (Array.isArray(value) ? value.join(", ") : value).includes(
3219
+ "text/event-stream"
3220
+ )) {
3221
+ isSSEStream = true;
3222
+ const { readable, writable } = new globalThis.TransformStream();
3223
+ streamWriter = writable.getWriter();
3224
+ streamingResponse = new Response(readable, {
3225
+ status: statusCode,
3226
+ headers
3227
+ });
3228
+ if (sseStreamReady) {
3229
+ sseStreamReady(streamingResponse);
3230
+ }
3231
+ }
3158
3232
  }
3159
3233
  }, "setHeader"),
3160
- getHeader: /* @__PURE__ */ __name((name) => headers[name], "getHeader"),
3234
+ getHeader: /* @__PURE__ */ __name((name) => headers[name.toLowerCase()], "getHeader"),
3161
3235
  write: /* @__PURE__ */ __name((chunk, encoding, callback) => {
3162
- if (!ended) {
3236
+ if (!ended || isSSEStream) {
3163
3237
  const data = typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
3164
- responseBody.push(data);
3238
+ if (isSSEStream && streamWriter) {
3239
+ streamWriter.write(data).catch(() => {
3240
+ });
3241
+ } else {
3242
+ responseBody.push(data);
3243
+ }
3165
3244
  }
3166
3245
  if (typeof encoding === "function") {
3167
3246
  encoding();
@@ -3173,9 +3252,16 @@ if (container && Component) {
3173
3252
  end: /* @__PURE__ */ __name((chunk, encoding, callback) => {
3174
3253
  if (chunk && !ended) {
3175
3254
  const data = typeof chunk === "string" ? new TextEncoder().encode(chunk) : chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
3176
- responseBody.push(data);
3255
+ if (isSSEStream && streamWriter) {
3256
+ streamWriter.write(data).catch(() => {
3257
+ });
3258
+ } else {
3259
+ responseBody.push(data);
3260
+ }
3261
+ }
3262
+ if (!isSSEStream) {
3263
+ ended = true;
3177
3264
  }
3178
- ended = true;
3179
3265
  if (typeof encoding === "function") {
3180
3266
  encoding();
3181
3267
  } else if (callback) {
@@ -3196,7 +3282,28 @@ if (container && Component) {
3196
3282
  expressRes.statusCode = code;
3197
3283
  headersSent = true;
3198
3284
  if (_headers) {
3199
- Object.assign(headers, _headers);
3285
+ if (Array.isArray(_headers)) {
3286
+ for (const [name, value] of _headers) {
3287
+ headers[name.toLowerCase()] = value;
3288
+ }
3289
+ } else {
3290
+ for (const [key, value] of Object.entries(_headers)) {
3291
+ headers[key.toLowerCase()] = value;
3292
+ }
3293
+ }
3294
+ const contentType = headers["content-type"];
3295
+ if (contentType && contentType.includes("text/event-stream")) {
3296
+ isSSEStream = true;
3297
+ const { readable, writable } = new globalThis.TransformStream();
3298
+ streamWriter = writable.getWriter();
3299
+ streamingResponse = new Response(readable, {
3300
+ status: statusCode,
3301
+ headers
3302
+ });
3303
+ if (sseStreamReady) {
3304
+ sseStreamReady(streamingResponse);
3305
+ }
3306
+ }
3200
3307
  }
3201
3308
  return expressRes;
3202
3309
  }, "writeHead"),
@@ -3214,6 +3321,9 @@ if (container && Component) {
3214
3321
  expressReq,
3215
3322
  expressRes,
3216
3323
  getResponse: /* @__PURE__ */ __name(() => {
3324
+ if (isSSEStream && streamingResponse) {
3325
+ return streamingResponse;
3326
+ }
3217
3327
  if (ended) {
3218
3328
  if (responseBody.length > 0) {
3219
3329
  const body = isDeno2 ? Buffer.concat(responseBody) : Buffer.concat(responseBody);
@@ -3229,12 +3339,20 @@ if (container && Component) {
3229
3339
  }
3230
3340
  }
3231
3341
  return null;
3232
- }, "getResponse")
3342
+ }, "getResponse"),
3343
+ isSSEStream: /* @__PURE__ */ __name(() => isSSEStream, "isSSEStream"),
3344
+ waitForSSEStream: /* @__PURE__ */ __name(() => sseStreamPromise, "waitForSSEStream")
3233
3345
  };
3234
3346
  }, "createExpressLikeObjects");
3235
3347
  const mountEndpoint = /* @__PURE__ */ __name((endpoint) => {
3236
3348
  this.app.post(endpoint, async (c) => {
3237
- const { expressReq, expressRes, getResponse } = createExpressLikeObjects(c);
3349
+ const {
3350
+ expressReq,
3351
+ expressRes,
3352
+ getResponse,
3353
+ isSSEStream,
3354
+ waitForSSEStream
3355
+ } = createExpressLikeObjects(c);
3238
3356
  let body = {};
3239
3357
  try {
3240
3358
  body = await c.req.json();
@@ -3277,20 +3395,82 @@ if (container && Component) {
3277
3395
  const session = this.sessions.get(sessionId);
3278
3396
  session.lastAccessedAt = Date.now();
3279
3397
  session.context = c;
3398
+ session.honoContext = c;
3399
+ session.expressRes = expressRes;
3400
+ if (body?.method === "tools/call" && body?.params?._meta?.progressToken) {
3401
+ session.progressToken = body.params._meta.progressToken;
3402
+ console.log(
3403
+ `Received progressToken ${session.progressToken} for tool call: ${body.params?.name}`
3404
+ );
3405
+ } else {
3406
+ session.progressToken = void 0;
3407
+ if (body?.method === "tools/call") {
3408
+ console.log(
3409
+ `No progressToken in tool call request: ${body.params?.name}`
3410
+ );
3411
+ }
3412
+ }
3280
3413
  }
3281
3414
  if (expressRes._closeHandler) {
3282
3415
  c.req.raw.signal?.addEventListener("abort", () => {
3283
3416
  transport.close();
3284
3417
  });
3285
3418
  }
3419
+ let streamingResponse = null;
3420
+ let shouldReturnStream = false;
3286
3421
  await runWithContext(c, async () => {
3287
- await this.waitForRequestComplete(
3288
- transport,
3422
+ const handleRequestPromise = transport.handleRequest(
3289
3423
  expressReq,
3290
3424
  expressRes,
3291
3425
  expressReq.body
3292
3426
  );
3427
+ try {
3428
+ const sseStream = await Promise.race([
3429
+ waitForSSEStream(),
3430
+ new Promise((resolve) => {
3431
+ setTimeout(() => resolve(null), 50);
3432
+ })
3433
+ ]);
3434
+ if (sseStream) {
3435
+ streamingResponse = sseStream;
3436
+ shouldReturnStream = true;
3437
+ handleRequestPromise.catch((err) => {
3438
+ });
3439
+ return;
3440
+ } else {
3441
+ if (isSSEStream()) {
3442
+ const response2 = getResponse();
3443
+ if (response2) {
3444
+ streamingResponse = response2;
3445
+ shouldReturnStream = true;
3446
+ handleRequestPromise.catch(() => {
3447
+ });
3448
+ return;
3449
+ }
3450
+ }
3451
+ }
3452
+ } catch {
3453
+ }
3454
+ await new Promise((resolve) => {
3455
+ const originalEnd = expressRes.end;
3456
+ let ended = false;
3457
+ expressRes.end = (...args) => {
3458
+ if (!ended) {
3459
+ originalEnd.apply(expressRes, args);
3460
+ ended = true;
3461
+ resolve();
3462
+ }
3463
+ };
3464
+ handleRequestPromise.finally(() => {
3465
+ if (!ended) {
3466
+ expressRes.end();
3467
+ }
3468
+ });
3469
+ });
3293
3470
  });
3471
+ if (shouldReturnStream && streamingResponse) {
3472
+ return streamingResponse;
3473
+ }
3294
3474
  const response = getResponse();
3295
3475
  if (response) {
3296
3476
  return response;