feat: add connectMCPTools() to register MCP server tools as standard agent tools#89
Conversation
|
Two blockers: 1.
2. MCP
The fix isn't bad: MCP SDK's Smaller stuff, not blocking:
|
|
I've committed the changes. I implemented the approach you outlined: Client.listTools() / tools/list inputSchema is forwarded into LLMToolDef.inputSchema as plain JSON Schema, while inputSchema on the tool stays z.any() so ToolExecutor still does a normal safeParse passthrough and the MCP server remains the source of truth for real validation. One small design choice vs. wiring it only inside mcp.ts: I added an optional llmInputSchema on ToolDefinition (and on defineTool’s config). ToolRegistry.toToolDefs() uses tool.llmInputSchema ?? zodToJsonSchema(tool.inputSchema), so MCP tools bypass Zod for the LLM payload without special-casing the registry. Same idea as “stuff the raw JSON Schema into LLMToolDef.inputSchema,” just stored on the tool def until conversion. We don’t assume the server always returns only { type: 'object', properties, required } - we pass through any object-shaped inputSchema from the list response; if it’s missing or not a plain object, we fall back to { type: 'object' } so we never send undefined into the LLM slot. toLLMTools() was updated to respect llmInputSchema as well, and its input_schema typing was loosened to Record<string, unknown> so full MCP-style schemas type-check. If anything in the above diverges from what you had in mind for the PR, happy to align. |
|
All blockers from round 1 resolved. Merging. |
What
Introduces
connectMCPTools(), a utility to connect to an MCP (Model Context Protocol) server, discover its tools, and register them as standardToolDefinitions in the existingToolRegistry. Supports stdio transport and returns adisconnect()handle for lifecycle management.Why
Manual wrapping of MCP servers via
defineTool()is unnecessary friction. This change allows agents to consume MCP tools with minimal setup, streamlining multi-agent workflows and external tool integration.Closes #86
Checklist
connectMCPTools(config)implemented and returnsToolDefinition[]+disconnect()@modelcontextprotocol/sdkadded as optional peer dependencynpm run lintandnpm testpass