mcp-use 1.0.4 → 1.0.6

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.
Files changed (34) hide show
  1. package/README.md +98 -1
  2. package/dist/index.cjs +118 -689
  3. package/dist/index.d.ts +10 -2
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +118 -54
  6. package/dist/src/agents/mcp_agent.d.ts +1 -1
  7. package/dist/src/agents/mcp_agent.d.ts.map +1 -1
  8. package/dist/src/server/adapters/mcp-ui-adapter.d.ts +66 -0
  9. package/dist/src/server/adapters/mcp-ui-adapter.d.ts.map +1 -0
  10. package/dist/src/server/index.cjs +292 -14
  11. package/dist/src/server/index.d.ts +4 -2
  12. package/dist/src/server/index.d.ts.map +1 -1
  13. package/dist/src/server/index.js +913 -4
  14. package/dist/src/server/mcp-server.d.ts +91 -2
  15. package/dist/src/server/mcp-server.d.ts.map +1 -1
  16. package/dist/src/server/types/common.d.ts +27 -0
  17. package/dist/src/server/types/common.d.ts.map +1 -0
  18. package/dist/src/server/types/index.d.ts +8 -0
  19. package/dist/src/server/types/index.d.ts.map +1 -0
  20. package/dist/src/server/types/prompt.d.ts +14 -0
  21. package/dist/src/server/types/prompt.d.ts.map +1 -0
  22. package/dist/src/server/types/resource.d.ts +155 -0
  23. package/dist/src/server/types/resource.d.ts.map +1 -0
  24. package/dist/src/server/types/tool.d.ts +14 -0
  25. package/dist/src/server/types/tool.d.ts.map +1 -0
  26. package/dist/src/server/types.d.ts +3 -76
  27. package/dist/src/server/types.d.ts.map +1 -1
  28. package/dist/tests/helpers/widget-generators.d.ts +24 -0
  29. package/dist/tests/helpers/widget-generators.d.ts.map +1 -0
  30. package/dist/tests/mcp-ui-adapter.test.d.ts +8 -0
  31. package/dist/tests/mcp-ui-adapter.test.d.ts.map +1 -0
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +33 -36
  34. package/dist/chunk-MZPKOZE4.js +0 -644
