# MCP Client The `@agent-smith/core` package includes a Model Context Protocol (MCP) client implementation that connects to external MCP servers and exposes their tools as `ToolSpec` objects usable within agents. ## McpClient Class The `McpClient` class wraps the `@modelcontextprotocol/sdk` client to manage MCP server connections: ```typescript import { McpClient } from "@agent-smith/core"; const client = new McpClient( "filesystem", // server name "npx", // command ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"], // args null, // authorizedTools (null = all allowed) null // askUserTools (null = no confirmation needed) ); ``` ### Constructor Parameters | Parameter | Type | Description | |-----------|------|-------------| | `servername` | `string` | Human-readable name for the MCP server | | `command` | `string` | Executable command (e.g., `npx`, `python`) | | `args` | `Array` | Command arguments; supports `$MCP_AUTH` placeholder replaced by `MCP__AUTH` env var | | `authorizedTools` | `Array \| null` | Whitelist of tool names to expose (null = all) | | `askUserTools` | `Array \| null` | Tools that require user confirmation before execution | ## Connecting to MCP Servers ### Starting a Server ```typescript await client.start(); // Connects to the MCP server via stdio transport ``` The `start()` method initializes the stdio transport and connects the SDK client. The server runs as a child process with stdio communication. ### Stopping a Server ```typescript await client.stop(); // Closes the connection and terminates the server ``` ## Using MCP Tools Within Agents MCP tools are extracted from connected servers and added to an agent's tool list during execution: ```typescript import { useAgentExecutor } from "@agent-smith/core"; const executor = await useAgentExecutor("researcher", { prompt: "Find files matching pattern" }, {}); // MCP servers are started automatically and their tools are injected // into the agent's tool list before execution const result = await executor.execute(); ``` ### Tool Extraction The `extractTools()` method queries the MCP server for available tools and converts them to `ToolSpec` objects: ```typescript const tools = await client.extractTools({ confirmToolUsage }); // Returns: Array ``` For each tool from the server: 1. Filters by `authorizedTools` whitelist if specified 2. Extracts input schema properties as argument definitions with descriptions and types 3. Creates an `execute` function that calls `client.callTool()` with the tool name and arguments 4. Handles array-type arguments by parsing JSON strings 5. Adds `canRun` callback for tools in `askUserTools` (requires `confirmToolUsage` option) 6. Sets `parallelCalls: true` for all MCP tools ### Tool Spec Format MCP tools are converted to `ToolSpec` with the following structure: ```typescript const tool: ToolSpec = { type: "mcp", name: "read_file", description: "Read the contents of a file", arguments: { path: { description: "File path (string)" } }, parallelCalls: true, execute: async (args) => { // Calls the MCP server's tool return await client.callTool({ name: "read_file", arguments: args }); }, canRun: async (toolCall) => { // User confirmation callback (if in askUserTools) return await confirmToolUsage(toolCall); } }; ``` ## Configuration and Setup ### Environment Variables for Authentication MCP servers that require authentication use environment variables: ```bash export MCP_FILESYSTEM_AUTH="Bearer my-token" ``` The constructor replaces `$MCP_AUTH` placeholders in args with the corresponding env variable: ```typescript const client = new McpClient( "filesystem", "npx", ["-y", "@modelcontextprotocol/server-filesystem", "Authorization:$MCP_AUTH"] ); // Resolves to: npx -y @modelcontextprotocol/server-filesystem Authorization:Bearer my-token ``` ### Error Handling The constructor throws if an authorization environment variable is missing: ```typescript // Throws: Error("Env variable MCP_FILESYSTEM_AUTH not found for filesystem mcp auth") ``` Tool extraction throws if `askUserTools` contains tools but no `confirmToolUsage` callback is provided: ```typescript // Throws: Error("provide a tool usage confirm function") ``` ## API Reference ### `McpClient` Class | Method | Signature | Description | |--------|-----------|-------------| | `constructor()` | `(servername, command, args, authorizedTools?, askUserTools?)` | Create a new MCP client instance | | `start()` | `async () => Promise` | Connect to the MCP server | | `stop()` | `async () => Promise` | Close the connection | | `extractTools()` | `async (options) => Promise>` | Extract and convert server tools to ToolSpec objects | ### Properties | Property | Type | Description | |----------|------|-------------| | `name` | `string` | Server name | | `tools` | `Record` | Cached tool specs keyed by name | | `authorizedTools` | `Array \| null` | Tool whitelist | | `askUserTools` | `Array \| null` | Tools requiring confirmation | ## Integration with Agent Execution MCP servers are started and their tools injected during agent execution in `useAgentExecutor()`: ```typescript // Inside useAgentExecutor(): for (const mcp of mcpServers) { await mcp.start(); const _tools = await mcp.extractTools(localOptions); _tools.forEach(t => agentSpec.tools?.push(t)); } ``` This allows agents to discover and use external tools at runtime without requiring them to be defined in YAML feature files. ← Back: Get Started