UNPKG

@tanstack/ai-mcp

Version:

Host-side Model Context Protocol client for TanStack AI: discover and run MCP server tools, resources, and prompts in any adapter's chat() loop, with generated end-to-end types.

63 lines (62 loc) 3.77 kB
import { Client, ClientOptions } from '@modelcontextprotocol/sdk/client/index.js'; import { TransportConfig } from './transport.js'; import { AnyToolDefinition, AutomaticDescriptor, DescriptorTools, MCPClientOptions, MappedServerTools, ServerDescriptor, ToolsOptions } from './types.js'; import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; import { GetPromptResult, Prompt, ReadResourceResult, Resource, ResourceTemplate } from '@modelcontextprotocol/sdk/types.js'; export interface MCPClient<TServer extends ServerDescriptor = AutomaticDescriptor> { readonly capabilities: TServer['capabilities']; /** * Auto-discovery: every server tool as a ServerTool. With a generated * descriptor, tool names are typed as the descriptor's name literals; * args/results stay untyped — use the `tools(defs)` overload for typed args. * * Both overloads yield {@link McpServerTool}s, so `tool.metadata.mcp` (the * server's title / annotations) is typed without an annotation or a cast. */ tools: { (options?: ToolsOptions): Promise<DescriptorTools<TServer>>; /** * Explicit: bind these TanStack toolDefinitions to the server (typed + * validated, allowlist). Note: when the client has a `prefix`, the * runtime tool name is `${prefix}_${def.name}` while the static `TName` * stays the unprefixed definition name. */ <const TDefs extends ReadonlyArray<AnyToolDefinition>>(defs: TDefs, options?: ToolsOptions): Promise<MappedServerTools<TDefs>>; }; resources: () => Promise<Array<Resource>>; readResource: (uri: string) => Promise<ReadResourceResult>; resourceTemplates: () => Promise<Array<ResourceTemplate>>; prompts: () => Promise<Array<Prompt>>; getPrompt: (name: string, args?: Record<string, string>) => Promise<GetPromptResult>; callTool: (name: string, args?: Record<string, unknown>) => Promise<Awaited<ReturnType<Client['callTool']>>>; /** * The ORIGINAL connection descriptor this client was created from — the * `transport` input and `prefix` passed to `createMCPClient`. Used by * `createMcpAppCallHandler` to reconnect per-call (serverless-safe) without * a separate transport-config map. * * `transport` is `undefined` when the client was built from a ready-made * `Transport` instance rather than a serializable config — either via * `createMCPClientFromTransport` (test-only) or `createMCPClient({ transport: * <instance> })`. A live `Transport` instance is single-use and cannot be * reconnected, so only serializable `TransportConfig`s are retained here. */ getInfo: () => { transport: TransportConfig | undefined; prefix: string | undefined; /** * The options this client was built with, so a caller that reconstructs it * from this descriptor keeps them. Without it a rebuilt client silently * reverts to the SDK defaults — including the AJV validator that edge * runtimes cannot compile. * * Optional so an existing hand-rolled `MCPClient` keeps compiling. */ clientOptions?: ClientOptions; }; close: () => Promise<void>; [Symbol.asyncDispose]: () => Promise<void>; } export declare function createMCPClient<TServer extends ServerDescriptor = AutomaticDescriptor>(options: MCPClientOptions): Promise<MCPClient<TServer>>; /** Test-only: connect directly from a transport instance (skips resolveTransport). */ export declare function createMCPClientFromTransport<TServer extends ServerDescriptor = AutomaticDescriptor>(transport: Transport, prefix?: string, clientOptions?: ClientOptions): Promise<MCPClient<TServer>>;