Docs
CodeRabbit
Cloudflare
Railway
Netlify
AG Grid
OpenRouter
WorkOS
Clerk
SerpAPI
Electric
Prisma
Sentry
Unkey
CodeRabbit
Cloudflare
Railway
Netlify
AG Grid
OpenRouter
WorkOS
Clerk
SerpAPI
Electric
Prisma
Sentry
Unkey
Class References
Function References
Interface References
Type Alias References
Variable References
MCP

MCP Type Generation

You have a running MCP server and you call its tools through createMCPClient, but nothing checks the tool names you reference at compile time. By the end of this guide you'll have generated per-server interface types from the live server and wired them into createMCPClient, narrowing discovered tool names to the server's literal names and compile-checking pool config keys — with zero runtime overhead. This is Mode 3 of MCP type safety. (Tool arguments stay untyped on the discovery path — for Zod-validated, TypeScript-typed arguments, combine with the tools([toolDefinition(...)]) overload.)

The generate CLI introspects a live MCP server and emits TypeScript interface types that you pass as a generic to createMCPClient / createMCPClients.

1. Create mcp.config.ts

Declare each server you want to generate types for. The defineConfig helper gives the config file full type checking and autocomplete.

ts
// mcp.config.ts
import { defineConfig } from '@tanstack/ai-mcp'

export default defineConfig({
  servers: {
    github: {
      transport: { type: 'http', url: 'https://github-mcp.example.com/mcp' },
    },
    linear: {
      transport: { type: 'http', url: 'https://linear-mcp.example.com/mcp' },
      prefix: 'linear', // must match runtime createMCPClient({ prefix })
    },
  },
  outFile: './mcp-types.generated.ts',
})
// mcp.config.ts
import { defineConfig } from '@tanstack/ai-mcp'

export default defineConfig({
  servers: {
    github: {
      transport: { type: 'http', url: 'https://github-mcp.example.com/mcp' },
    },
    linear: {
      transport: { type: 'http', url: 'https://linear-mcp.example.com/mcp' },
      prefix: 'linear', // must match runtime createMCPClient({ prefix })
    },
  },
  outFile: './mcp-types.generated.ts',
})

2. Run the generator

sh
npx @tanstack/ai-mcp generate
npx @tanstack/ai-mcp generate

The CLI connects to each declared server, introspects its tools, resources, and prompts, and writes the result to outFile.

3. Inspect the output

The generator emits one interface per server plus a combined pool map:

ts
// AUTO-GENERATED by `npx @tanstack/ai-mcp generate`. Do not edit.

import type { ServerDescriptor } from '@tanstack/ai-mcp'

export interface GithubServer extends ServerDescriptor {
  tools: {
    'search_repositories': { input: { query: string; limit?: number }; output: unknown }
    'create_issue': { input: { repo: string; title: string; body?: string }; output: unknown }
  }
  resources: {}
  prompts: {}
  capabilities: { tools: {} } & Record<string, unknown>
}

export interface LinearServer extends ServerDescriptor {
  tools: {
    'linear_create_issue': { input: { title: string; teamId: string }; output: unknown }
  }
  resources: {}
  prompts: {}
  capabilities: { tools: {} } & Record<string, unknown>
}

export interface MCPServers extends Record<string, ServerDescriptor> {
  'github': GithubServer
  'linear': LinearServer
}
// AUTO-GENERATED by `npx @tanstack/ai-mcp generate`. Do not edit.

import type { ServerDescriptor } from '@tanstack/ai-mcp'

export interface GithubServer extends ServerDescriptor {
  tools: {
    'search_repositories': { input: { query: string; limit?: number }; output: unknown }
    'create_issue': { input: { repo: string; title: string; body?: string }; output: unknown }
  }
  resources: {}
  prompts: {}
  capabilities: { tools: {} } & Record<string, unknown>
}

export interface LinearServer extends ServerDescriptor {
  tools: {
    'linear_create_issue': { input: { title: string; teamId: string }; output: unknown }
  }
  resources: {}
  prompts: {}
  capabilities: { tools: {} } & Record<string, unknown>
}

export interface MCPServers extends Record<string, ServerDescriptor> {
  'github': GithubServer
  'linear': LinearServer
}

4. Use generated types at runtime

Pass the generated type as a generic to createMCPClient (single server) or createMCPClients (pool). Tool names are narrowed to the literal types declared by the server, so a typo is a compile error.

Single server:

ts
import type { GithubServer } from './mcp-types.generated'
import { createMCPClient } from '@tanstack/ai-mcp'

const mcp = await createMCPClient<GithubServer>({
  transport: { type: 'http', url: process.env.GITHUB_MCP_URL! },
})

const tools = await mcp.tools()
// Each tool name is narrowed from GithubServer['tools']
import type { GithubServer } from './mcp-types.generated'
import { createMCPClient } from '@tanstack/ai-mcp'

const mcp = await createMCPClient<GithubServer>({
  transport: { type: 'http', url: process.env.GITHUB_MCP_URL! },
})

const tools = await mcp.tools()
// Each tool name is narrowed from GithubServer['tools']

Multi-server pool:

ts
import type { MCPServers } from './mcp-types.generated'
import { createMCPClients } from '@tanstack/ai-mcp'

const pool = await createMCPClients<MCPServers>({
  github: { transport: { type: 'http', url: process.env.GITHUB_MCP_URL! } },
  linear: {
    transport: { type: 'http', url: process.env.LINEAR_MCP_URL! },
    prefix: 'linear',
  },
})

// Config keys are constrained to the declared servers — a typo is a compile error
const tools = await pool.tools()
import type { MCPServers } from './mcp-types.generated'
import { createMCPClients } from '@tanstack/ai-mcp'

const pool = await createMCPClients<MCPServers>({
  github: { transport: { type: 'http', url: process.env.GITHUB_MCP_URL! } },
  linear: {
    transport: { type: 'http', url: process.env.LINEAR_MCP_URL! },
    prefix: 'linear',
  },
})

// Config keys are constrained to the declared servers — a typo is a compile error
const tools = await pool.tools()

Now that tool names and pool keys are compile-checked, hand the generated client to chat(). See Managed MCP with chat() to let chat() own discovery and lifecycle.