@tanstack/ai
Version:
Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.
90 lines (82 loc) • 3 kB
text/typescript
import type { ServerTool } from '../tools/tool-definition'
/**
* The shape `readResource` resolves to — a structural subset of MCP's
* `ReadResourceResult`. Single source of truth shared by
* `MCPToolSource.readResource` (this file) and the tool-bound
* `McpToolAppMeta.readResource` (tool-calls.ts) so the two copies cannot drift.
*/
export interface McpResourceReadResult {
contents: Array<{
uri: string
mimeType?: string
text?: string
blob?: string
}>
}
/**
* Minimal structural shape that `chat({ mcp })` needs from an MCP client.
*
* `@tanstack/ai-mcp`'s `MCPClient` and `MCPClients` satisfy this interface by
* shape — the core `@tanstack/ai` package does NOT import `@tanstack/ai-mcp`
* (ai-mcp depends on ai, not the reverse).
*/
export interface MCPToolSource {
// Keep the options shape in sync with ai-mcp's `ToolsOptions` — extra
// optional fields added there still match structurally, but chat() only
// forwards what is declared here.
tools: (options?: { lazy?: boolean }) => Promise<Array<ServerTool>>
close: () => Promise<void>
/**
* Reads an MCP resource by URI. Used by the chat manager to eagerly fetch
* `ui://` resource widgets (MCP Apps) after a tool result resolves.
*
* Optional — sources that do not serve `ui://` resources need not implement
* this method. `ai-mcp`'s `MCPClient` satisfies this structurally.
*/
readResource?: (uri: string) => Promise<McpResourceReadResult>
}
/**
* Controls what happens to MCP connections when the chat run ends.
*
* - `'close'` (default) — `chat()` closes each connection when the run ends
* (after the agent loop completes and the stream is drained), so tools can
* still execute throughout the run.
* - `'keep-alive'` — `chat()` never closes the connections; the caller owns
* their lifecycle (e.g. keep them warm across requests).
*/
export type MCPConnectionPolicy = 'close' | 'keep-alive'
/**
* Options controlling MCP tool discovery and lifecycle for a `chat()` call.
*/
export interface ChatMCPOptions {
/**
* The MCP clients or client pools to discover tools from and manage.
*/
clients: Array<MCPToolSource>
/**
* Connection lifecycle policy applied to all clients when the run ends.
*
* Defaults to `'close'`.
*/
connection?: MCPConnectionPolicy
/**
* When `true`, tool schemas are fetched lazily (forwarded to
* `tools({ lazy: true })`).
*
* Defaults to `false`.
*/
lazyTools?: boolean
/**
* Called when tool discovery fails for a single source.
*
* - Throw (or re-throw) from this handler to fail the entire chat call fast.
* - Return normally to skip that source and continue with remaining clients.
* - Omit this handler entirely to rethrow the error (fail-fast by default).
*
* Async handlers are awaited, so a rejected promise also fails fast.
*/
onDiscoveryError?: (
error: unknown,
source: MCPToolSource,
) => void | Promise<void>
}