MCP 타입 생성
실행 중인 MCP 서버가 있고 createMCPClient를 통해 해당 서버의 도구를 호출하지만, 참조하는 도구 이름을 컴파일 시점에 검사하지는 않는다고 가정합니다. 이 가이드를 마치면 실행 중인 서버에서 서버별 interface 타입을 생성하고 이를 createMCPClient에 연결하게 됩니다. 그러면 검색된 도구 이름이 서버의 리터럴 이름으로 좁혀지고 풀 구성 키가 컴파일 검사를 받으며, 런타임 오버헤드는 전혀 발생하지 않습니다. 이것은 MCP 타입 안전성의 모드 3입니다. (도구 인수는 검색 경로에서 타입이 지정되지 않습니다. Zod로 검증되고 TypeScript 타입이 지정된 인수를 사용하려면 tools([toolDefinition(...)]) 오버로드와 결합합니다.)
generate CLI는 실행 중인 MCP 서버를 검사하고, createMCPClient / createMCPClients에 제네릭으로 전달할 TypeScript 인터페이스 타입을 생성합니다.
1. mcp.config.ts 생성
타입을 생성할 각 서버를 선언합니다. defineConfig 헬퍼를 사용하면 구성 파일에서 완전한 타입 검사와 자동 완성을 사용할 수 있습니다.
// 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. 생성기 실행
npx @tanstack/ai-mcp generate
CLI는 선언된 각 서버에 연결하여 해당 서버의 도구, 리소스, 프롬프트를 검사하고 결과를 outFile에 기록합니다.
3. 출력 검사
생성기는 서버별 인터페이스 하나와 이를 결합한 풀 맵을 생성합니다.
// 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. 런타임에 생성된 타입 사용
생성된 타입을 createMCPClient(단일 서버) 또는 createMCPClients(풀)에 제네릭으로 전달합니다. 도구 이름은 서버가 선언한 리터럴 타입으로 좁혀지므로 오타가 컴파일 오류가 됩니다.
단일 서버:
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 { 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()
이제 도구 이름과 풀 키가 컴파일 검사를 받으므로 생성된 클라이언트를 chat()에 전달합니다. chat()이 검색과 수명 주기를 관리하도록 하려면 Managed MCP with chat()을 참조합니다.