TanStack AI: Your MCP, your way TanStack released @tanstack/ai-mcp, a host-side Model Context Protocol client that converts any MCP server into standard ServerTool arrays for use with any AI adapter or agent loop. The library, built on the official @modelcontextprotocol/sdk, supports edge-deployable Streamable HTTP transport and offers flexible configuration including multi-server pooling, tool prefixing, and optional codegen for strict typing. by Alem Tuzlak on Jun 5, 2026. Most "we support MCP now" announcements hand you exactly one way to use it. Connect to a server, get some tools, hope the lifecycle works out. @tanstack/ai-mcp takes the opposite stance. It is a host-side Model Context Protocol client that turns any MCP server into ordinary ServerTool you spread into chat . Because the output is just tools, every layer above it stays the same: any adapter OpenAI, Anthropic, Gemini, Ollama , any agent loop, any framework integration. TanStack AI never knows MCP was involved. That single design decision is what lets you use MCP your way : one server or fifty, fully managed or hand-wired, untyped-and-fast or generated-and-strict. This post walks the entire surface, every flag and every config, with the exact types from the package. Built on the official @modelcontextprotocol/sdk, the runtime stays edge-deployable. The Streamable HTTP transport is node:-free, the Node-only stdio transport is isolated behind a subpath, and the codegen CLI's heavy dependencies are bundled into the bin only, never into the library you ship. There is exactly one idea to internalize: An MCP client is a tool factory. You get back ServerTool . You spread them into chat { tools } . js import { chat } from '@tanstack/ai' import { openaiText } from '@tanstack/ai-openai/adapters' import { createMCPClient } from '@tanstack/ai-mcp' const mcp = await createMCPClient { transport: { type: 'http', url: process.env.MCP URL }, } const stream = chat { adapter: openaiText 'gpt-5.5' , messages, tools: await mcp.tools , } await mcp.close js import { chat } from '@tanstack/ai' import { openaiText } from '@tanstack/ai-openai/adapters' import { createMCPClient } from '@tanstack/ai-mcp' const mcp = await createMCPClient { transport: { type: 'http', url: process.env.MCP URL }, } const stream = chat { adapter: openaiText 'gpt-5.5' , messages, tools: await mcp.tools , } await mcp.close Everything else in this post is a variation on that line: how you build the client, how you type the tools, how many servers you fan in, and who owns close . php flowchart LR S1 MCP server -- |callTool| C1 createMCPClient S2 MCP server -- P createMCPClients pool S3 MCP server -- P C1 -- |ServerTool array| CHAT "chat { tools } or chat { mcp } " P -- |prefixed ServerTool array| CHAT CLI npx @tanstack/ai-mcp generate -.- |compile-time types| C1 CLI -.- |compile-time types| P CHAT -- ADP any adapter: OpenAI / Anthropic / Gemini / Ollama MCP tool execution is server-side only. createMCPClient lives in a server route or serverless function, never in browser code. A single client connects to a single server. The options are small and every field is load-bearing. interface MCPClientOptions { transport: TransportInput // config object or a raw SDK Transport prefix?: string // tool-name prefix, e.g. 'github' - 'github search' name?: string // client identity sent to the server default 'tanstack-ai-mcp' version?: string // client version default '0.0.1' } interface MCPClientOptions { transport: TransportInput // config object or a raw SDK Transport prefix?: string // tool-name prefix, e.g. 'github' - 'github search' name?: string // client identity sent to the server default 'tanstack-ai-mcp' version?: string // client version default '0.0.1' } The returned MCPClient exposes the full protocol surface: interface MCPClient { readonly capabilities: Record