mcp-use 0.1.8 → 0.1.10

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.
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Structured Output Example - City Research with Playwright
3
+ *
4
+ * This example demonstrates intelligent structured output by researching Padova, Italy.
5
+ * The agent becomes schema-aware and will intelligently retry to gather missing
6
+ * information until all required fields can be populated.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=structured_output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured_output.d.ts","sourceRoot":"","sources":["../../examples/structured_output.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Structured Output Example - City Research with Playwright
3
+ *
4
+ * This example demonstrates intelligent structured output by researching Padova, Italy.
5
+ * The agent becomes schema-aware and will intelligently retry to gather missing
6
+ * information until all required fields can be populated.
7
+ */
8
+ import { ChatOpenAI } from '@langchain/openai';
9
+ import { config } from 'dotenv';
10
+ import { z } from 'zod';
11
+ import { MCPAgent, MCPClient } from '../index.js';
12
+ // Load environment variables from .env file
13
+ config();
14
+ // Define the structured output schema using Zod
15
+ const CityInfoSchema = z.object({
16
+ name: z.string().describe('Official name of the city'),
17
+ country: z.string().describe('Country where the city is located'),
18
+ region: z.string().describe('Region or state within the country'),
19
+ population: z.number().describe('Current population count'),
20
+ area_km2: z.number().describe('Area in square kilometers'),
21
+ foundation_date: z.string().describe('When the city was founded (approximate year or period)'),
22
+ mayor: z.string().describe('Current mayor or city leader'),
23
+ famous_landmarks: z.array(z.string()).describe('List of famous landmarks, monuments, or attractions'),
24
+ universities: z.array(z.string()).describe('List of major universities or educational institutions'),
25
+ economy_sectors: z.array(z.string()).describe('Main economic sectors or industries'),
26
+ sister_cities: z.array(z.string()).describe('Twin cities or sister cities partnerships'),
27
+ historical_significance: z.string().describe('Brief description of historical importance'),
28
+ climate_type: z.string().nullable().describe('Type of climate (e.g., Mediterranean, Continental)'),
29
+ elevation_meters: z.number().nullable().describe('Elevation above sea level in meters'),
30
+ });
31
+ async function main() {
32
+ const mcpConfig = {
33
+ mcpServers: {
34
+ playwright: {
35
+ command: 'npx',
36
+ args: ['@playwright/mcp@latest'],
37
+ env: {
38
+ DISPLAY: ':1',
39
+ },
40
+ },
41
+ },
42
+ };
43
+ const client = new MCPClient(mcpConfig);
44
+ const llm = new ChatOpenAI({ model: 'gpt-4o' });
45
+ const agent = new MCPAgent({ llm, client, maxSteps: 50, memoryEnabled: true });
46
+ try {
47
+ // Use structured output with intelligent retry
48
+ // The agent will:
49
+ // 1. Know exactly what information it needs to collect
50
+ // 2. Attempt structured output at finish points
51
+ // 3. Continue execution if required information is missing
52
+ // 4. Only finish when all required fields can be populated
53
+ const result = await agent.run(`
54
+ Research comprehensive information about the city of Padova (also known as Padua) in Italy.
55
+
56
+ Visit multiple reliable sources like Wikipedia, official city websites, tourism sites,
57
+ and university websites to gather detailed information including demographics, history,
58
+ governance, education, economy, landmarks, and international relationships.
59
+ `, 50, // maxSteps
60
+ true, // manageConnector
61
+ [], // externalHistory
62
+ CityInfoSchema);
63
+ // Now you have strongly-typed, validated data!
64
+ console.log(`Name: ${result.name}`);
65
+ console.log(`Country: ${result.country}`);
66
+ console.log(`Region: ${result.region}`);
67
+ console.log(`Population: ${result.population.toLocaleString()}`);
68
+ console.log(`Area: ${result.area_km2} km²`);
69
+ console.log(`Foundation: ${result.foundation_date}`);
70
+ console.log(`Mayor: ${result.mayor}`);
71
+ console.log(`Universities: ${result.universities.join(', ')}`);
72
+ console.log(`Economy: ${result.economy_sectors.join(', ')}`);
73
+ console.log(`Landmarks: ${result.famous_landmarks.join(', ')}`);
74
+ console.log(`Sister Cities: ${result.sister_cities.length > 0 ? result.sister_cities.join(', ') : 'None'}`);
75
+ console.log(`Historical Significance: ${result.historical_significance}`);
76
+ if (result.climate_type) {
77
+ console.log(`Climate: ${result.climate_type}`);
78
+ }
79
+ if (result.elevation_meters !== null) {
80
+ console.log(`Elevation: ${result.elevation_meters} meters`);
81
+ }
82
+ }
83
+ catch (error) {
84
+ console.error('Error:', error);
85
+ }
86
+ finally {
87
+ await agent.close();
88
+ }
89
+ }
90
+ // Handle unhandled promise rejections
91
+ process.on('unhandledRejection', (reason, promise) => {
92
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
93
+ process.exit(1);
94
+ });
95
+ main().catch(console.error);
@@ -3,6 +3,7 @@ import type { BaseMessage } from '@langchain/core/messages';
3
3
  import type { StructuredToolInterface } from '@langchain/core/tools';
