@kubb/plugin-mcp
@kubb/plugin-mcp turns your OpenAPI spec into a Model Context Protocol server, with each operation becoming an MCP tool that AI assistants like Claude Desktop and Claude Code can call to reach your API. The plugin generates the tool handlers, a server.ts, and a .mcp.json, and validates each call with the schemas from @kubb/plugin-zod.
Each handler calls a registered client plugin, so add @kubb/plugin-axios or @kubb/plugin-fetch alongside @kubb/plugin-ts and @kubb/plugin-zod. Without a client plugin, the build stops with a setup error.
This plugin generates an MCP server from your spec, distinct from the built-in kubb mcp server that exposes the Kubb CLI itself, documented under AI / MCP.
The Connect Claude to a remote MCP server guide explains how to register the generated server with an assistant.
Installation
bun add -d @kubb/plugin-mcp@betapnpm add -D @kubb/plugin-mcp@betanpm install --save-dev @kubb/plugin-mcp@betayarn add -D @kubb/plugin-mcp@betaDependencies
This plugin needs three other plugins. @kubb/plugin-ts and @kubb/plugin-zod are declared dependencies, so Kubb runs them before plugin-mcp and the handlers can import the generated types and Zod schemas. The client plugin is resolved separately at setup.
@kubb/plugin-tsfor the request and response types.@kubb/plugin-zodfor the schemas that validate each tool call.@kubb/plugin-axiosor@kubb/plugin-fetchfor the HTTP client the handlers call.
A client plugin is required, since the handlers call its generated functions. Register one of them and set client only when both are present.
Example
import { defineConfig } from 'kubb'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginAxios } from '@kubb/plugin-axios'
import { pluginZod } from '@kubb/plugin-zod'
import { pluginMcp } from '@kubb/plugin-mcp'
export default defineConfig({
input: './petStore.yaml',
output: { path: './src/gen' },
plugins: [
pluginTs(),
pluginAxios({ baseURL: 'https://petstore.swagger.io/v2' }),
pluginZod(),
pluginMcp({
output: { path: 'mcp', mode: 'directory', barrel: { type: 'named' } },
group: {
type: 'tag',
name: ({ group }) => `${group}Handlers`,
},
}),
],
})