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.

85 lines (76 loc) • 2.43 kB
import { SSEClientTransport, StreamableHTTPClientTransport, } from '@modelcontextprotocol/client' import type { OAuthClientProvider, Transport, } from '@modelcontextprotocol/client' export interface HttpTransportConfig { type: 'http' url: string headers?: Record<string, string> fetch?: typeof fetch authProvider?: OAuthClientProvider } export interface SseTransportConfig { type: 'sse' url: string headers?: Record<string, string> fetch?: typeof fetch authProvider?: OAuthClientProvider } /** stdio is declared here for typing but constructed only via `@tanstack/ai-mcp/stdio`. */ export interface StdioTransportConfig { type: 'stdio' command: string args?: Array<string> env?: Record<string, string> cwd?: string } export type TransportConfig = | HttpTransportConfig | SseTransportConfig | StdioTransportConfig /** Either a built-in config or a ready-made Transport instance (escape hatch). */ export type TransportInput = TransportConfig | Transport /** * Return true when `input` is already a Transport, not a config object. */ export function isTransportInstance(input: TransportInput): input is Transport { return 'start' in input && typeof input.start === 'function' } /** * Build a Transport from HTTP config, SSE config, or an existing Transport. * * For stdio, build the Transport with `stdioTransport` and pass that instance. * Throws an Error when the config type is `stdio` or is not a known type. */ export async function resolveTransport(input: TransportInput) { if (isTransportInstance(input)) return input switch (input.type) { case 'http': return new StreamableHTTPClientTransport(new URL(input.url), { requestInit: { headers: input.headers }, fetch: input.fetch, authProvider: input.authProvider, }) case 'sse': return new SSEClientTransport(new URL(input.url), { requestInit: { headers: input.headers }, fetch: input.fetch, authProvider: input.authProvider, }) case 'stdio': throw new Error( "stdio transport must be created via '@tanstack/ai-mcp/stdio': " + "import { stdioTransport } from '@tanstack/ai-mcp/stdio' and pass the result as `transport`.", ) default: { const unknownConfig: never = input throw new Error( `Unknown MCP transport config: ${JSON.stringify(unknownConfig)}`, ) } } }