@kubb/plugin-mcp 5.0.0-beta.42 → 5.0.0-beta.56

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/extension.yaml DELETED
@@ -1,943 +0,0 @@
1
- $schema: https://kubb.dev/schemas/extension.json
2
- kind: plugin
3
- id: plugin-mcp
4
- name: MCP
5
- description: Generate a Model Context Protocol (MCP) server from OpenAPI so AI assistants like Claude can call your API as tools.
6
- category: ai
7
- type: official
8
- npmPackage: '@kubb/plugin-mcp'
9
- docsPath: /plugins/plugin-mcp
10
- repo: https://github.com/kubb-labs/plugins
11
- maintainers:
12
- - name: Stijn Van Hulle
13
- github: stijnvanhulle
14
- compatibility:
15
- kubb: '>=5.0.0'
16
- node: '>=22'
17
- tags:
18
- - mcp
19
- - model-context-protocol
20
- - ai
21
- - claude
22
- - llm
23
- - codegen
24
- - openapi
25
- dependencies:
26
- - plugin-ts
27
- - plugin-client
28
- - plugin-zod
29
- resources:
30
- documentation: https://kubb.dev/plugins/plugin-mcp
31
- repository: https://github.com/kubb-labs/plugins
32
- issues: https://github.com/kubb-labs/plugins/issues
33
- changelog: https://github.com/kubb-labs/plugins/blob/main/packages/plugin-mcp/CHANGELOG.md
34
- codesandbox: https://codesandbox.io/p/github/kubb-labs/plugins/main/examples/mcp
35
- featured: false
36
- icon:
37
- light: https://kubb.dev/feature/mcp-light.svg
38
- dark: https://kubb.dev/feature/mcp-dark.svg
39
- intro: |
40
- # @kubb/plugin-mcp
41
-
42
- Generate a [Model Context Protocol](https://modelcontextprotocol.io/introduction) server straight from your OpenAPI spec. Every operation becomes a typed MCP tool that AI assistants (Claude Desktop, Claude Code, MCP-compatible clients) can call directly.
43
-
44
- The plugin emits the tool definitions, the request handlers, and the Zod schemas they validate against. Plug the generated server into Claude with one config file.
45
-
46
- ```mermaid
47
- graph TD
48
- A[OpenAPI spec] --> B[Kubb<br/>code generation]
49
- B --> C[MCP server<br/>tool registry]
50
- C --> D[Claude / MCP client]
51
- D -->|Tool call| C
52
- C -->|HTTP request| E[Your API]
53
- ```
54
- notes:
55
- - type: tip
56
- body: |
57
- See [Connect Claude to a remote MCP server](https://modelcontextprotocol.io/docs/tools/claude-desktop) for connecting the generated server.
58
- options:
59
- - name: output
60
- type: Output
61
- required: false
62
- default: "{ path: 'mcp', barrel: { type: 'named' } }"
63
- description: Where the generated MCP tool handlers are written and how they are exported.
64
- properties:
65
- - name: path
66
- type: string
67
- required: true
68
- description: |
69
- Folder (or single file) where the plugin writes its generated code. The path is resolved against the global `output.path` set on `defineConfig`.
70
-
71
- Use a folder to keep each generator's output isolated (`'types'`, `'clients'`, `'hooks'`). Use a single file when you want everything in one place, for example `'api.ts'`.
72
- tip: |
73
- When `output.path` points to a single file, the `group` option cannot be used because every operation ends up in the same file.
74
- examples:
75
- - name: kubb.config.ts
76
- files:
77
- - lang: typescript
78
- twoslash: false
79
- code: |
80
- import { defineConfig } from 'kubb'
81
- import { pluginTs } from '@kubb/plugin-ts'
82
-
83
- export default defineConfig({
84
- input: { path: './petStore.yaml' },
85
- output: { path: './src/gen' },
86
- plugins: [
87
- pluginTs({
88
- output: { path: './types' },
89
- }),
90
- ],
91
- })
92
- - name: Resulting tree
93
- files:
94
- - lang: text
95
- twoslash: false
96
- code: |
97
- src/
98
- └── gen/
99
- └── types/
100
- ├── Pet.ts
101
- └── Store.ts
102
- default: "'mcp'"
103
- - name: barrel
104
- type: "{ type: 'named' | 'all', nested?: boolean } | false"
105
- required: false
106
- default: "{ type: 'named' }"
107
- description: |
108
- Controls how the generated `index.ts` (barrel) file re-exports the plugin's output.
109
-
110
- - `{ type: 'named' }` re-exports each symbol by name. Best for tree-shaking and explicit imports.
111
- - `{ type: 'all' }` uses `export *`. Smaller barrel file, but exports everything.
112
- - `{ nested: true }` creates a barrel in every subdirectory, so callers can import from any depth.
113
- - `false` skips the barrel entirely. The plugin's files are also excluded from the root `index.ts`.
114
- tip: |
115
- Pick `'named'` when consumers care about which symbols they import (better tree-shaking, friendlier auto-import). Pick `'all'` when the file count is small and you want a one-line barrel.
116
- examples:
117
- - name: "'named' (default)"
118
- files:
119
- - name: kubb.config.ts
120
- lang: typescript
121
- twoslash: false
122
- code: |
123
- import { defineConfig } from 'kubb'
124
- import { pluginTs } from '@kubb/plugin-ts'
125
-
126
- export default defineConfig({
127
- input: { path: './petStore.yaml' },
128
- output: { path: './src/gen' },
129
- plugins: [
130
- pluginTs({
131
- output: { barrel: { type: 'named' } },
132
- }),
133
- ],
134
- })
135
- - name: src/gen/types/index.ts
136
- lang: typescript
137
- twoslash: false
138
- code: |
139
- export { Pet, PetStatus } from './Pet'
140
- export { Store } from './Store'
141
- - name: "'all'"
142
- files:
143
- - name: kubb.config.ts
144
- lang: typescript
145
- twoslash: false
146
- code: |
147
- import { defineConfig } from 'kubb'
148
- import { pluginTs } from '@kubb/plugin-ts'
149
-
150
- export default defineConfig({
151
- input: { path: './petStore.yaml' },
152
- output: { path: './src/gen' },
153
- plugins: [
154
- pluginTs({
155
- output: { barrel: { type: 'all' } },
156
- }),
157
- ],
158
- })
159
- - name: src/gen/types/index.ts
160
- lang: typescript
161
- twoslash: false
162
- code: |
163
- export * from './Pet'
164
- export * from './Store'
165
- - name: nested
166
- files:
167
- - name: kubb.config.ts
168
- lang: typescript
169
- twoslash: false
170
- code: |
171
- import { defineConfig } from 'kubb'
172
- import { pluginTs } from '@kubb/plugin-ts'
173
-
174
- export default defineConfig({
175
- input: { path: './petStore.yaml' },
176
- output: { path: './src/gen' },
177
- plugins: [
178
- pluginTs({
179
- output: { barrel: { type: 'named', nested: true } },
180
- }),
181
- ],
182
- })
183
- - name: Generated tree
184
- lang: text
185
- twoslash: false
186
- code: |
187
- src/gen/types/
188
- ├── index.ts # re-exports ./petController and ./storeController
189
- ├── petController/
190
- │ ├── index.ts # re-exports Pet, Store, ...
191
- │ └── Pet.ts
192
- └── storeController/
193
- ├── index.ts
194
- └── Store.ts
195
- - name: 'false'
196
- files:
197
- - name: kubb.config.ts
198
- lang: typescript
199
- twoslash: false
200
- code: |
201
- import { defineConfig } from 'kubb'
202
- import { pluginTs } from '@kubb/plugin-ts'
203
-
204
- export default defineConfig({
205
- input: { path: './petStore.yaml' },
206
- output: { path: './src/gen' },
207
- plugins: [
208
- pluginTs({
209
- output: { barrel: false },
210
- }),
211
- ],
212
- })
213
- - name: Result
214
- lang: text
215
- twoslash: false
216
- code: |
217
- # No index.ts is generated for this plugin.
218
- # Its files are also excluded from the root index.ts.
219
- - name: banner
220
- type: 'string | ((node: RootNode) => string)'
221
- required: false
222
- description: |
223
- Text prepended to every generated file. Useful for license headers, lint disables, or `@ts-nocheck` directives.
224
-
225
- Pass a string for a static banner. Pass a function to compute the banner from each file's `RootNode` (the AST root containing path, schema, and operation context).
226
- examples:
227
- - name: Static banner
228
- files:
229
- - name: kubb.config.ts
230
- lang: typescript
231
- twoslash: false
232
- code: |
233
- import { defineConfig } from 'kubb'
234
- import { pluginTs } from '@kubb/plugin-ts'
235
-
236
- export default defineConfig({
237
- input: { path: './petStore.yaml' },
238
- output: { path: './src/gen' },
239
- plugins: [
240
- pluginTs({
241
- output: {
242
- banner: '/* eslint-disable */\n// @ts-nocheck',
243
- },
244
- }),
245
- ],
246
- })
247
- - name: Generated file
248
- lang: typescript
249
- twoslash: false
250
- code: |
251
- /* eslint-disable */
252
- // @ts-nocheck
253
- export type Pet = {
254
- id: number
255
- name: string
256
- }
257
- - name: Dynamic banner
258
- files:
259
- - name: kubb.config.ts
260
- lang: typescript
261
- twoslash: false
262
- code: |
263
- import { defineConfig } from 'kubb'
264
- import { pluginTs } from '@kubb/plugin-ts'
265
-
266
- export default defineConfig({
267
- input: { path: './petStore.yaml' },
268
- output: { path: './src/gen' },
269
- plugins: [
270
- pluginTs({
271
- output: {
272
- banner: (node) => `// Source: ${node.path}\n// Generated at ${new Date().toISOString()}`,
273
- },
274
- }),
275
- ],
276
- })
277
- - name: footer
278
- type: 'string | ((node: RootNode) => string)'
279
- required: false
280
- description: |
281
- Text appended at the end of every generated file. The mirror of `banner` — use it for closing comments, re-enabling lint rules, or marker lines.
282
-
283
- Pass a string for a static footer, or a function that receives the file's `RootNode` and returns the footer text.
284
- examples:
285
- - name: Re-enable lint after a banner disable
286
- files:
287
- - name: kubb.config.ts
288
- lang: typescript
289
- twoslash: false
290
- code: |
291
- import { defineConfig } from 'kubb'
292
- import { pluginTs } from '@kubb/plugin-ts'
293
-
294
- export default defineConfig({
295
- input: { path: './petStore.yaml' },
296
- output: { path: './src/gen' },
297
- plugins: [
298
- pluginTs({
299
- output: {
300
- banner: '/* eslint-disable */',
301
- footer: '/* eslint-enable */',
302
- },
303
- }),
304
- ],
305
- })
306
- - name: override
307
- type: boolean
308
- required: false
309
- default: 'false'
310
- description: |
311
- Allows the plugin to overwrite hand-written files that share a name with a generated file.
312
-
313
- - `false` (default): Kubb skips a file if it already exists and is not marked as generated. This protects manual edits.
314
- - `true`: Kubb overwrites any file at the target path, including hand-written ones.
315
- warning: |
316
- Enable this only when you are sure the target folder contains nothing you need to keep. Local edits are lost on the next generation.
317
- examples:
318
- - name: kubb.config.ts
319
- files:
320
- - lang: typescript
321
- twoslash: false
322
- code: |
323
- import { defineConfig } from 'kubb'
324
- import { pluginTs } from '@kubb/plugin-ts'
325
-
326
- export default defineConfig({
327
- input: { path: './petStore.yaml' },
328
- output: { path: './src/gen' },
329
- plugins: [
330
- pluginTs({
331
- output: { override: true },
332
- }),
333
- ],
334
- })
335
- - name: resolver
336
- type: Partial<ResolverMcp> & ThisType<ResolverMcp>
337
- required: false
338
- description: |
339
- Overrides how the plugin builds names and paths for generated files and symbols. Use this to add prefixes, suffixes, or to swap the casing strategy without forking the plugin.
340
-
341
- Only override the methods you want to change. Anything you omit falls back to the plugin's default resolver. A method that returns `null` or `undefined` also falls back.
342
-
343
- Inside each method, `this` is bound to the full resolver, so you can call `this.default(name, 'function')` to delegate to the built-in implementation.
344
- body: |
345
- Each plugin ships with a default resolver:
346
-
347
- | Plugin | Default resolver |
348
- | --- | --- |
349
- | `@kubb/plugin-ts` | `resolverTs` |
350
- | `@kubb/plugin-zod` | `resolverZod` |
351
- | `@kubb/plugin-faker` | `resolverFaker` |
352
- | `@kubb/plugin-cypress` | `resolverCypress` |
353
- | `@kubb/plugin-msw` | `resolverMsw` |
354
- | `@kubb/plugin-mcp` | `resolverMcp` |
355
- | `@kubb/plugin-client` | `resolverClient` |
356
- codeBlock:
357
- lang: typescript
358
- title: Prefix every tool name with "Mcp"
359
- code: |
360
- import { defineConfig } from 'kubb'
361
- import { pluginMcp } from '@kubb/plugin-mcp'
362
-
363
- export default defineConfig({
364
- input: { path: './petStore.yaml' },
365
- output: { path: './src/gen' },
366
- plugins: [
367
- pluginMcp({
368
- resolver: {
369
- resolveName(name) {
370
- return `Mcp${this.default(name, 'function')}`
371
- },
372
- },
373
- }),
374
- ],
375
- })
376
- tip: |
377
- Use `resolver` for naming and file-location tweaks. For changing the AST nodes themselves (e.g. stripping descriptions), use `transformer` instead.
378
- - name: group
379
- type: Group
380
- required: false
381
- description: |
382
- Splits generated files into subfolders based on the operation's tag, so each tag in your OpenAPI spec gets its own directory.
383
-
384
- Without `group`, every file lands in the plugin's `output.path` folder. With `group`, files are bucketed under `{output.path}/{groupName}/`, where `groupName` is derived from the operation's first tag.
385
- tip: |
386
- Use `group` to mirror your API's domain structure (pet, store, user) in the generated code. Combine it with `output.barrel: { type: 'named', nested: true }` to get per-tag barrel files.
387
- examples:
388
- - name: kubb.config.ts
389
- files:
390
- - lang: typescript
391
- twoslash: false
392
- code: |
393
- import { defineConfig } from 'kubb'
394
- import { pluginTs } from '@kubb/plugin-ts'
395
-
396
- export default defineConfig({
397
- input: { path: './petStore.yaml' },
398
- output: { path: './src/gen' },
399
- plugins: [
400
- pluginTs({
401
- group: {
402
- type: 'tag',
403
- name: ({ group }) => `${group}Controller`,
404
- },
405
- }),
406
- ],
407
- })
408
- body: |
409
- With the configuration above, the generator emits:
410
-
411
- ```text
412
- src/gen/
413
- ├── petController/
414
- │ ├── AddPet.ts
415
- │ └── GetPet.ts
416
- └── storeController/
417
- ├── CreateStore.ts
418
- └── GetStoreById.ts
419
- ```
420
- properties:
421
- - name: type
422
- type: "'tag'"
423
- required: true
424
- description: |
425
- Property used to assign each operation to a group. Required whenever `group` is set.
426
-
427
- Today only `'tag'` is supported: Kubb reads the first tag on the operation (`operation.getTags().at(0)?.name`) and uses it as the group key. Operations without a tag are placed in a default group.
428
- note: |
429
- `Required: true*` is conditional — only required when the parent `group` option is used. `group` itself stays optional.
430
- - name: name
431
- type: '(context: GroupContext) => string'
432
- required: false
433
- default: (ctx) => `${ctx.group}Requests`
434
- description: Function that builds the folder/identifier name from a group key (the operation's first tag).
435
- - name: paramsCasing
436
- type: "'camelcase'"
437
- required: false
438
- description: |
439
- Renames parameter properties in the generated MCP handlers. The HTTP layer still uses the original spec names — Kubb adds the mapping for you.
440
- important: |
441
- Set the same `paramsCasing` here as on `@kubb/plugin-ts` so the handlers' parameter types line up with the generated request types.
442
- examples:
443
- - name: "With `paramsCasing: 'camelcase'`"
444
- files:
445
- - lang: typescript
446
- twoslash: false
447
- code: |
448
- // Handler signature uses camelCase
449
- export async function findPetsByStatusHandler({
450
- stepId,
451
- }: {
452
- stepId: FindPetsByStatusPathParams['stepId']
453
- }): Promise<CallToolResult> {
454
- const step_id = stepId
455
-
456
- const res = await fetch({
457
- method: 'GET',
458
- url: `/pet/findByStatus/${step_id}`,
459
- })
460
- // ...
461
- }
462
- - name: Without `paramsCasing`
463
- files:
464
- - lang: typescript
465
- twoslash: false
466
- code: |
467
- export async function findPetsByStatusHandler({
468
- step_id,
469
- }: {
470
- step_id: FindPetsByStatusPathParams['step_id']
471
- }): Promise<CallToolResult> {
472
- const res = await fetch({
473
- method: 'GET',
474
- url: `/pet/findByStatus/${step_id}`,
475
- })
476
- // ...
477
- }
478
- - name: client
479
- type: ClientImportPath & { clientType?, dataReturnType?, baseURL?, bundle?, paramsCasing? }
480
- required: false
481
- description: |
482
- HTTP client used by each MCP handler to call the underlying API. Mirrors a subset of `pluginClient` options.
483
- properties:
484
- - name: importPath
485
- type: string
486
- required: false
487
- description: |
488
- Path or module specifier of a custom client module. Generated code imports its HTTP runtime from here instead of `@kubb/plugin-client/clients/{client}`.
489
-
490
- Use this when you need to inject auth headers, add interceptors, change the base URL at runtime, or wrap a different HTTP library (ky, ofetch, ...). Both relative paths (`./src/client.ts`) and bare specifiers (`@my-org/api-client`) work.
491
- details:
492
- - title: When to use `importPath`
493
- body: |
494
- Reach for a custom client when you need to:
495
-
496
- - Add an auth token to every request.
497
- - Plug in interceptors, retries, or logging.
498
- - Configure `baseURL` and headers from environment variables.
499
- - Wrap a library other than `axios`/`fetch`.
500
- - title: Default behavior
501
- body: |
502
- Without `importPath`:
503
-
504
- - `bundle: false` (default) — generated code imports from `@kubb/plugin-client/clients/{axios|fetch}`.
505
- - `bundle: true` — Kubb writes `.kubb/client.ts` and generated code imports from there.
506
- - title: Required exports
507
- body: |
508
- The module pointed to by `importPath` must satisfy the same shape as the built-in client. At minimum:
509
-
510
- - A default export of the `client` function.
511
- - A `RequestConfig` type.
512
- - A `ResponseErrorConfig` type.
513
-
514
- When used together with a query plugin (`@kubb/plugin-react-query`, `@kubb/plugin-vue-query`), it must also export a `Client` type alias.
515
- - title: How generated files import it
516
- body: |
517
- Generated code imports the client as a default import (bound to the local name `client`) and the runtime types as named type imports:
518
- codeBlock:
519
- lang: typescript
520
- code: |
521
- import client from '${client.importPath}'
522
- import type { RequestConfig, ResponseErrorConfig } from '${client.importPath}'
523
- // ... rest of the generated file
524
- important: |
525
- When used with query plugins (`@kubb/plugin-react-query`, `@kubb/plugin-vue-query`), generated hooks also import a `Client` type alias. Your module **must** export `Client`, `RequestConfig`, and `ResponseErrorConfig` — TypeScript will fail the import otherwise.
526
- codeBlock:
527
- lang: typescript
528
- title: src/client.ts
529
- code: |
530
- import axios from 'axios'
531
-
532
- export type RequestConfig<TData = unknown> = {
533
- url?: string
534
- method: 'GET' | 'PUT' | 'PATCH' | 'POST' | 'DELETE'
535
- params?: object
536
- data?: TData | FormData
537
- responseType?: 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'
538
- signal?: AbortSignal
539
- headers?: HeadersInit
540
- }
541
-
542
- export type ResponseConfig<TData = unknown> = {
543
- data: TData
544
- status: number
545
- statusText: string
546
- }
547
-
548
- export type ResponseErrorConfig<TError = unknown> = TError
549
-
550
- // Required when used with @kubb/plugin-react-query or @kubb/plugin-vue-query
551
- export type Client = <TData, _TError = unknown, TVariables = unknown>(
552
- config: RequestConfig<TVariables>,
553
- ) => Promise<ResponseConfig<TData>>
554
-
555
- const client: Client = async (config) => {
556
- const response = await axios.request<TData>({
557
- ...config,
558
- headers: {
559
- Authorization: `Bearer ${process.env.API_TOKEN}`,
560
- ...config.headers,
561
- },
562
- })
563
-
564
- return response
565
- }
566
-
567
- export default client
568
- examples:
569
- - name: Wire up a custom client
570
- files:
571
- - name: kubb.config.ts
572
- lang: typescript
573
- twoslash: false
574
- code: |
575
- import { defineConfig } from 'kubb'
576
- import { pluginClient } from '@kubb/plugin-client'
577
-
578
- export default defineConfig({
579
- input: { path: './petStore.yaml' },
580
- output: { path: './src/gen' },
581
- plugins: [
582
- pluginClient({
583
- importPath: './src/client.ts',
584
- }),
585
- ],
586
- })
587
- tip: |
588
- See the [custom client guide](https://kubb.dev/plugins/plugin-client#importpath) for a worked example.
589
- - name: dataReturnType
590
- type: "'data' | 'full'"
591
- required: false
592
- default: "'data'"
593
- description: |
594
- Shape of the value returned from each generated client function.
595
-
596
- - `'data'` returns only the response body (`response.data`). Concise and matches what most apps need.
597
- - `'full'` returns the full response config — body, status code, headers, and the original request. Use this when callers need to inspect headers or status.
598
- examples:
599
- - name: "'data' (default)"
600
- files:
601
- - name: getPetById.ts
602
- lang: typescript
603
- twoslash: false
604
- code: |
605
- export async function getPetById<TData>(
606
- petId: GetPetByIdPathParams,
607
- ): Promise<ResponseConfig<TData>['data']> {
608
- // ...
609
- }
610
- - name: usage.ts
611
- lang: typescript
612
- twoslash: false
613
- code: |
614
- const pet = await getPetById(1)
615
- // ^? Pet
616
- - name: "'full'"
617
- files:
618
- - name: getPetById.ts
619
- lang: typescript
620
- twoslash: false
621
- code: |
622
- export async function getPetById<TData>(
623
- petId: GetPetByIdPathParams,
624
- ): Promise<ResponseConfig<TData>> {
625
- // ...
626
- }
627
- - name: usage.ts
628
- lang: typescript
629
- twoslash: false
630
- code: |
631
- const response = await getPetById(1)
632
- // ^? ResponseConfig<Pet>
633
- console.log(response.status, response.headers)
634
- const pet = response.data
635
- - name: baseURL
636
- type: string
637
- required: false
638
- description: |
639
- Base URL prepended to every request URL in the generated client. When omitted, the URL comes from the OpenAPI spec's `servers[0].url` (or whichever index the adapter is configured to read).
640
-
641
- Set this when the generated client should point at a different environment (staging, production) than the one written in the spec.
642
- examples:
643
- - name: Override the spec's server URL
644
- files:
645
- - lang: typescript
646
- twoslash: false
647
- code: |
648
- import { defineConfig } from 'kubb'
649
- import { pluginClient } from '@kubb/plugin-client'
650
-
651
- export default defineConfig({
652
- input: { path: './petStore.yaml' },
653
- output: { path: './src/gen' },
654
- plugins: [
655
- pluginClient({
656
- baseURL: 'https://petstore.swagger.io/v2',
657
- }),
658
- ],
659
- })
660
- - name: clientType
661
- type: "'function' | 'class' | 'staticClass'"
662
- required: false
663
- description: |
664
- Shape of the underlying client the handlers call into. Mirrors `pluginClient`'s `clientType` option.
665
- - name: bundle
666
- type: boolean
667
- required: false
668
- description: |
669
- Copies the HTTP client runtime into the generated output so consumers do not need `@kubb/plugin-client` at runtime. Mirrors `pluginClient`'s `bundle` option.
670
- - name: paramsCasing
671
- type: "'camelcase'"
672
- required: false
673
- description: |
674
- Renames parameter properties passed to the underlying client. Mirrors `pluginClient`'s `paramsCasing` option.
675
- - name: include
676
- type: Array<Include>
677
- required: false
678
- description: |
679
- Restricts generation to operations that match at least one entry in the list. Anything not matched is skipped.
680
-
681
- Each entry filters by one of:
682
-
683
- - `tag` — the operation's first tag in the OpenAPI spec.
684
- - `operationId` — the operation's `operationId`.
685
- - `path` — the URL pattern (`'/pet/{petId}'`).
686
- - `method` — HTTP method (`'get'`, `'post'`, ...).
687
- - `contentType` — the media type of the request body.
688
-
689
- `pattern` accepts either a string (exact match) or a `RegExp` for fuzzy matches.
690
- codeBlock:
691
- lang: typescript
692
- title: Type definition
693
- code: |
694
- export type Include = {
695
- type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
696
- pattern: string | RegExp
697
- }
698
- examples:
699
- - name: Only the pet tag
700
- files:
701
- - name: kubb.config.ts
702
- lang: typescript
703
- twoslash: false
704
- code: |
705
- import { defineConfig } from 'kubb'
706
- import { pluginTs } from '@kubb/plugin-ts'
707
-
708
- export default defineConfig({
709
- input: { path: './petStore.yaml' },
710
- output: { path: './src/gen' },
711
- plugins: [
712
- pluginTs({
713
- include: [
714
- { type: 'tag', pattern: 'pet' },
715
- ],
716
- }),
717
- ],
718
- })
719
- - name: Only GET operations under /pet
720
- files:
721
- - name: kubb.config.ts
722
- lang: typescript
723
- twoslash: false
724
- code: |
725
- import { defineConfig } from 'kubb'
726
- import { pluginTs } from '@kubb/plugin-ts'
727
-
728
- export default defineConfig({
729
- input: { path: './petStore.yaml' },
730
- output: { path: './src/gen' },
731
- plugins: [
732
- pluginTs({
733
- include: [
734
- { type: 'method', pattern: 'get' },
735
- { type: 'path', pattern: /^\/pet/ },
736
- ],
737
- }),
738
- ],
739
- })
740
- - name: exclude
741
- type: Array<Exclude>
742
- required: false
743
- description: |
744
- Skips any operation that matches at least one entry in the list. The opposite of `include`.
745
-
746
- Each entry filters by one of:
747
-
748
- - `tag` — the operation's first tag.
749
- - `operationId` — the operation's `operationId`.
750
- - `path` — the URL pattern (`'/pet/{petId}'`).
751
- - `method` — HTTP method (`'get'`, `'post'`, ...).
752
- - `contentType` — the media type of the request body.
753
-
754
- `pattern` accepts a plain string or a `RegExp`. When both `include` and `exclude` are set, `exclude` wins.
755
- codeBlock:
756
- lang: typescript
757
- title: Type definition
758
- code: |
759
- export type Exclude = {
760
- type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
761
- pattern: string | RegExp
762
- }
763
- examples:
764
- - name: Skip everything under the store tag
765
- files:
766
- - name: kubb.config.ts
767
- lang: typescript
768
- twoslash: false
769
- code: |
770
- import { defineConfig } from 'kubb'
771
- import { pluginTs } from '@kubb/plugin-ts'
772
-
773
- export default defineConfig({
774
- input: { path: './petStore.yaml' },
775
- output: { path: './src/gen' },
776
- plugins: [
777
- pluginTs({
778
- exclude: [
779
- { type: 'tag', pattern: 'store' },
780
- ],
781
- }),
782
- ],
783
- })
784
- - name: Skip a specific operation and all delete methods
785
- files:
786
- - name: kubb.config.ts
787
- lang: typescript
788
- twoslash: false
789
- code: |
790
- import { defineConfig } from 'kubb'
791
- import { pluginTs } from '@kubb/plugin-ts'
792
-
793
- export default defineConfig({
794
- input: { path: './petStore.yaml' },
795
- output: { path: './src/gen' },
796
- plugins: [
797
- pluginTs({
798
- exclude: [
799
- { type: 'operationId', pattern: 'deletePet' },
800
- { type: 'method', pattern: 'delete' },
801
- ],
802
- }),
803
- ],
804
- })
805
- - name: override
806
- type: Array<Override>
807
- required: false
808
- description: |
809
- Applies a different set of plugin options to operations that match a pattern. Use this when most of your API should follow the global config, but a handful of endpoints need different treatment.
810
-
811
- Each entry has the same `type` and `pattern` shape as `include`/`exclude`, plus an `options` object that overrides the plugin's options for matched operations.
812
-
813
- Entries are evaluated top to bottom. The first matching entry's `options` is merged onto the plugin defaults; later entries do not stack.
814
- codeBlock:
815
- lang: typescript
816
- title: Type definition
817
- code: |
818
- export type Override = {
819
- type: 'tag' | 'operationId' | 'path' | 'method' | 'contentType'
820
- pattern: string | RegExp
821
- options: PluginOptions
822
- }
823
- examples:
824
- - name: Use a different enum style for the user tag
825
- files:
826
- - name: kubb.config.ts
827
- lang: typescript
828
- twoslash: false
829
- code: |
830
- import { defineConfig } from 'kubb'
831
- import { pluginTs } from '@kubb/plugin-ts'
832
-
833
- export default defineConfig({
834
- input: { path: './petStore.yaml' },
835
- output: { path: './src/gen' },
836
- plugins: [
837
- pluginTs({
838
- enumType: 'asConst',
839
- override: [
840
- {
841
- type: 'tag',
842
- pattern: 'user',
843
- options: { enumType: 'literal' },
844
- },
845
- ],
846
- }),
847
- ],
848
- })
849
- - name: generators
850
- type: Array<Generator<PluginMcp>>
851
- required: false
852
- experimental: true
853
- description: |
854
- Adds custom generators that run alongside the plugin's built-in generators. Each generator can emit additional files or post-process existing ones using the plugin's AST and options.
855
-
856
- Use this when you need output the plugin does not produce out of the box (a custom client wrapper, an extra index, a metadata file). For end-to-end guidance, see [Creating plugins](https://kubb.dev/docs/5.x/guides/creating-plugins).
857
- warning: |
858
- Generators are an experimental, low-level API. The signature may change between minor releases.
859
- - name: transformer
860
- type: Visitor
861
- required: false
862
- description: |
863
- Modifies AST nodes before they are printed to source code. Use this when you need to rewrite operation IDs, drop descriptions, or change schema metadata without forking the generator.
864
-
865
- Each visitor method (e.g. `schema`, `operation`) receives the node and a context object. Return a new node to replace it, or return `undefined` to leave it untouched. Methods you omit keep the plugin's default behavior.
866
- examples:
867
- - name: Strip descriptions before printing
868
- files:
869
- - name: kubb.config.ts
870
- lang: typescript
871
- twoslash: false
872
- code: |
873
- import { defineConfig } from 'kubb'
874
- import { pluginTs } from '@kubb/plugin-ts'
875
-
876
- export default defineConfig({
877
- input: { path: './petStore.yaml' },
878
- output: { path: './src/gen' },
879
- plugins: [
880
- pluginTs({
881
- transformer: {
882
- schema(node) {
883
- return { ...node, description: undefined }
884
- },
885
- },
886
- }),
887
- ],
888
- })
889
- - name: Prefix every operationId
890
- files:
891
- - name: kubb.config.ts
892
- lang: typescript
893
- twoslash: false
894
- code: |
895
- import { defineConfig } from 'kubb'
896
- import { pluginTs } from '@kubb/plugin-ts'
897
-
898
- export default defineConfig({
899
- input: { path: './petStore.yaml' },
900
- output: { path: './src/gen' },
901
- plugins: [
902
- pluginTs({
903
- transformer: {
904
- operation(node) {
905
- return { ...node, operationId: `api_${node.operationId}` }
906
- },
907
- },
908
- }),
909
- ],
910
- })
911
- tip: |
912
- Use `transformer` to rewrite node properties before printing. For changing the names of generated symbols and files, use `resolver` instead.
913
- examples:
914
- - name: kubb.config.ts
915
- files:
916
- - lang: typescript
917
- twoslash: false
918
- code: |
919
- import { defineConfig } from 'kubb'
920
- import { pluginTs } from '@kubb/plugin-ts'
921
- import { pluginClient } from '@kubb/plugin-client'
922
- import { pluginZod } from '@kubb/plugin-zod'
923
- import { pluginMcp } from '@kubb/plugin-mcp'
924
-
925
- export default defineConfig({
926
- input: { path: './petStore.yaml' },
927
- output: { path: './src/gen' },
928
- plugins: [
929
- pluginTs(),
930
- pluginClient(),
931
- pluginZod(),
932
- pluginMcp({
933
- output: { path: 'mcp', barrel: { type: 'named' } },
934
- client: {
935
- baseURL: 'https://petstore.swagger.io/v2',
936
- },
937
- group: {
938
- type: 'tag',
939
- name: ({ group }) => `${group}Handlers`,
940
- },
941
- }),
942
- ],
943
- })