/** * mockMcpClient — in-memory MCP client for development and tests. * * const slack = mockMcpClient({ * tools: [ * { * name: 'send_message', * description: 'Post a message to a channel', * inputSchema: { type: 'object' }, * handler: async ({ text }) => `Posted: ${text}`, * }, * ], * }); * * const agent = Agent.create({ provider: mock({ reply: 'ok' }) }) * .tools(await slack.tools()) * .build(); * * Pattern: Adapter (GoF) — produces an `McpClient` with the same shape * as `mcpClient(opts)` but driven by an in-memory tool table * instead of the MCP SDK + transport. Drop-in for development: * start with `mockMcpClient`, swap to `mcpClient` once the * real server is ready. * * Why public: `mcpClient`'s `_client` injection is `@internal` because * the SDK shape isn't a stable public surface. `mockMcpClient` exposes * a curated tool-handler shape that's tied to OUR Tool contract instead * — stable, documented, and the right level of abstraction for * mock-first development. */ import type { McpClient } from './types.js'; /** A scripted tool exposed by the mock MCP server. */ export interface MockMcpTool { /** Tool name as the LLM sees it. */ readonly name: string; /** Description surfaced to the LLM via the tool schema. */ readonly description?: string; /** * JSON-schema-like input schema. Passed through to the agent's tool * registry verbatim — same as a real MCP server's `listTools()`. */ readonly inputSchema: Readonly>; /** * Async handler that runs when the agent calls this tool. Receives * the args the LLM produced; returns the string result the agent * sees as the tool-result message. * * Defaults to `async () => '[mock result]'` when omitted — useful * when the consumer cares about wiring not behavior. */ readonly handler?: (args: Record) => Promise; } export interface MockMcpClientOptions { /** Logical server name. Surfaces in observability + error messages. */ readonly name?: string; /** Tools exposed by the mock server. */ readonly tools: readonly MockMcpTool[]; } /** * Build an in-memory `McpClient`. Useful when you want to develop * against MCP semantics without spawning subprocesses, hitting the * network, or installing `@modelcontextprotocol/sdk`. Same `McpClient` * shape as `mcpClient(opts)` — code that consumes one accepts the other. */ export declare function mockMcpClient(options: MockMcpClientOptions): McpClient;