4
4
  import type { StreamEvent } from '@langchain/core/tracers/log_stream';
5
5
  import type { AgentStep } from 'langchain/agents';
6
+ import type { z } from 'zod';
6
7
  import type { MCPClient } from '../client.js';
7
8
  import type { BaseConnector } from '../connectors/base.js';
8
9
  import { SystemMessage } from '@langchain/core/messages';
@@ -65,15 +66,28 @@ export declare class MCPAgent {
65
66
  * Runs the agent and returns a promise for the final result.
66
67
  */
67
68
  run(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[]): Promise<string>;
69
+ /**
70
+ * Runs the agent with structured output and returns a promise for the typed result.
71
+ */
72
+ run<T>(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[], outputSchema?: z.ZodSchema<T>): Promise<T>;
68
73
  /**
69
74
  * Runs the agent and yields intermediate steps as an async generator.
75
+ * If outputSchema is provided, returns structured output of type T.
70
76
  */
71
- stream(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[]): AsyncGenerator<AgentStep, string, void>;
77
+ stream<T = string>(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[], outputSchema?: z.ZodSchema<T>): AsyncGenerator<AgentStep, string | T, void>;
72
78
  close(): Promise<void>;
73
79
  /**
74
80
  * Yields LangChain StreamEvent objects from the underlying streamEvents() method.
75
81
  * This provides token-level streaming and fine-grained event updates.
76
82
  */
77
83
  streamEvents(query: string, maxSteps?: number, manageConnector?: boolean, externalHistory?: BaseMessage[]): AsyncGenerator<StreamEvent, void, void>;
84
+ /**
85
+ * Attempt to create structured output from raw result with validation.
86
+ */
87
+ private _attemptStructuredOutput;
88
+ /**
89
+ * Enhance the query with schema information to make the agent aware of required fields.
90
+ */
91
+ private _enhanceQueryWithSchema;
78
92
  }
79
93
  //# sourceMappingURL=mcp_agent.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mcp_agent.d.ts","sourceRoot":"","sources":["../../../src/agents/mcp_agent.ts"],"names":[],"mappings":"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"}
@@ -211,23 +211,54 @@ export class MCPAgent {
211
211
  }
212
212
  }
213
213
  }
