-
Notifications
You must be signed in to change notification settings - Fork 28
Feat/add server tool #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| npx lint-staged | ||
| npm run lint |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| /** | ||
| * Dynamic server management example for mcp-use. | ||
| * | ||
| * This example demonstrates how to equip an MCPAgent with a tool | ||
| * to dynamically add and connect to MCP servers during a run. | ||
| */ | ||
|
|
||
| import { ChatOpenAI } from '@langchain/openai' | ||
| import { config } from 'dotenv' | ||
| import { MCPAgent, MCPClient } from '../index.js' | ||
| import { LangChainAdapter } from '../src/adapters/langchain_adapter.js' | ||
| import { ServerManager } from '../src/managers/server_manager.js' | ||
|
|
||
| // Load environment variables from .env file | ||
| config() | ||
|
|
||
| async function main() { | ||
| // Create an empty MCPClient. It has no servers to start with. | ||
| const client = new MCPClient() | ||
|
|
||
| // The LLM to power the agent | ||
| const llm = new ChatOpenAI({ model: 'gpt-4o', temperature: 0 }) | ||
|
|
||
| // Create the agent, enabling the ServerManager | ||
| const agent = new MCPAgent({ | ||
| llm, | ||
| client, | ||
| maxSteps: 30, | ||
| useServerManager: true, | ||
| serverManagerFactory: client => new ServerManager(client, new LangChainAdapter()), | ||
| autoInitialize: true, | ||
| }) | ||
|
|
||
| // Define the server configuration that the agent will be asked to add. | ||
| const serverConfigA = { | ||
| command: 'npx', | ||
| args: ['@playwright/mcp@latest'], | ||
| env: { | ||
| DISPLAY: ':1', | ||
| }, | ||
| } | ||
| const serverConfigB = { | ||
| command: 'npx', | ||
| args: ['-y', '@openbnb/mcp-server-airbnb', '--ignore-robots-txt'], | ||
| } | ||
| // We'll pass the config as a JSON string in the prompt. | ||
| const serverConfigStringA = JSON.stringify(serverConfigA, null, 2) | ||
| const serverConfigStringB = JSON.stringify(serverConfigB, null, 2) | ||
|
|
||
| const query = `I need to browse the web. To do this, please add and connect to a new MCP server for Playwright. | ||
| The server name is 'playwright' and its configuration is: | ||
| \`\`\`json | ||
| ${serverConfigStringA} | ||
| \`\`\` | ||
| Once the server is ready, navigate to https://github.com/mcp-use/mcp-use, give a star to the project, and then provide a concise summary of the project's README. | ||
|
|
||
| Then, please add and connect to a new MCP server for Airbnb. | ||
| The server name is 'airbnb' and its configuration is: | ||
| \`\`\`json | ||
| ${serverConfigStringB} | ||
| \`\`\` | ||
| and give me a house in the location of the company mcp-use. | ||
| ` | ||
|
|
||
| // Run the agent. It will first use the AddMCPServerTool, then the tools from the new server. | ||
| const result = await agent.run(query) | ||
|
|
||
| console.log(`\n✅ Final Result:\n${result}`) | ||
|
|
||
| // Clean up the session created by the agent | ||
| await client.closeAllSessions() | ||
| } | ||
|
|
||
| if (import.meta.url === `file://${process.argv[1]}`) { | ||
| main().catch(console.error) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import type { StructuredToolInterface } from '@langchain/core/tools' | ||
| import type { ServerManager } from '../server_manager.js' | ||
| import { StructuredTool } from 'langchain/tools' | ||
| import { z } from 'zod' | ||
| import { logger } from '../../logging.js' | ||
|
|
||
| export class AddMCPServerTool extends StructuredTool { | ||
| name = 'add_mcp_server' | ||
| description | ||
| = 'Adds a new MCP server to the client and connects to it, making its tools available.' | ||
|
|
||
| schema = z.object({ | ||
| serverName: z.string().describe('The name for the new MCP server.'), | ||
| serverConfig: z | ||
| .any() | ||
| .describe( | ||
| 'The configuration object for the server. This should not include the top-level "mcpServers" key.', | ||
| ), | ||
| }) | ||
|
|
||
| private manager: ServerManager | ||
|
|
||
| constructor(manager: ServerManager) { | ||
| super() | ||
| this.manager = manager | ||
| } | ||
|
|
||
| protected async _call({ | ||
| serverName, | ||
| serverConfig, | ||
| }: z.infer<typeof this.schema>): Promise<string> { | ||
| try { | ||
| this.manager.client.addServer(serverName, serverConfig) | ||
| let result = `Server '${serverName}' added to the client.` | ||
| logger.debug( | ||
| `Connecting to new server '${serverName}' and discovering tools.`, | ||
| ) | ||
| const session = await this.manager.client.createSession(serverName) | ||
| const connector = session.connector | ||
| const tools: StructuredToolInterface[] | ||
| = await this.manager.adapter.createToolsFromConnectors([connector]) | ||
|
|
||
| this.manager.serverTools[serverName] = tools | ||
| this.manager.initializedServers[serverName] = true | ||
| this.manager.activeServer = serverName // Set as active server | ||
|
|
||
| const numTools = tools.length | ||
| result += ` Session created and connected. '${serverName}' is now the active server with ${numTools} tools available.` | ||
| result += `\n\n${tools.map(t => t.name).join('\n')}` | ||
| logger.info(result) | ||
| return result | ||
| } | ||
| catch (e: any) { | ||
| logger.error( | ||
| `Failed to add or connect to server '${serverName}': ${e.message}`, | ||
| ) | ||
| return `Failed to add or connect to server '${serverName}': ${e.message}` | ||
| } | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.