---
url: /docs/5.x/migration/plugin-mcp.md
description: Changes for @kubb/plugin-mcp when migrating from Kubb v4 to v5.
---

# Migration: `@kubb/plugin-mcp`

Part of the [v4 → v5 migration guide](/docs/5.x/migration). For the full option reference, see [`@kubb/plugin-mcp`](/plugins/plugin-mcp/).

[`resolver.name`](/docs/5.x/migration#transformersname-resolver) replaces `transformers.name`, and the `generators` option is [gone](/docs/5.x/migration#generators-removed).

## `client` selects a registered client plugin

In v4, `client` was an object that configured a bundled client (`clientType`, `dataReturnType`, `baseURL`, `bundle`, `importPath`, `paramsCasing`). In v5 it is a string that names a registered client plugin. See [Query and MCP plugins select a client](/docs/5.x/migration#client-becomes-a-selector) for the shared rules, then register [`@kubb/plugin-axios`](/plugins/plugin-axios/) or [`@kubb/plugin-fetch`](/plugins/plugin-fetch/) in `plugins` and set `baseURL` there instead of on `pluginMcp`.

`pluginMcp` also depends on [`@kubb/plugin-ts`](/plugins/plugin-ts/) and [`@kubb/plugin-zod`](/plugins/plugin-zod/), so register both alongside the client plugin.

::: code-group

```typescript [v4 kubb.config.ts]
import { defineConfig } from '@kubb/core'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginZod } from '@kubb/plugin-zod'
import { pluginMcp } from '@kubb/plugin-mcp'

export default defineConfig({
  input: './petStore.yaml',
  output: { path: './src/gen' },
  plugins: [
    pluginTs(),
    pluginZod(),
    pluginMcp({
      client: {
        client: 'fetch',
        baseURL: 'https://petstore.swagger.io/v2',
      },
    }),
  ],
})
```

```typescript twoslash [v5 kubb.config.ts]
import { defineConfig } from 'kubb/config'
import { pluginTs } from '@kubb/plugin-ts'
import { pluginZod } from '@kubb/plugin-zod'
import { pluginFetch } from '@kubb/plugin-fetch'
import { pluginMcp } from '@kubb/plugin-mcp'

export default defineConfig({
  input: './petStore.yaml',
  output: { path: './src/gen' },
  plugins: [
    pluginTs(),
    pluginZod(),
    pluginFetch({ baseURL: 'https://petstore.swagger.io/v2' }),
    pluginMcp({ client: 'fetch' }),
  ],
})
```

:::

## Removed: `paramsCasing`

```typescript [v4 kubb.config.ts]
pluginMcp({ paramsCasing: 'camelcase' })
```

Parameter properties in the generated handlers come from the `@kubb/plugin-ts` `*Options` type, so they match the names in your OpenAPI document. The `client.paramsCasing` sub-option is gone too, so drop both.

## Generated output

Each handler now takes a second argument, the MCP `RequestHandlerExtra` object, so it can read the request context. The handler no longer builds the request inline. Instead it calls the named operation from the registered client plugin (`addPet` here) with a single grouped `{ path, query, headers, body }` config object, and reads `res.data`.

```diff [Generated output]
-import type { CallToolResult } from '@modelcontextprotocol/sdk/types'
+import type { CallToolResult, ServerNotification, ServerRequest } from '@modelcontextprotocol/sdk/types'
+import type { RequestHandlerExtra } from '@modelcontextprotocol/sdk/shared/protocol'
+import { addPet } from './clients/addPet'

-export async function addPetHandler({ data }: { data: AddPetMutationRequest }): Promise<CallToolResult> {
+export async function addPetHandler(
+  { body }: AddPetOptions,
+  request: RequestHandlerExtra<ServerRequest, ServerNotification>,
+): Promise<CallToolResult> {
-  const res = await fetch<AddPetMutationResponse, ResponseErrorConfig<AddPet405>, AddPetMutationRequest>({
-    method: 'POST',
-    url: '/pet',
-    baseURL: 'https://petstore.swagger.io/v2',
-    data,
-  })
+  const res = await addPet({ body })
  ...
}
```