package/dist/index.cjs CHANGED
@@ -496,7 +496,6 @@ __export(index_exports, {
496
496
  Telemetry: () => Telemetry,
497
497
  ToolMessage: () => import_messages3.ToolMessage,
498
498
  WebSocketConnector: () => WebSocketConnector,
499
- createMCPServer: () => createMCPServer,
500
499
  createOAuthMCPConfig: () => createOAuthMCPConfig,
501
500
  createReadableStreamFromGenerator: () => createReadableStreamFromGenerator,
502
501
  loadConfigFile: () => loadConfigFile,
@@ -2277,7 +2276,8 @@ var MCPAgent = class {
2277
2276
  const startTime = Date.now();
2278
2277
  const toolsUsedNames = [];
2279
2278
  let stepsTaken = 0;
2280
- let success = false;
2279
+ const structuredOutputSuccess = false;
2280
+ const structuredOutputSuccessRef = { value: structuredOutputSuccess };
2281
2281
  let structuredLlm = null;
2282
2282
  let schemaDescription = "";
2283
2283
  if (outputSchema) {
@@ -2367,28 +2367,26 @@ var MCPAgent = class {
2367
2367
  result = nextStepOutput.returnValues?.output ?? "No output generated";
2368
2368
  runManager?.handleChainEnd({ output: result });
2369
2369
  if (outputSchema && structuredLlm) {
2370
- try {
2371
- logger.info("\u{1F527} Attempting structured output...");
2372
- const structuredResult = await this._attemptStructuredOutput(
2373
- result,
2374
- structuredLlm,
2375
- outputSchema,
2376
- schemaDescription
2377
- );
2378
- logger.debug(`\u{1F504} Structured result: ${JSON.stringify(structuredResult)}`);
2370
+ logger.info("\u{1F527} Attempting structured output...");
2371
+ const currentResult = result;
2372
+ this._attemptStructuredOutput(
2373
+ currentResult,
2374
+ this.llm,
2375
+ outputSchema
2376
+ ).then((structuredResult) => {
2379
2377
  if (this.memoryEnabled) {
2380
2378
  this.addToHistory(new import_messages2.AIMessage(`Structured result: ${JSON.stringify(structuredResult)}`));
2381
2379
  }
2382
2380
  logger.info("\u2705 Structured output successful");
2383
- success = true;
2381
+ structuredOutputSuccessRef.value = true;
2384
2382
  return structuredResult;
2385
- } catch (e) {
2383
+ }).catch((e) => {
2386
2384
  logger.warn(`\u26A0\uFE0F Structured output failed: ${e}`);
2387
2385
  const failedStructuredOutputPrompt = `
2388
2386
  The current result cannot be formatted into the required structure.
2389
2387
  Error: ${String(e)}
2390
2388
 
2391
- Current information: ${result}
2389
+ Current information: ${currentResult}
2392
2390
 
2393
2391
  If information is missing, please continue working to gather the missing information needed for:
2394
2392
  ${schemaDescription}
@@ -2400,36 +2398,35 @@ var MCPAgent = class {
2400
2398
  this.addToHistory(new import_messages2.HumanMessage(failedStructuredOutputPrompt));
2401
2399
  }
2402
2400
  logger.info("\u{1F504} Continuing execution to gather missing information...");
2403
- continue;
2404
- }
2405
- } else {
2406
- break;
2401
+ });
2407
2402
  }
2408
2403
  }
2409
- const stepArray = nextStepOutput;
2410
- intermediateSteps.push(...stepArray);
2411
- for (const step of stepArray) {
2412
- yield step;
2413
- const { action, observation } = step;
2414
- const toolName = action.tool;
2415
- toolsUsedNames.push(toolName);
2416
- let toolInputStr = typeof action.toolInput === "string" ? action.toolInput : JSON.stringify(action.toolInput, null, 2);
2417
- if (toolInputStr.length > 100)
2418
- toolInputStr = `${toolInputStr.slice(0, 97)}...`;
2419
- logger.info(`\u{1F527} Tool call: ${toolName} with input: ${toolInputStr}`);
2420
- let outputStr = String(observation);
2421
- if (outputStr.length > 100)
2422
- outputStr = `${outputStr.slice(0, 97)}...`;
2423
- outputStr = outputStr.replace(/\n/g, " ");
2424
- logger.info(`\u{1F4C4} Tool result: ${outputStr}`);
2425
- }
2426
- if (stepArray.length) {
2427
- const lastStep = stepArray[stepArray.length - 1];
2428
- const toolReturn = await this._agentExecutor._getToolReturn(lastStep);
2429
- if (toolReturn) {
2430
- logger.info(`\u{1F3C6} Tool returned directly at step ${stepNum + 1}`);
2431
- result = toolReturn.returnValues?.output ?? "No output generated";
2432
- break;
2404
+ if (Array.isArray(nextStepOutput)) {
2405
+ const stepArray = nextStepOutput;
2406
+ intermediateSteps.push(...stepArray);
2407
+ for (const step of stepArray) {
2408
+ yield step;
2409
+ const { action, observation } = step;
2410
+ const toolName = action.tool;
2411
+ toolsUsedNames.push(toolName);
2412
+ let toolInputStr = typeof action.toolInput === "string" ? action.toolInput : JSON.stringify(action.toolInput, null, 2);
2413
+ if (toolInputStr.length > 100)
2414
+ toolInputStr = `${toolInputStr.slice(0, 97)}...`;
2415
+ logger.info(`\u{1F527} Tool call: ${toolName} with input: ${toolInputStr}`);
2416
+ let outputStr = String(observation);
2417
+ if (outputStr.length > 100)
2418
+ outputStr = `${outputStr.slice(0, 97)}...`;
2419
+ outputStr = outputStr.replace(/\n/g, " ");
2420
+ logger.info(`\u{1F4C4} Tool result: ${outputStr}`);
2421
+ }
2422
+ if (stepArray.length) {
2423
+ const lastStep = stepArray[stepArray.length - 1];
2424
+ const toolReturn = await this._agentExecutor._getToolReturn(lastStep);
2425
+ if (toolReturn) {
2426
+ logger.info(`\u{1F3C6} Tool returned directly at step ${stepNum + 1}`);
2427
+ result = toolReturn.returnValues?.output ?? "No output generated";
2428
+ break;
2429
+ }
2433
2430
  }
2434
2431
  }
2435
2432
  } catch (e) {
@@ -2452,7 +2449,7 @@ var MCPAgent = class {
2452
2449
  runManager?.handleChainEnd({ output: result });
2453
2450
  }
2454
2451
  logger.info("\u{1F389} Agent execution complete");
2455
- success = true;
2452
+ structuredOutputSuccessRef.value = true;
2456
2453
  return result;
2457
2454
  } catch (e) {
2458
2455
  logger.error(`\u274C Error running query: ${e}`);
@@ -2473,7 +2470,7 @@ var MCPAgent = class {
2473
2470
  await this.telemetry.trackAgentExecution({
2474
2471
  executionMethod: "stream",
2475
2472
  query,
2476
- success,
2473
+ success: structuredOutputSuccess,
2477
2474
  modelProvider: this.modelProvider,
2478
2475
  modelName: this.modelName,
2479
2476
  serverCount,
@@ -2491,7 +2488,7 @@ var MCPAgent = class {
2491
2488
  toolsUsedNames,
2492
2489
  response: result,
2493
2490
  executionTimeMs,
2494
- errorType: success ? null : "execution_error",
2491
+ errorType: structuredOutputSuccess ? null : "execution_error",
2495
2492
  conversationHistoryLength
2496
2493
  });
2497
2494
  if (manageConnector && !this.client && initializedHere) {
@@ -2532,13 +2529,16 @@ var MCPAgent = class {
2532
2529
  * Yields LangChain StreamEvent objects from the underlying streamEvents() method.
2533
2530
  * This provides token-level streaming and fine-grained event updates.
2534
2531
  */
2535
- async *streamEvents(query, maxSteps, manageConnector = true, externalHistory) {
2532
+ async *streamEvents(query, maxSteps, manageConnector = true, externalHistory, outputSchema) {
2536
2533
  let initializedHere = false;
2537
2534
  const startTime = Date.now();
2538
2535
  let success = false;
2539
2536
  let eventCount = 0;
2540
2537
  let totalResponseLength = 0;
2541
2538
  let finalResponse = "";
2539
+ if (outputSchema) {
2540
+ query = this._enhanceQueryWithSchema(query, outputSchema);
2541
+ }
2542
2542
  try {
2543
2543
  if (manageConnector && !this._initialized) {
2544
2544
  await this.initialize();
@@ -2586,15 +2586,71 @@ var MCPAgent = class {
2586
2586
  totalResponseLength += event.data.chunk.content.length;
2587
2587
  }
2588
2588
  yield event;
2589
- await new Promise((resolve) => setTimeout(resolve, 0));
2590
2589
  if (event.event === "on_chain_end" && event.data?.output) {
2591
2590
  const output = event.data.output;
2592
2591
  if (Array.isArray(output) && output.length > 0 && output[0]?.text) {
2593
2592
  finalResponse = output[0].text;
2593
+ } else if (typeof output === "string") {
2594
+ finalResponse = output;
2595
+ } else if (output && typeof output === "object" && "output" in output) {
2596
+ finalResponse = output.output;
2594
2597
  }
2595
2598
  }
2596
2599
  }
2597
- if (this.memoryEnabled && finalResponse) {
2600
+ if (outputSchema && finalResponse) {
2601
+ logger.info("\u{1F527} Attempting structured output conversion...");
2602
+ try {
2603
+ let conversionCompleted = false;
2604
+ let conversionResult = null;
2605
+ let conversionError = null;
2606
+ const _conversionPromise = this._attemptStructuredOutput(
2607
+ finalResponse,
2608
+ this.llm,
2609
+ outputSchema
2610
+ ).then((result) => {
2611
+ conversionCompleted = true;
2612
+ conversionResult = result;
2613
+ return result;
2614
+ }).catch((error) => {
2615
+ conversionCompleted = true;
2616
+ conversionError = error;
2617
+ throw error;
2618
+ });
2619
+ let progressCount = 0;
2620
+ while (!conversionCompleted) {
2621
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
2622
+ if (!conversionCompleted) {
2623
+ progressCount++;
2624
+ yield {
2625
+ event: "on_structured_output_progress",
2626
+ data: {
2627
+ message: `Converting to structured output... (${progressCount * 2}s)`,
2628
+ elapsed: progressCount * 2
2629
+ }
2630
+ };
2631
+ }
2632
+ }
2633
+ if (conversionError) {
2634
+ throw conversionError;
2635
+ }
2636
+ if (conversionResult) {
2637
+ yield {
2638
+ event: "on_structured_output",
2639
+ data: { output: conversionResult }
2640
+ };
2641
+ if (this.memoryEnabled) {
2642
+ this.addToHistory(new import_messages2.AIMessage(`Structured result: ${JSON.stringify(conversionResult)}`));
2643
+ }
2644
+ logger.info("\u2705 Structured output successful");
2645
+ }
2646
+ } catch (e) {
2647
+ logger.warn(`\u26A0\uFE0F Structured output failed: ${e}`);
2648
+ yield {
2649
+ event: "on_structured_output_error",
2650
+ data: { error: e instanceof Error ? e.message : String(e) }
2651
+ };
2652
+ }
2653
+ } else if (this.memoryEnabled && finalResponse) {
2598
2654
  this.addToHistory(new import_messages2.AIMessage(finalResponse));
2599
2655
  }
2600
2656
  logger.info(`\u{1F389} StreamEvents complete - ${eventCount} events emitted`);
@@ -2645,10 +2701,21 @@ var MCPAgent = class {
2645
2701
  /**
2646
2702
  * Attempt to create structured output from raw result with validation and retry logic.
2647
2703
  */
2648
- async _attemptStructuredOutput(rawResult, structuredLlm, outputSchema, schemaDescription) {
2704
+ async _attemptStructuredOutput(rawResult, llm, outputSchema) {
2649
2705
  logger.info(`\u{1F504} Attempting structured output with schema: ${outputSchema}`);
2650
- logger.info(`\u{1F504} Schema description: ${schemaDescription}`);
2651
2706
  logger.info(`\u{1F504} Raw result: ${JSON.stringify(rawResult, null, 2)}`);
2707
+ let structuredLlm = null;
2708
+ let schemaDescription = "";
2709
+ logger.debug(`\u{1F504} Structured output requested, schema: ${JSON.stringify((0, import_zod_to_json_schema2.zodToJsonSchema)(outputSchema), null, 2)}`);
2710
+ if (llm && "withStructuredOutput" in llm && typeof llm.withStructuredOutput === "function") {
2711
+ structuredLlm = llm.withStructuredOutput(outputSchema);
2712
+ } else if (llm) {
2713
+ structuredLlm = llm;
2714
+ } else {
2715
+ throw new Error("LLM is required for structured output");
2716
+ }
2717
+ schemaDescription = JSON.stringify((0, import_zod_to_json_schema2.zodToJsonSchema)(outputSchema), null, 2);
2718
+ logger.info(`\u{1F504} Schema description: ${schemaDescription}`);
2652
2719
  let textContent = "";
2653
2720
  if (typeof rawResult === "string") {
2654
2721
  textContent = rawResult;
@@ -2692,6 +2759,7 @@ var MCPAgent = class {
2692
2759
  let chunkCount = 0;
2693
2760
  for await (const chunk of stream) {
2694
2761
  chunkCount++;
2762
+ logger.info(`Chunk ${chunkCount}: ${JSON.stringify(chunk, null, 2)}`);
2695
2763
  if (typeof chunk === "string") {
2696
2764
  try {
2697
2765
  structuredResult = JSON.parse(chunk);
@@ -2707,7 +2775,6 @@ var MCPAgent = class {
2707
2775
  logger.warn(`\u{1F504} Failed to parse chunk as JSON: ${chunk}`);
2708
2776
  }
2709
2777
  }
2710
- await new Promise((resolve) => setTimeout(resolve, 0));
2711
2778
  if (chunkCount % 10 === 0) {
2712
2779
  logger.info(`\u{1F504} Structured output streaming: ${chunkCount} chunks`);
2713
2780
  }
@@ -4001,643 +4068,6 @@ async function* streamEventsToAISDKWithTools(streamEvents) {
4001
4068
  }
4002
4069
  __name(streamEventsToAISDKWithTools, "streamEventsToAISDKWithTools");
4003
4070
 
4004
- // src/server/mcp-server.ts
4005
- var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
4006
- var import_zod7 = require("zod");
4007
- var import_express = __toESM(require("express"), 1);
4008
- var import_node_fs3 = require("fs");
4009
- var import_node_path2 = require("path");
4010
-
4011
- // src/server/logging.ts
4012
- function requestLogger(req, res, next) {
4013
- const timestamp2 = (/* @__PURE__ */ new Date()).toISOString().substring(11, 23);
4014
- const method = req.method;
4015
- const url = req.url;
4016
- const originalEnd = res.end.bind(res);
4017
- res.end = function(chunk, encoding, cb) {
4018
- const statusCode = res.statusCode;
4019
- let statusColor = "";
4020
- if (statusCode >= 200 && statusCode < 300) {
4021
- statusColor = "\x1B[32m";
4022
- } else if (statusCode >= 300 && statusCode < 400) {
4023
- statusColor = "\x1B[33m";
4024
- } else if (statusCode >= 400 && statusCode < 500) {
4025
- statusColor = "\x1B[31m";
4026
- } else if (statusCode >= 500) {
4027
- statusColor = "\x1B[35m";
4028
- }
4029
- let logMessage = `[${timestamp2}] ${method} \x1B[1m${url}\x1B[0m`;
4030
- if (method === "POST" && url === "/mcp" && req.body?.method) {
4031
- logMessage += ` \x1B[1m[${req.body.method}]\x1B[0m`;
4032
- }
4033
- logMessage += ` ${statusColor}${statusCode}\x1B[0m`;
4034
- console.log(logMessage);
4035
- return originalEnd(chunk, encoding, cb);
4036
- };
4037
- next();
4038
- }
4039
- __name(requestLogger, "requestLogger");
4040
-
4041
- // src/server/mcp-server.ts
4042
- var McpServer = class {
4043
- static {
4044
- __name(this, "McpServer");
4045
- }
4046
- server;
4047
- config;
4048
- app;
4049
- mcpMounted = false;
4050
- inspectorMounted = false;
4051
- serverPort;
4052
- /**
4053
- * Creates a new MCP server instance with Express integration
4054
- *
4055
- * Initializes the server with the provided configuration, sets up CORS headers,
4056
- * configures widget serving routes, and creates a proxy that allows direct
4057
- * access to Express methods while preserving MCP server functionality.
4058
- *
4059
- * @param config - Server configuration including name, version, and description
4060
- * @returns A proxied McpServer instance that supports both MCP and Express methods
4061
- */
4062
- constructor(config2) {
4063
- this.config = config2;
4064
- this.server = new import_mcp.McpServer({
4065
- name: config2.name,
4066
- version: config2.version
4067
- });
4068
- this.app = (0, import_express.default)();
4069
- this.app.use(import_express.default.json());
4070
- this.app.use((req, res, next) => {
4071
- res.header("Access-Control-Allow-Origin", "*");
4072
- res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, OPTIONS");
4073
- res.header("Access-Control-Allow-Headers", "Content-Type");
4074
- next();
4075
- });
4076
- this.app.use(requestLogger);
4077
- this.setupWidgetRoutes();
4078
- return new Proxy(this, {
4079
- get(target, prop) {
4080
- if (prop in target) {
4081
- return target[prop];
4082
- }
4083
- const value = target.app[prop];
4084
- return typeof value === "function" ? value.bind(target.app) : value;
4085
- }
4086
- });
4087
- }
4088
- /**
4089
- * Define a static resource that can be accessed by clients
4090
- *
4091
- * Registers a resource with the MCP server that clients can access via HTTP.
4092
- * Resources are static content like files, data, or pre-computed results that
4093
- * can be retrieved by clients without requiring parameters.
4094
- *
4095
- * @param resourceDefinition - Configuration object containing resource metadata and handler function
4096
- * @param resourceDefinition.name - Unique identifier for the resource
4097
- * @param resourceDefinition.uri - URI pattern for accessing the resource
4098
- * @param resourceDefinition.title - Optional human-readable title for the resource
4099
- * @param resourceDefinition.description - Optional description of the resource
4100
- * @param resourceDefinition.mimeType - MIME type of the resource content
4101
- * @param resourceDefinition.annotations - Optional annotations (audience, priority, lastModified)
4102
- * @param resourceDefinition.fn - Async function that returns the resource content
4103
- * @returns The server instance for method chaining
4104
- *
4105
- * @example
4106
- * ```typescript
4107
- * server.resource({
4108
- * name: 'config',
4109
- * uri: 'config://app-settings',
4110
- * title: 'Application Settings',
4111
- * mimeType: 'application/json',
4112
- * description: 'Current application configuration',
4113
- * annotations: {
4114
- * audience: ['user'],
4115
- * priority: 0.8
4116
- * },
4117
- * fn: async () => ({
4118
- * contents: [{
4119
- * uri: 'config://app-settings',
4120
- * mimeType: 'application/json',
4121
- * text: JSON.stringify({ theme: 'dark', language: 'en' })
4122
- * }]
4123
- * })
4124
- * })
4125
- * ```
4126
- */
4127
- resource(resourceDefinition) {
4128
- this.server.resource(
4129
- resourceDefinition.name,
4130
- resourceDefinition.uri,
4131
- {
4132
- name: resourceDefinition.name,
4133
- title: resourceDefinition.title,
4134
- description: resourceDefinition.description,
4135
- mimeType: resourceDefinition.mimeType,
4136
- annotations: resourceDefinition.annotations
4137
- },
4138
- async () => {
4139
- return await resourceDefinition.fn();
4140
- }
4141
- );
4142
- return this;
4143
- }
4144
- /**
4145
- * Define a dynamic resource template with parameters
4146
- *
4147
- * Registers a parameterized resource template with the MCP server. Templates use URI
4148
- * patterns with placeholders that can be filled in at request time, allowing dynamic
4149
- * resource generation based on parameters.
4150
- *
4151
- * @param resourceTemplateDefinition - Configuration object for the resource template
4152
- * @param resourceTemplateDefinition.name - Unique identifier for the template
4153
- * @param resourceTemplateDefinition.resourceTemplate - ResourceTemplate object with uriTemplate and metadata
4154
- * @param resourceTemplateDefinition.fn - Async function that generates resource content from URI and params
4155
- * @returns The server instance for method chaining
4156
- *
4157
- * @example
4158
- * ```typescript
4159
- * server.resourceTemplate({
4160
- * name: 'user-profile',
4161
- * resourceTemplate: {
4162
- * uriTemplate: 'user://{userId}/profile',
4163
- * name: 'User Profile',
4164
- * mimeType: 'application/json'
4165
- * },
4166
- * fn: async (uri, params) => ({
4167
- * contents: [{
4168
- * uri: uri.toString(),
4169
- * mimeType: 'application/json',
4170
- * text: JSON.stringify({ userId: params.userId, name: 'John Doe' })
4171
- * }]
4172
- * })
4173
- * })
4174
- * ```
4175
- */
4176
- resourceTemplate(resourceTemplateDefinition) {
4177
- const template = new import_mcp.ResourceTemplate(
4178
- resourceTemplateDefinition.resourceTemplate.uriTemplate,
4179
- {
4180
- list: void 0,
4181
- // Optional: callback to list all matching resources
4182
- complete: void 0
4183
- // Optional: callback for auto-completion
4184
- }
4185
- );
4186
- const metadata = {};
4187
- if (resourceTemplateDefinition.resourceTemplate.name) {
4188
- metadata.name = resourceTemplateDefinition.resourceTemplate.name;
4189
- }
4190
- if (resourceTemplateDefinition.title) {
4191
- metadata.title = resourceTemplateDefinition.title;
4192
- }
4193
- if (resourceTemplateDefinition.description || resourceTemplateDefinition.resourceTemplate.description) {
4194
- metadata.description = resourceTemplateDefinition.description || resourceTemplateDefinition.resourceTemplate.description;
4195
- }
4196
- if (resourceTemplateDefinition.resourceTemplate.mimeType) {
4197
- metadata.mimeType = resourceTemplateDefinition.resourceTemplate.mimeType;
4198
- }
4199
- if (resourceTemplateDefinition.annotations) {
4200
- metadata.annotations = resourceTemplateDefinition.annotations;
4201
- }
4202
- this.server.resource(
4203
- resourceTemplateDefinition.name,
4204
- template,
4205
- metadata,
4206
- async (uri) => {
4207
- const params = this.parseTemplateUri(
4208
- resourceTemplateDefinition.resourceTemplate.uriTemplate,
4209
- uri.toString()
4210
- );
4211
- return await resourceTemplateDefinition.fn(uri, params);
4212
- }
4213
- );
4214
- return this;
4215
- }
4216
- /**
4217
- * Define a tool that can be called by clients
4218
- *
4219
- * Registers a tool with the MCP server that clients can invoke with parameters.
4220
- * Tools are functions that perform actions, computations, or operations and
4221
- * return results. They accept structured input parameters and return structured output.
4222
- *
4223
- * @param toolDefinition - Configuration object containing tool metadata and handler function
4224
- * @param toolDefinition.name - Unique identifier for the tool
4225
- * @param toolDefinition.description - Human-readable description of what the tool does
4226
- * @param toolDefinition.inputs - Array of input parameter definitions with types and validation
4227
- * @param toolDefinition.fn - Async function that executes the tool logic with provided parameters
4228
- * @returns The server instance for method chaining
4229
- *
4230
- * @example
4231
- * ```typescript
4232
- * server.tool({
4233
- * name: 'calculate',
4234
- * description: 'Performs mathematical calculations',
4235
- * inputs: [
4236
- * { name: 'expression', type: 'string', required: true },
4237
- * { name: 'precision', type: 'number', required: false }
4238
- * ],
4239
- * fn: async ({ expression, precision = 2 }) => {
4240
- * const result = eval(expression)
4241
- * return { result: Number(result.toFixed(precision)) }
4242
- * }
4243
- * })
4244
- * ```
4245
- */
4246
- tool(toolDefinition) {
4247
- const inputSchema = this.createToolInputSchema(toolDefinition.inputs || []);
4248
- this.server.tool(
4249
- toolDefinition.name,
4250
- toolDefinition.description ?? "",
4251
- inputSchema,
4252
- async (params) => {
4253
- return await toolDefinition.fn(params);
4254
- }
4255
- );
4256
- return this;
4257
- }
4258
- /**
4259
- * Define a prompt template
4260
- *
4261
- * Registers a prompt template with the MCP server that clients can use to generate
4262
- * structured prompts for AI models. Prompt templates accept parameters and return
4263
- * formatted text that can be used as input to language models or other AI systems.
4264
- *
4265
- * @param promptDefinition - Configuration object containing prompt metadata and handler function
4266
- * @param promptDefinition.name - Unique identifier for the prompt template
4267
- * @param promptDefinition.description - Human-readable description of the prompt's purpose
4268
- * @param promptDefinition.args - Array of argument definitions with types and validation
4269
- * @param promptDefinition.fn - Async function that generates the prompt from provided arguments
4270
- * @returns The server instance for method chaining
4271
- *
4272
- * @example
4273
- * ```typescript
4274
- * server.prompt({
4275
- * name: 'code-review',
4276
- * description: 'Generates a code review prompt',
4277
- * args: [
4278
- * { name: 'language', type: 'string', required: true },
4279
- * { name: 'focus', type: 'string', required: false }
4280
- * ],
4281
- * fn: async ({ language, focus = 'general' }) => {
4282
- * return {
4283
- * messages: [{
4284
- * role: 'user',
4285
- * content: `Please review this ${language} code with focus on ${focus}...`
4286
- * }]
4287
- * }
4288
- * }
4289
- * })
4290
- * ```
4291
- */
4292
- prompt(promptDefinition) {
4293
- const argsSchema = this.createPromptArgsSchema(promptDefinition.args || []);
4294
- this.server.prompt(
4295
- promptDefinition.name,
4296
- promptDefinition.description ?? "",
4297
- argsSchema,
4298
- async (params) => {
4299
- return await promptDefinition.fn(params);
4300
- }
4301
- );
4302
- return this;
4303
- }
4304
- /**
4305
- * Mount MCP server endpoints at /mcp
4306
- *
4307
- * Sets up the HTTP transport layer for the MCP server, creating endpoints for
4308
- * Server-Sent Events (SSE) streaming, POST message handling, and DELETE session cleanup.
4309
- * Uses stateless mode for session management, making it suitable for stateless deployments.
4310
- *
4311
- * This method is called automatically when the server starts listening and ensures
4312
- * that MCP clients can communicate with the server over HTTP.
4313
- *
4314
- * @private
4315
- * @returns Promise that resolves when MCP endpoints are successfully mounted
4316
- *
4317
- * @example
4318
- * Endpoints created:
4319
- * - GET /mcp - SSE streaming endpoint for real-time communication
4320
- * - POST /mcp - Message handling endpoint for MCP protocol messages
4321
- * - DELETE /mcp - Session cleanup endpoint
4322
- */
4323
- async mountMcp() {
4324
- if (this.mcpMounted) return;
4325
- const { StreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/streamableHttp.js");
4326
- const httpTransport = new StreamableHTTPServerTransport({
4327
- sessionIdGenerator: void 0
4328
- // Stateless mode
4329
- });
4330
- await this.server.connect(httpTransport);
4331
- const endpoint = "/mcp";
4332
- this.app.get(endpoint, async (req, res) => {
4333
- await httpTransport.handleRequest(req, res);
4334
- });
4335
- this.app.post(endpoint, import_express.default.json(), async (req, res) => {
4336
- await httpTransport.handleRequest(req, res, req.body);
4337
- });
4338
- this.app.delete(endpoint, async (req, res) => {
4339
- await httpTransport.handleRequest(req, res);
4340
- });
4341
- this.mcpMounted = true;
4342
- console.log(`[MCP] Server mounted at ${endpoint}`);
4343
- }
4344
- /**
4345
- * Start the Express server with MCP endpoints
4346
- *
4347
- * Initiates the server startup process by mounting MCP endpoints, configuring
4348
- * the inspector UI (if available), and starting the Express server to listen
4349
- * for incoming connections. This is the main entry point for running the server.
4350
- *
4351
- * The server will be accessible at the specified port with MCP endpoints at /mcp
4352
- * and inspector UI at /inspector (if the inspector package is installed).
4353
- *
4354
- * @param port - Port number to listen on (defaults to 3001 if not specified)
4355
- * @returns Promise that resolves when the server is successfully listening
4356
- *
4357
- * @example
4358
- * ```typescript
4359
- * await server.listen(8080)
4360
- * // Server now running at http://localhost:8080
4361
- * // MCP endpoints: http://localhost:8080/mcp
4362
- * // Inspector UI: http://localhost:8080/inspector
4363
- * ```
4364
- */
4365
- async listen(port) {
4366
- await this.mountMcp();
4367
- this.serverPort = port || 3001;
4368
- this.mountInspector();
4369
- this.app.listen(this.serverPort, () => {
4370
- console.log(`[SERVER] Listening on http://localhost:${this.serverPort}`);
4371
- console.log(`[MCP] Endpoints: http://localhost:${this.serverPort}/mcp`);
4372
- });
4373
- }
4374
- /**
4375
- * Mount MCP Inspector UI at /inspector
4376
- *
4377
- * Dynamically loads and mounts the MCP Inspector UI package if available, providing
4378
- * a web-based interface for testing and debugging MCP servers. The inspector
4379
- * automatically connects to the local MCP server endpoints.
4380
- *
4381
- * This method gracefully handles cases where the inspector package is not installed,
4382
- * allowing the server to function without the inspector in production environments.
4383
- *
4384
- * @private
4385
- * @returns void
4386
- *
4387
- * @example
4388
- * If @mcp-use/inspector is installed:
4389
- * - Inspector UI available at http://localhost:PORT/inspector
4390
- * - Automatically connects to http://localhost:PORT/mcp
4391
- *
4392
- * If not installed:
4393
- * - Server continues to function normally
4394
- * - No inspector UI available
4395
- */
4396
- mountInspector() {
4397
- if (this.inspectorMounted) return;
4398
- import("@mcp-use/inspector").then(({ mountInspector }) => {
4399
- const mcpServerUrl = `http://localhost:${this.serverPort}/mcp`;
4400
- mountInspector(this.app, "/inspector", mcpServerUrl);
4401
- this.inspectorMounted = true;
4402
- console.log(`[INSPECTOR] UI available at http://localhost:${this.serverPort}/inspector`);
4403
- }).catch(() => {
4404
- });
4405
- }
4406
- /**
4407
- * Setup default widget serving routes
4408
- *
4409
- * Configures Express routes to serve MCP UI widgets and their static assets.
4410
- * Widgets are served from the dist/resources/mcp-use/widgets directory and can
4411
- * be accessed via HTTP endpoints for embedding in web applications.
4412
- *
4413
- * Routes created:
4414
- * - GET /mcp-use/widgets/:widget - Serves widget's index.html
4415
- * - GET /mcp-use/widgets/:widget/assets/* - Serves widget-specific assets
4416
- * - GET /mcp-use/widgets/assets/* - Fallback asset serving with auto-discovery
4417
- *
4418
- * @private
4419
- * @returns void
4420
- *
4421
- * @example
4422
- * Widget routes:
4423
- * - http://localhost:3001/mcp-use/widgets/kanban-board
4424
- * - http://localhost:3001/mcp-use/widgets/todo-list/assets/style.css
4425
- * - http://localhost:3001/mcp-use/widgets/assets/script.js (auto-discovered)
4426
- */
4427
- setupWidgetRoutes() {
4428
- this.app.get("/mcp-use/widgets/:widget/assets/*", (req, res, next) => {
4429
- const widget = req.params.widget;
4430
- const assetFile = req.params[0];
4431
- const assetPath = (0, import_node_path2.join)(process.cwd(), "dist", "resources", "mcp-use", "widgets", widget, "assets", assetFile);
4432
- res.sendFile(assetPath, (err) => err ? next() : void 0);
4433
- });
4434
- this.app.get("/mcp-use/widgets/assets/*", (req, res, next) => {
4435
- const assetFile = req.params[0];
4436
- const widgetsDir = (0, import_node_path2.join)(process.cwd(), "dist", "resources", "mcp-use", "widgets");
4437
- try {
4438
- const widgets = (0, import_node_fs3.readdirSync)(widgetsDir);
4439
- for (const widget of widgets) {
4440
- const assetPath = (0, import_node_path2.join)(widgetsDir, widget, "assets", assetFile);
4441
- if ((0, import_node_fs3.existsSync)(assetPath)) {
4442
- return res.sendFile(assetPath);
4443
- }
4444
- }
4445
- next();
4446
- } catch {
4447
- next();
4448
- }
4449
- });
4450
- this.app.get("/mcp-use/widgets/:widget", (req, res, next) => {
4451
- const filePath = (0, import_node_path2.join)(process.cwd(), "dist", "resources", "mcp-use", "widgets", req.params.widget, "index.html");
4452
- res.sendFile(filePath, (err) => err ? next() : void 0);
4453
- });
4454
- }
4455
- /**
4456
- * Create input schema for resource templates
4457
- *
4458
- * Parses a URI template string to extract parameter names and generates a Zod
4459
- * validation schema for those parameters. Used internally for validating resource
4460
- * template parameters before processing requests.
4461
- *
4462
- * @param uriTemplate - URI template string with parameter placeholders (e.g., "/users/{id}/posts/{postId}")
4463
- * @returns Object mapping parameter names to Zod string schemas
4464
- *
4465
- * @example
4466
- * ```typescript
4467
- * const schema = this.createInputSchema("/users/{id}/posts/{postId}")
4468
- * // Returns: { id: z.string(), postId: z.string() }
4469
- * ```
4470
- */
4471
- createInputSchema(uriTemplate) {
4472
- const params = this.extractTemplateParams(uriTemplate);
4473
- const schema = {};
4474
- params.forEach((param) => {
4475
- schema[param] = import_zod7.z.string();
4476
- });
4477
- return schema;
4478
- }
4479
- /**
4480
- * Create input schema for tools
4481
- *
4482
- * Converts tool input definitions into Zod validation schemas for runtime validation.
4483
- * Supports common data types (string, number, boolean, object, array) and optional
4484
- * parameters. Used internally when registering tools with the MCP server.
4485
- *
4486
- * @param inputs - Array of input parameter definitions with name, type, and optional flag
4487
- * @returns Object mapping parameter names to Zod validation schemas
4488
- *
4489
- * @example
4490
- * ```typescript
4491
- * const schema = this.createToolInputSchema([
4492
- * { name: 'query', type: 'string', required: true },
4493
- * { name: 'limit', type: 'number', required: false }
4494
- * ])
4495
- * // Returns: { query: z.string(), limit: z.number().optional() }
4496
- * ```
4497
- */
4498
- createToolInputSchema(inputs) {
4499
- const schema = {};
4500
- inputs.forEach((input) => {
4501
- let zodType;
4502
- switch (input.type) {
4503
- case "string":
4504
- zodType = import_zod7.z.string();
4505
- break;
4506
- case "number":
4507
- zodType = import_zod7.z.number();
4508
- break;
4509
- case "boolean":
4510
- zodType = import_zod7.z.boolean();
4511
- break;
4512
- case "object":
4513
- zodType = import_zod7.z.object({});
4514
- break;
4515
- case "array":
4516
- zodType = import_zod7.z.array(import_zod7.z.any());
4517
- break;
4518
- default:
4519
- zodType = import_zod7.z.any();
4520
- }
4521
- if (!input.required) {
4522
- zodType = zodType.optional();
4523
- }
4524
- schema[input.name] = zodType;
4525
- });
4526
- return schema;
4527
- }
4528
- /**
4529
- * Create arguments schema for prompts
4530
- *
4531
- * Converts prompt argument definitions into Zod validation schemas for runtime validation.
4532
- * Supports common data types (string, number, boolean, object, array) and optional
4533
- * parameters. Used internally when registering prompt templates with the MCP server.
4534
- *
4535
- * @param inputs - Array of argument definitions with name, type, and optional flag
4536
- * @returns Object mapping argument names to Zod validation schemas
4537
- *
4538
- * @example
4539
- * ```typescript
4540
- * const schema = this.createPromptArgsSchema([
4541
- * { name: 'topic', type: 'string', required: true },
4542
- * { name: 'style', type: 'string', required: false }
4543
- * ])
4544
- * // Returns: { topic: z.string(), style: z.string().optional() }
4545
- * ```
4546
- */
4547
- createPromptArgsSchema(inputs) {
4548
- const schema = {};
4549
- inputs.forEach((input) => {
4550
- let zodType;
4551
- switch (input.type) {
4552
- case "string":
4553
- zodType = import_zod7.z.string();
4554
- break;
4555
- case "number":
4556
- zodType = import_zod7.z.number();
4557
- break;
4558
- case "boolean":
4559
- zodType = import_zod7.z.boolean();
4560
- break;
4561
- case "object":
4562
- zodType = import_zod7.z.object({});
4563
- break;
4564
- case "array":
4565
- zodType = import_zod7.z.array(import_zod7.z.any());
4566
- break;
4567
- default:
4568
- zodType = import_zod7.z.any();
4569
- }
4570
- if (!input.required) {
4571
- zodType = zodType.optional();
4572
- }
4573
- schema[input.name] = zodType;
4574
- });
4575
- return schema;
4576
- }
4577
- /**
4578
- * Extract parameter names from URI template
4579
- *
4580
- * Parses a URI template string to extract parameter names enclosed in curly braces.
4581
- * Used internally to identify dynamic parameters in resource templates and generate
4582
- * appropriate validation schemas.
4583
- *
4584
- * @param uriTemplate - URI template string with parameter placeholders (e.g., "/users/{id}/posts/{postId}")
4585
- * @returns Array of parameter names found in the template
4586
- *
4587
- * @example
4588
- * ```typescript
4589
- * const params = this.extractTemplateParams("/users/{id}/posts/{postId}")
4590
- * // Returns: ["id", "postId"]
4591
- * ```
4592
- */
4593
- extractTemplateParams(uriTemplate) {
4594
- const matches = uriTemplate.match(/\{([^}]+)\}/g);
4595
- return matches ? matches.map((match) => match.slice(1, -1)) : [];
4596
- }
4597
- /**
4598
- * Parse parameter values from a URI based on a template
4599
- *
4600
- * Extracts parameter values from an actual URI by matching it against a URI template.
4601
- * The template contains placeholders like {param} which are extracted as key-value pairs.
4602
- *
4603
- * @param template - URI template with placeholders (e.g., "user://{userId}/posts/{postId}")
4604
- * @param uri - Actual URI to parse (e.g., "user://123/posts/456")
4605
- * @returns Object mapping parameter names to their values
4606
- *
4607
- * @example
4608
- * ```typescript
4609
- * const params = this.parseTemplateUri("user://{userId}/posts/{postId}", "user://123/posts/456")
4610
- * // Returns: { userId: "123", postId: "456" }
4611
- * ```
4612
- */
4613
- parseTemplateUri(template, uri) {
4614
- const params = {};
4615
- let regexPattern = template.replace(/[.*+?^$()[\]\\|]/g, "\\$&");
4616
- const paramNames = [];
4617
- regexPattern = regexPattern.replace(/\\\{([^}]+)\\\}/g, (_, paramName) => {
4618
- paramNames.push(paramName);
4619
- return "([^/]+)";
4620
- });
4621
- const regex = new RegExp(`^${regexPattern}$`);
4622
- const match = uri.match(regex);
4623
- if (match) {
4624
- paramNames.forEach((paramName, index) => {
4625
- params[paramName] = match[index + 1];
4626
- });
4627
- }
4628
- return params;
4629
- }
4630
- };
4631
- function createMCPServer(name, config2 = {}) {
4632
- const instance = new McpServer({
4633
- name,
4634
- version: config2.version || "1.0.0",
4635
- description: config2.description
4636
- });
4637
- return instance;
4638
- }
4639
- __name(createMCPServer, "createMCPServer");
4640
-
4641
4071
  // src/oauth-helper.ts
4642
4072
  var OAuthHelper = class {
4643
4073
  static {
@@ -5986,7 +5416,6 @@ var import_messages3 = require("@langchain/core/messages");
5986
5416
  Telemetry,
5987
5417
  ToolMessage,
5988
5418
  WebSocketConnector,
5989
- createMCPServer,
5990
5419
  createOAuthMCPConfig,
5991
5420
  createReadableStreamFromGenerator,
5992
5421
  loadConfigFile,