214
- /**
215
- * Runs the agent and returns a promise for the final result.
216
- */
217
- async run(query, maxSteps, manageConnector, externalHistory) {
218
- const generator = this.stream(query, maxSteps, manageConnector, externalHistory);
214
+ async run(query, maxSteps, manageConnector, externalHistory, outputSchema) {
215
+ const generator = this.stream(query, maxSteps, manageConnector, externalHistory, outputSchema);
219
216
  return this._consumeAndReturn(generator);
220
217
  }
221
218
  /**
222
219
  * Runs the agent and yields intermediate steps as an async generator.
220
+ * If outputSchema is provided, returns structured output of type T.
223
221
  */
224
- async *stream(query, maxSteps, manageConnector = true, externalHistory) {
222
+ async *stream(query, maxSteps, manageConnector = true, externalHistory, outputSchema) {
225
223
  let result = '';
226
224
  let initializedHere = false;
227
225
  const startTime = Date.now();
228
226
  const toolsUsedNames = [];
229
227
  let stepsTaken = 0;
230
228
  let success = false;
229
+ // Schema-aware setup for structured output
230
+ let structuredLlm = null;
231
+ let schemaDescription = '';
232
+ if (outputSchema) {
233
+ query = this._enhanceQueryWithSchema(query, outputSchema);
234
+ // Check if withStructuredOutput method exists
235
+ if ('withStructuredOutput' in this.llm && typeof this.llm.withStructuredOutput === 'function') {
236
+ structuredLlm = this.llm.withStructuredOutput(outputSchema);
237
+ }
238
+ else {
239
+ // Fallback: use the same LLM but we'll handle structure in our helper method
240
+ structuredLlm = this.llm;
241
+ }
242
+ // Get schema description for feedback
243
+ try {
244
+ const schemaType = outputSchema;
245
+ if (schemaType._def && schemaType._def.shape) {
246
+ const fields = [];
247
+ for (const [key, fieldSchema] of Object.entries(schemaType._def.shape)) {
248
+ const field = fieldSchema;
249
+ const isOptional = field.isOptional?.() ?? field._def?.typeName === 'ZodOptional';
250
+ const isNullable = field.isNullable?.() ?? field._def?.typeName === 'ZodNullable';
251
+ const description = field._def?.description || field.description || key;
252
+ fields.push(`- ${key}: ${description} ${(isOptional || isNullable) ? '(optional)' : '(required)'}`);
253
+ }
254
+ schemaDescription = fields.join('\n');
255
+ }
256
+ }
257
+ catch (e) {
258
+ logger.warn(`Could not extract schema details: ${e}`);
259
+ schemaDescription = `Schema: ${outputSchema.constructor.name}`;
260
+ }
261
+ }
231
262
  try {
232
263
  if (manageConnector && !this._initialized) {
233
264
  await this.initialize();
@@ -284,7 +315,46 @@ export class MCPAgent {
284
315
  if (nextStepOutput.returnValues) {
285
316
  logger.info(`✅ Agent finished at step ${stepNum + 1}`);
286
317
  result = nextStepOutput.returnValues?.output ?? 'No output generated';
287
- break;
318
+ // If structured output is requested, attempt to create it
319
+ if (outputSchema && structuredLlm) {
320
+ try {
321
+ logger.info('🔧 Attempting structured output...');
322
+ const structuredResult = await this._attemptStructuredOutput(result, structuredLlm, outputSchema, schemaDescription);
323
+ // Add the final response to conversation history if memory is enabled
324
+ if (this.memoryEnabled) {
325
+ this.addToHistory(new AIMessage(`Structured result: ${JSON.stringify(structuredResult)}`));
326
+ }
327
+ logger.info('✅ Structured output successful');
328
+ success = true;
329
+ return structuredResult;
330
+ }
331
+ catch (e) {
332
+ logger.warn(`⚠️ Structured output failed: ${e}`);
333
+ // Continue execution to gather missing information
334
+ const missingInfoPrompt = `
335
+ The current result cannot be formatted into the required structure.
336
+ Error: ${String(e)}
337
+
338
+ Current information: ${result}
339
+
340
+ Please continue working to gather the missing information needed for:
341
+ ${schemaDescription}
342
+
343
+ Focus on finding the specific missing details.
344
+ `;
345
+ // Add this as feedback and continue the loop
346
+ inputs.input = missingInfoPrompt;
347
+ if (this.memoryEnabled) {
348
+ this.addToHistory(new HumanMessage(missingInfoPrompt));
349
+ }
350
+ logger.info('🔄 Continuing execution to gather missing information...');
351
+ continue;
352
+ }
353
+ }
354
+ else {
355
+ // Regular execution without structured output
356
+ break;
357
+ }
288
358
  }
289
359
  const stepArray = nextStepOutput;
290
360
  intermediateSteps.push(...stepArray);
@@ -333,11 +403,31 @@ export class MCPAgent {
333
403
  logger.warn(`⚠️ Agent stopped after reaching max iterations (${steps})`);
334
404
  result = `Agent stopped after reaching the maximum number of steps (${steps}).`;
335
405
  }
336
- if (this.memoryEnabled) {
406
+ // If structured output was requested but not achieved, attempt one final time
407
+ if (outputSchema && structuredLlm && !success) {
408
+ try {
409
+ logger.info('🔧 Final attempt at structured output...');
410
+ const structuredResult = await this._attemptStructuredOutput(result, structuredLlm, outputSchema, schemaDescription);
411
+ // Add the final response to conversation history if memory is enabled
412
+ if (this.memoryEnabled) {
413
+ this.addToHistory(new AIMessage(`Structured result: ${JSON.stringify(structuredResult)}`));
414
+ }
415
+ logger.info('✅ Final structured output successful');
416
+ success = true;
417
+ return structuredResult;
418
+ }
419
+ catch (e) {
420
+ logger.error(`❌ Final structured output attempt failed: ${e}`);
421
+ throw new Error(`Failed to generate structured output after ${steps} steps: ${e}`);
422
+ }
423
+ }
424
+ // Add the final response to conversation history if memory is enabled (regular case)
425
+ if (this.memoryEnabled && !outputSchema) {
337
426
  this.addToHistory(new AIMessage(result));
338
427
  }
339
428
  logger.info('🎉 Agent execution complete');
340
429
  success = true;
430
+ // Return regular result
341
431
  return result;
342
432
  }
343
433
  catch (e) {
@@ -424,6 +514,7 @@ export class MCPAgent {
424
514
  let success = false;
425
515
  let eventCount = 0;
426
516
  let totalResponseLength = 0;
517
+ let finalResponse = '';
427
518
  try {
428
519
  // Initialize if needed
429
520
  if (manageConnector && !this._initialized) {
@@ -471,17 +562,21 @@ export class MCPAgent {
471
562
  totalResponseLength += event.data.chunk.content.length;
472
563
  }
473
564
  yield event;
474
- // Handle final message for history
565
+ // Capture final response from chain end event
475
566
  if (event.event === 'on_chain_end' && event.data?.output) {
476
567
  const output = event.data.output;
477
- if (typeof output === 'string' && this.memoryEnabled) {
478
- this.addToHistory(new AIMessage(output));
568
+ if (typeof output === 'string') {
569
+ finalResponse = output;
479
570
  }
480
- else if (output?.output && typeof output.output === 'string' && this.memoryEnabled) {
481
- this.addToHistory(new AIMessage(output.output));
571
+ else if (output?.output && typeof output.output === 'string') {
572
+ finalResponse = output.output;
482
573
  }
483
574
  }
484
575
  }
576
+ // Add the final AI response to conversation history if memory is enabled
577
+ if (this.memoryEnabled && finalResponse) {
578
+ this.addToHistory(new AIMessage(finalResponse));
579
+ }
485
580
  logger.info(`🎉 StreamEvents complete - ${eventCount} events emitted`);
486
581
  success = true;
487
582
  }
@@ -532,4 +627,86 @@ export class MCPAgent {
532
627
  }
533
628
  }
534
629
  }
630
+ /**
631
+ * Attempt to create structured output from raw result with validation.
632
+ */
633
+ async _attemptStructuredOutput(rawResult, structuredLlm, outputSchema, schemaDescription) {
634
+ const formatPrompt = `
635
+ Please format the following information according to the specified schema.
636
+ Extract and structure the relevant information from the content below.
637
+
638
+ Required schema fields:
639
+ ${schemaDescription}
640
+
641
+ Content to format:
642
+ ${rawResult}
643
+
644
+ Please provide the information in the requested structured format.
645
+ If any required information is missing, you must indicate this clearly.
646
+ `;
647
+ const structuredResult = await structuredLlm.invoke(formatPrompt);
648
+ // Validate that the result is complete (basic check)
649
+ try {
650
+ // Use Zod to validate the structured result
651
+ const validatedResult = outputSchema.parse(structuredResult);
652
+ // Additional validation for required fields
653
+ const schemaType = outputSchema;
654
+ if (schemaType._def && schemaType._def.shape) {
655
+ for (const [fieldName, fieldSchema] of Object.entries(schemaType._def.shape)) {
656
+ const field = fieldSchema;
657
+ const isOptional = field.isOptional?.() ?? field._def?.typeName === 'ZodOptional';
658
+ const isNullable = field.isNullable?.() ?? field._def?.typeName === 'ZodNullable';
659
+ if (!isOptional && !isNullable) {
660
+ const value = validatedResult[fieldName];
661
+ if (value === null || value === undefined
662
+ || (typeof value === 'string' && !value.trim())
663
+ || (Array.isArray(value) && value.length === 0)) {
664
+ throw new Error(`Required field '${fieldName}' is missing or empty`);
665
+ }
666
+ }
667
+ }
668
+ }
669
+ return validatedResult;
670
+ }
671
+ catch (e) {
672
+ logger.debug(`Validation details: ${e}`);
673
+ throw e; // Re-raise to trigger retry logic
674
+ }
675
+ }
676
+ /**
677
+ * Enhance the query with schema information to make the agent aware of required fields.
678
+ */
679
+ _enhanceQueryWithSchema(query, outputSchema) {
680
+ const schemaFields = [];
681
+ try {
682
+ // Get field information from the schema
683
+ const schemaType = outputSchema;
684
+ if (schemaType._def && schemaType._def.shape) {
685
+ for (const [fieldName, fieldSchema] of Object.entries(schemaType._def.shape)) {
686
+ const field = fieldSchema;
687
+ const description = field._def?.description || field.description || fieldName;
688
+ const isOptional = field.isOptional?.() ?? field._def?.typeName === 'ZodOptional';
689
+ const isNullable = field.isNullable?.() ?? field._def?.typeName === 'ZodNullable';
690
+ schemaFields.push(`- ${fieldName}: ${description} ${(isOptional || isNullable) ? '(optional)' : '(required)'}`);
691
+ }
692
+ }
693
+ const schemaDescription = schemaFields.join('\n');
694
+ // Enhance the query with schema awareness
695
+ const enhancedQuery = `
696
+ ${query}
697
+
698
+ IMPORTANT: Your response must include sufficient information to populate the following structured output:
699
+
700
+ ${schemaDescription}
701
+
702
+ Make sure you gather ALL the required information during your task execution.
703
+ If any required information is missing, continue working to find it.
704
+ `;
705
+ return enhancedQuery;
706
+ }
707
+ catch (e) {
708
+ logger.warn(`Could not extract schema details: ${e}`);
709
+ return query;
710
+ }
711
+ }
535
712
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mcp-use",
3
3
  "type": "module",
4
- "version": "0.1.8",
4
+ "version": "0.1.10",
5
5
  "packageManager": "pnpm@10.6.1",
6
6
  "description": "A utility library for integrating Model Context Protocol (MCP) with LangChain, Zod, and related tools. Provides helpers for schema conversion, event streaming, and SDK usage.",
7
7
  "author": "Zane",
@@ -73,7 +73,8 @@
73
73
  "example:sandbox": "npm run build && node dist/examples/sandbox_everything.js",
74
74
  "example:oauth": "npm run build && node dist/examples/simple_oauth_example.js",
75
75
  "example:blender": "npm run build && node dist/examples/blender_use.js",
76
- "example:add_server": "npm run build && node dist/examples/add_server_tool.js"
76
+ "example:add_server": "npm run build && node dist/examples/add_server_tool.js",
77
+ "example:structured": "npm run build && node dist/examples/structured_output.js"
77
78
  },
78
79
  "dependencies": {
79
80
  "@dmitryrechkin/json-schema-to-zod": "^1.0.1",