@kubb/plugin-mcp 5.0.7 → 5.0.9

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/README.md CHANGED
@@ -10,7 +10,7 @@
10
10
  [![Node][node-src]][node-href]
11
11
 
12
12
  <h4>
13
- <a href="https://kubb.dev/plugins/mcp" target="_blank">Documentation</a>
13
+ <a href="https://kubb.dev/plugins/plugin-mcp" target="_blank">Documentation</a>
14
14
  <span> · </span>
15
15
  <a href="https://github.com/kubb-labs/kubb/issues/" target="_blank">Report Bug</a>
16
16
  <span> · </span>
@@ -38,7 +38,7 @@ npm install @kubb/plugin-mcp
38
38
 
39
39
  ## Documentation
40
40
 
41
- See the [full documentation](https://kubb.dev/plugins/mcp) for configuration options and examples.
41
+ See the [full documentation](https://kubb.dev/plugins/plugin-mcp) for configuration options and examples.
42
42
 
43
43
  ## Supporting Kubb
44
44
 
package/dist/index.cjs CHANGED
@@ -474,8 +474,8 @@ return server`
474
474
  *
475
475
  * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
476
476
  * imports and calls them.
477
- * - `error` — no client plugin is registered, several are registered without a selector, or the
478
- * requested one is missing.
477
+ * - `error` — no client plugin is registered, several are registered without a selector, the
478
+ * requested one is missing, or `client` is not a known selector.
479
479
  *
480
480
  * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered
481
481
  * contract client plugin is picked up automatically.
@@ -516,6 +516,10 @@ function resolveClient(options) {
516
516
  pluginName
517
517
  };
518
518
  }
519
+ if (client !== void 0) return {
520
+ kind: "error",
521
+ message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios'. Drop \`client\` to use the registered client plugin.`
522
+ };
519
523
  const registered = contractPlugins.filter(has);
520
524
  if (registered.length === 1) return {
521
525
  kind: "contract",
@@ -606,8 +610,7 @@ const mcpGenerator = (0, kubb_kit.defineGenerator)({
606
610
  if (!kubb_kit.ast.isHttpOperationNode(node)) return null;
607
611
  const { resolver, driver, root, config } = ctx;
608
612
  const { output, client, group } = ctx.options;
609
- const pluginTs = driver.getPlugin(_kubb_plugin_ts.pluginTsName);
610
- if (!pluginTs) return null;
613
+ const pluginTs = ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
611
614
  const tsResolver = driver.getResolver(_kubb_plugin_ts.pluginTsName);
612
615
  const contractOp = resolveClientOperation({
613
616
  clientPlugin: { pluginName: client.pluginName },
@@ -711,8 +714,7 @@ const serverGenerator = (0, kubb_kit.defineGenerator)({
711
714
  operations(nodes, ctx) {
712
715
  const { config, resolver, plugin, driver, root } = ctx;
713
716
  const { output, group } = ctx.options;
714
- const pluginZod = driver.getPlugin(_kubb_plugin_zod.pluginZodName);
715
- if (!pluginZod) return;
717
+ const pluginZod = ctx.requirePlugin(_kubb_plugin_zod.pluginZodName);
716
718
  const zodResolver = driver.getResolver(_kubb_plugin_zod.pluginZodName);
717
719
  const name = "server";
718
720
  const serverFile = {
@@ -922,6 +924,8 @@ const pluginMcp = (0, kubb_kit.definePlugin)((options) => {
922
924
  options,
923
925
  dependencies: [_kubb_plugin_ts.pluginTsName, _kubb_plugin_zod.pluginZodName],
924
926
  hooks: { "kubb:plugin:setup"(ctx) {
927
+ ctx.requirePlugin(_kubb_plugin_ts.pluginTsName);
928
+ ctx.requirePlugin(_kubb_plugin_zod.pluginZodName);
925
929
  const resolver = userResolver ? kubb_kit.Resolver.merge(resolverMcp, userResolver) : resolverMcp;
926
930
  ctx.setOptions({
927
931
  output,
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["Url","ast","File","Function","functionPrinter","createFunctionParameters","createFunctionParameter","createObjectBindingPattern","File","Function","Const","path","defineGenerator","jsxRenderer","ast","pluginTsName","File","defineGenerator","jsxRenderer","pluginZodName","path","ast","File","createResolver","definePlugin","pluginTsName","pluginZodName","Resolver"],"sources":["../../../internals/shared/src/params.ts","../../../internals/shared/src/operation.ts","../../../internals/utils/src/casing.ts","../../../internals/shared/src/group.ts","../src/components/McpHandler.tsx","../src/utils.ts","../src/components/Server.tsx","../../../internals/client/src/resolveClient.ts","../../../internals/client/src/resolveClientOperation.ts","../src/generators/mcpGenerator.tsx","../src/generators/serverGenerator.tsx","../src/resolvers/resolverMcp.ts","../src/plugin.ts"],"sourcesContent":["import type { ast } from 'kubb/kit'\n\n/**\n * Drops parameters that share the same name, keeping the first.\n *\n * A malformed spec can declare the same parameter name twice within one `in` location. Both would\n * resolve to the same output property, so emitting both would yield an object type with a duplicate\n * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:\n * parameter names flow through unchanged, so no two distinct names ever collide here anymore.\n */\nexport function dedupeParams(params: Array<ast.ParameterNode>): Array<ast.ParameterNode> {\n const seen = new Set<string>()\n\n return params.filter((param) => {\n if (seen.has(param.name)) return false\n seen.add(param.name)\n return true\n })\n}\n","import { ast, type Group, type NodeCache, type Output, type Resolver, type ResolverFileParams, Url } from 'kubb/kit'\nimport { dedupeParams } from './params.ts'\n\n/**\n * Builds the `ResolverFileParams` every operation generator passes to\n * `resolver.file`: a file named `name`, tagged by the operation's first\n * tag (or `'default'`), at the operation's path. Centralizes the entry object\n * that was repeated at dozens of call sites across the client and query plugins.\n *\n * @example\n * ```ts\n * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })\n * ```\n */\nexport function operationFileEntry(node: ast.OperationNode, name: string, extname: ResolverFileParams['extname'] = '.ts'): ResolverFileParams {\n return {\n name,\n extname,\n tag: node.tags[0] ?? 'default',\n path: node.path,\n }\n}\n\n/**\n * Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the\n * current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the\n * same dependency for the same operation in one pass (a query plugin's several hook generators, the\n * MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.\n *\n * @example Cache `plugin-ts`'s file for the current operation\n * ```ts\n * const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })\n * ```\n */\nexport function resolveDependencyOperationFile(options: {\n cache: NodeCache\n node: ast.OperationNode\n resolver: Pick<Resolver, 'file' | 'pluginName'>\n root: string\n output: Output\n group?: Group | null\n}): ast.FileNode {\n const { cache, node, resolver, root, output, group } = options\n\n return cache.ensureItem(`${resolver.pluginName}:operationFile`, () =>\n resolver.file({ ...operationFileEntry(node, node.operationId), root, output, group: group ?? undefined }),\n )\n}\n\nexport type ContentTypeInfo = {\n contentTypes: string[]\n isMultipleContentTypes: boolean\n contentTypeUnion: string\n defaultContentType: string\n hasFormData: boolean\n}\n\nexport type RequestConfigResolver = {\n response: {\n body(node: ast.OperationNode): string\n }\n}\n\nexport type ResponseStatusNameResolver = {\n response: {\n status(node: ast.OperationNode, statusCode: ast.StatusCode): string\n }\n}\n\nexport type ResponseNameResolver = ResponseStatusNameResolver & {\n response: {\n response(node: ast.OperationNode): string\n }\n}\n\nexport type OperationTypeNameResolver = RequestConfigResolver &\n ResponseNameResolver & {\n param: {\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n }\n\n/**\n * Resolver interface for building operation parameters.\n *\n * `ResolverTs` from `@kubb/plugin-ts` satisfies this interface and can be passed directly.\n */\nexport type OperationParamsResolver = {\n /**\n * Naming for an operation's parameters, grouped by location.\n */\n param: {\n /**\n * Resolves the type name for an individual parameter.\n *\n * @example Individual path parameter name\n * `resolver.param.name(node, param) // → 'DeletePetPathPetId'`\n */\n name(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped path parameters type name.\n * When the return value equals `resolver.param.name`, no indexed access is emitted.\n *\n * @example Grouped path params type name\n * `resolver.param.path(node, param) // → 'DeletePetPath'`\n */\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped query parameters type name.\n * When the return value equals `resolver.param.name`, an inline struct type is emitted instead.\n *\n * @example Grouped query params type name\n * `resolver.param.query(node, param) // → 'FindPetsByStatusQuery'`\n */\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped header parameters type name.\n * When the return value equals `resolver.param.name`, an inline struct type is emitted instead.\n *\n * @example Grouped header params type name\n * `resolver.param.headers(node, param) // → 'DeletePetHeaders'`\n */\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n /**\n * Naming for an operation's request and response types.\n */\n response: {\n /**\n * Resolves the request body type name.\n *\n * @example Request body type name\n * `resolver.response.body(node) // → 'CreatePetBody'`\n */\n body(node: ast.OperationNode): string\n }\n}\n\nexport type OperationCommentLink = 'pathTemplate' | 'urlPath' | false | ((node: ast.OperationNode) => string | undefined)\n\nexport type BuildOperationCommentsOptions = {\n link?: OperationCommentLink\n linkPosition?: 'beforeDeprecated' | 'afterDeprecated'\n splitLines?: boolean\n}\n\ntype ResponseLike = {\n statusCode: ast.StatusCode | number | string\n}\n\nexport type OperationParameterGroups = Record<ast.ParameterNode['in'], Array<ast.ParameterNode>>\n\nexport type ResolveOperationTypeNameOptions = {\n responseStatusNames?: boolean | 'error'\n exclude?: ReadonlyArray<string | undefined>\n order?: 'params-first' | 'body-response-first'\n /**\n * Include the individual `Path`/`Query`/`Headers` group type names. Set to `false` for clients\n * that reference the grouped `Options` type instead of the per-group types.\n */\n includeParams?: boolean\n}\n\nfunction getOperationLink(node: ast.OperationNode, link: OperationCommentLink): string | null {\n if (!link) {\n return null\n }\n\n if (typeof link === 'function') {\n return link(node) ?? null\n }\n\n return node.path ? `{@link ${Url.toPath(node.path)}}` : null\n}\n\n/**\n * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several\n * are present and the union, default, and form-data flags the client uses to pick one.\n */\nfunction buildContentTypeInfo(contentTypes: string[]): ContentTypeInfo {\n const isMultipleContentTypes = contentTypes.length > 1\n\n return {\n contentTypes,\n isMultipleContentTypes,\n contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(' | ') : '',\n defaultContentType: contentTypes[0] ?? 'application/json',\n hasFormData: contentTypes.some((ct) => ct === 'multipart/form-data'),\n }\n}\n\nexport function getContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? [])\n}\n\n/**\n * The request-body counterpart for the primary success response: the content types it documents and\n * whether several are present, so the client can let a caller pick which one to accept.\n */\nexport function getResponseContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [])\n}\n\nexport type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n\n/**\n * Reads the single base content type of an operation's primary success response, lowercased and\n * stripped of any `; charset=...` suffix. Returns `undefined` when the response declares zero or\n * more than one content type, since neither case has a single type to act on.\n */\nfunction getPrimarySuccessContentType(node: ast.OperationNode): string | undefined {\n const contentTypes = getPrimarySuccessResponse(node)?.content?.map((entry) => entry.contentType) ?? []\n if (contentTypes.length !== 1) return undefined\n return contentTypes[0]!.split(';')[0]!.trim().toLowerCase()\n}\n\n/**\n * Whether an operation streams its primary success response as Server-Sent Events\n * (`text/event-stream`). The client generator uses this to return a typed event stream instead of a\n * one-shot `RequestResult`.\n */\nexport function isEventStream(node: ast.OperationNode): boolean {\n return getPrimarySuccessContentType(node) === 'text/event-stream'\n}\n\n/**\n * Derives the default `responseType` for an operation from its primary success response.\n *\n * Returns a value only when that response declares a single non-JSON content type. `text/event-stream`\n * and other binary types (`application/octet-stream`, `application/pdf`, `image/*`, `audio/*`,\n * `video/*`) map to a stream or `'blob'`, and other `text/*` maps to `'text'`. Otherwise `undefined`,\n * leaving the runtime client's `Content-Type` auto-detection in charge.\n */\nexport function getResponseType(node: ast.OperationNode): ResponseType | undefined {\n const baseType = getPrimarySuccessContentType(node)\n if (!baseType) return undefined\n\n if (baseType === 'application/json' || baseType.endsWith('+json') || baseType === 'text/json') return undefined\n if (baseType === 'text/event-stream') return 'stream'\n if (baseType.startsWith('text/')) return 'text'\n if (baseType === 'application/octet-stream' || baseType === 'application/pdf' || /^(image|audio|video)\\//.test(baseType)) return 'blob'\n return undefined\n}\n\n/**\n * Maps a content type to the PascalCase suffix used to name per-content-type variants\n * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).\n */\nfunction getContentTypeSuffix(contentType: string): string {\n const baseType = contentType.split(';')[0]!.trim()\n if (baseType === 'application/json') return 'Json'\n if (baseType === 'multipart/form-data') return 'FormData'\n if (baseType === 'application/x-www-form-urlencoded') return 'FormUrlEncoded'\n const subtype = baseType.split('/').pop() ?? baseType\n const parts = subtype.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n if (parts.length === 0) return 'Unknown'\n return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join('')\n}\n\n/**\n * Appends a content-type suffix to a base name, keeping a trailing `Data` segment last\n * (e.g. `AddPetData` + `Json` → `AddPetJsonData`, `AddPetStatus200` + `Xml` → `AddPetStatus200Xml`).\n */\nexport function getPerContentTypeName(baseName: string, suffix: string): string {\n if (baseName.endsWith('Data')) {\n return suffix.endsWith('Data') ? baseName.slice(0, -4) + suffix : `${baseName.slice(0, -4)}${suffix}Data`\n }\n return baseName + suffix\n}\n\nexport type ContentVariantInput = { contentType: string; schema?: ast.SchemaNode | null; keysToOmit?: Array<string> | null }\nexport type ContentVariant = { name: string; suffix: string; schema: ast.SchemaNode; keysToOmit?: Array<string> | null; contentType: string }\n\n/**\n * Resolves per-content-type variant names for a set of content entries, deduplicating suffix\n * collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is\n * the final (possibly counter-augmented) value, so callers can derive parallel names in another\n * namespace (e.g. plugin-faker deriving the matching plugin-ts type name).\n */\nexport function resolveContentTypeVariants(entries: Array<ContentVariantInput>, baseName: string): Array<ContentVariant> {\n const usedNames = new Set<string>()\n return entries\n .filter((entry) => entry.schema)\n .map((entry) => {\n const baseSuffix = getContentTypeSuffix(entry.contentType)\n let suffix = baseSuffix\n let name = getPerContentTypeName(baseName, suffix)\n let counter = 2\n while (usedNames.has(name)) {\n suffix = `${baseSuffix}${counter++}`\n name = getPerContentTypeName(baseName, suffix)\n }\n usedNames.add(name)\n return { name, suffix, schema: entry.schema!, keysToOmit: entry.keysToOmit, contentType: entry.contentType }\n })\n}\n\nexport function buildRequestConfigType(node: ast.OperationNode): string {\n const request = getContentTypeInfo(node)\n const response = getResponseContentTypeInfo(node)\n // The request groups come from the grouped params, so `config` drops the data-shape keys to stay\n // assignable to `Options`, which omits them from `RequestConfig`.\n const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n\n // Only the ambiguous side is offered: a single-type side has nothing to pick, so it stays baked in\n // the generated call.\n const members = [\n request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null,\n response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null,\n ].filter(Boolean)\n\n return members.length ? `${configType} & { contentType?: { ${members.join('; ')} } }` : configType\n}\n\n/**\n * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,\n * `useInfiniteQuery`, `useSWR`, ...). Unlike {@link buildRequestConfigType}, it never adds a\n * `contentType?:` member: query hooks wrap GET operations, which carry no request body to select a\n * content type for.\n */\nexport function buildClientOptionType(): string {\n return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n}\n\nexport type RequestGroups = {\n path: boolean\n query: boolean\n body: boolean\n headers: boolean\n}\n\n/**\n * Which of the grouped request options an operation carries.\n */\nexport function getRequestGroups(node: ast.OperationNode): RequestGroups {\n const { path, query, header } = getOperationParameters(node)\n return {\n path: path.length > 0,\n query: query.length > 0,\n body: Boolean(node.requestBody?.content?.[0]?.schema),\n headers: header.length > 0,\n }\n}\n\nexport type RequestGroupOptionality = {\n groups: RequestGroups\n hasRequiredPath: boolean\n hasRequiredQuery: boolean\n hasRequiredHeader: boolean\n /**\n * Whether the grouped request parameter can default to `{}`. True only when no group carries a\n * required member, so every member is safe to omit.\n */\n isOptional: boolean\n}\n\n/**\n * Resolves which grouped request options an operation carries together with whether each group\n * holds a required member. The grouped parameter stays optional only when nothing inside it is\n * required, matching the generated `RequestConfig` type.\n */\nexport function getRequestGroupOptionality(node: ast.OperationNode): RequestGroupOptionality {\n const groups = getRequestGroups(node)\n const { path, query, header } = getOperationParameters(node)\n const hasRequiredPath = path.some((param) => param.required)\n const hasRequiredQuery = query.some((param) => param.required)\n const hasRequiredHeader = header.some((param) => param.required)\n\n return {\n groups,\n hasRequiredPath,\n hasRequiredQuery,\n hasRequiredHeader,\n isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body,\n }\n}\n\nexport type RequestOptionsNameResolver = RequestConfigResolver & {\n response: {\n options(node: ast.OperationNode): string\n }\n}\n\n/**\n * Builds the grouped `{ path, query, body, headers }` parameter for a generated client\n * function, typed from the operation's `Options` (minus `url`). Only the groups the\n * operation actually has are destructured. The trailing `config` parameter carries the\n * runtime `RequestConfig` overrides plus `client`.\n */\nexport function buildRequestParamsSignature(\n node: ast.OperationNode,\n resolver: RequestOptionsNameResolver,\n options: { isConfigurable?: boolean } = {},\n): { signature: string; groups: RequestGroups } {\n const { isConfigurable = true } = options\n const { groups, isOptional } = getRequestGroupOptionality(node)\n\n const names = (['path', 'query', 'body', 'headers'] as const).filter((key) => groups[key])\n\n const firstParam = names.length > 0 ? `{ ${names.join(', ')} }: ${resolver.response.options(node)}${isOptional ? ' = {}' : ''}` : null\n const configParam = isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null\n\n return {\n signature: [firstParam, configParam].filter(Boolean).join(', '),\n groups,\n }\n}\n\nexport function buildOperationComments(node: ast.OperationNode, options: BuildOperationCommentsOptions = {}): Array<string> {\n const { link = 'pathTemplate', linkPosition = 'afterDeprecated', splitLines = false } = options\n const linkComment = getOperationLink(node, link)\n const comments =\n linkPosition === 'beforeDeprecated'\n ? [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, linkComment, node.deprecated && '@deprecated']\n : [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, node.deprecated && '@deprecated', linkComment]\n\n const filteredComments = comments.filter((comment): comment is string => Boolean(comment))\n\n if (!splitLines) {\n return filteredComments\n }\n\n return filteredComments.flatMap((text) => text.split(/\\r?\\n/).map((line) => line.trim())).filter((comment): comment is string => Boolean(comment))\n}\n\nconst operationParameterGroupsByNode = new WeakMap<ast.OperationNode, OperationParameterGroups>()\n\n/**\n * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each\n * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance\n * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the\n * same parameters once per plugin.\n */\nexport function getOperationParameters(node: ast.OperationNode): OperationParameterGroups {\n const cached = operationParameterGroupsByNode.get(node)\n if (cached) return cached\n\n const groups: OperationParameterGroups = {\n path: dedupeParams(node.parameters.filter((param) => param.in === 'path')),\n query: dedupeParams(node.parameters.filter((param) => param.in === 'query')),\n header: dedupeParams(node.parameters.filter((param) => param.in === 'header')),\n cookie: dedupeParams(node.parameters.filter((param) => param.in === 'cookie')),\n }\n\n operationParameterGroupsByNode.set(node, groups)\n return groups\n}\n\n/**\n * Builds the combined `{ body, path, query, headers }` options object schema for an operation,\n * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s\n * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same\n * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod\n * printer to emit `z.object(…)` rather than a record.\n */\nexport function buildOptionsSchema(node: ast.OperationNode, resolver: OperationTypeNameResolver): ast.SchemaNode {\n const { path, query, header } = getOperationParameters(node)\n const hasBody = Boolean(node.requestBody?.content?.[0]?.schema)\n const createNever = () => ast.factory.createSchema({ type: 'never', primitive: undefined, optional: true })\n const groups = [\n { name: 'path', params: path, resolve: resolver.param.path },\n { name: 'query', params: query, resolve: resolver.param.query },\n { name: 'headers', params: header, resolve: resolver.param.headers },\n ] as const\n\n // NOTE(v5-stable): the fields were renamed from the legacy beta shape\n // (`data`/`pathParams`/`queryParams`/`headerParams`) to `body`/`path`/`query`/`headers` so the\n // type matches the runtime client. Drop this note once v5 leaves beta.\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n deprecated: node.deprecated,\n properties: [\n ast.factory.createProperty({\n name: 'body',\n required: hasBody,\n schema: hasBody ? ast.factory.createSchema({ type: 'ref', name: resolver.response.body(node) }) : createNever(),\n }),\n ...groups.map(({ name, params, resolve }) => {\n const required = params.some((param) => param.required)\n\n return ast.factory.createProperty({\n name,\n required,\n schema:\n params.length > 0\n ? ast.factory.createSchema({ type: 'ref', name: resolve.call(resolver.param, node, params[0]!), optional: !required })\n : createNever(),\n })\n }),\n ],\n })\n}\n\n/**\n * The schema a status occupies in the `<Name>Responses` record. A status that documents several\n * content types becomes a `{ contentType; data }` union so the runtime can surface the negotiated type\n * on `result.parsed`, while the standalone `<Name>StatusNNN` alias stays the plain body union that the\n * query hooks and `result.data` use.\n */\nfunction buildResponseRecordEntry(node: ast.OperationNode, res: ast.ResponseNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n const statusName = resolver.response.status(node, res.statusCode)\n const variants = (res.content ?? []).filter((entry) => entry.schema)\n if (variants.length <= 1) {\n return ast.factory.createSchema({ type: 'ref', name: statusName })\n }\n\n return ast.factory.createSchema({\n type: 'union',\n members: resolveContentTypeVariants(variants, statusName).map((variant) =>\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: [\n ast.factory.createProperty({\n name: 'contentType',\n required: true,\n schema: ast.factory.createSchema({ type: 'enum', enumValues: [variant.contentType] }),\n }),\n ast.factory.createProperty({\n name: 'data',\n required: true,\n schema: ast.factory.createSchema({ type: 'ref', name: variant.name }),\n }),\n ],\n }),\n ),\n })\n}\n\n/**\n * Builds the per-status `<Name>Responses` record for an operation, referencing the already-resolved\n * `<Name>StatusNNN` names. Shared by `@kubb/plugin-ts`'s `Responses` type and `@kubb/plugin-zod`'s\n * inferred responses schema, so both emit the same shape from the same inputs.\n *\n * Always emits the keyed record, even when an operation declares no responses. An operation with no\n * responses renders as an empty object, which keeps every consumer's import (for example the axios\n * SDK's `RequestResult<XResponses>`) resolvable instead of pointing at a missing export.\n */\nexport function buildResponses(node: ast.OperationNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: node.responses.map((res) =>\n ast.factory.createProperty({\n name: String(res.statusCode),\n required: true,\n schema: buildResponseRecordEntry(node, res, resolver),\n }),\n ),\n })\n}\n\nexport function getStatusCodeNumber(statusCode: ast.StatusCode | number | string): number | null {\n const code = Number(statusCode)\n\n return Number.isNaN(code) ? null : code\n}\n\nexport function isSuccessStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 200 && code < 300\n}\n\nexport function isErrorStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 400\n}\n\nexport function getSuccessResponses<TResponse extends ResponseLike>(responses: ReadonlyArray<TResponse>): Array<TResponse> {\n return responses.filter((response) => isSuccessStatusCode(response.statusCode))\n}\n\nexport function getOperationSuccessResponses(node: ast.OperationNode): Array<ast.ResponseNode> {\n return getSuccessResponses(node.responses)\n}\n\nexport function getPrimarySuccessResponse(node: ast.OperationNode): ast.ResponseNode | null {\n return getOperationSuccessResponses(node)[0] ?? null\n}\n\nexport function resolveErrorNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveSuccessNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveStatusCodeNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.map((response) => resolver.response.status(node, response.statusCode))\n}\n\nconst typeNamesByResolver = new WeakMap<OperationTypeNameResolver, Map<string, string[]>>()\n\nexport function resolveOperationTypeNames(\n node: ast.OperationNode,\n resolver: OperationTypeNameResolver,\n options: ResolveOperationTypeNameOptions = {},\n): string[] {\n const cacheKey = `${node.operationId}\\0${options.order ?? ''}\\0${options.responseStatusNames ?? ''}\\0${options.includeParams === false ? 'noparams' : ''}\\0${(options.exclude ?? []).join(',')}`\n let byResolver = typeNamesByResolver.get(resolver)\n if (byResolver) {\n const cached = byResolver.get(cacheKey)\n if (cached) return cached\n } else {\n byResolver = new Map()\n typeNamesByResolver.set(resolver, byResolver)\n }\n\n const { path, query, header } = getOperationParameters(node)\n const responseStatusNames =\n options.responseStatusNames === 'error'\n ? resolveErrorNames(node, resolver)\n : options.responseStatusNames === false\n ? []\n : resolveStatusCodeNames(node, resolver)\n const exclude = new Set(options.exclude ?? [])\n const paramNames =\n options.includeParams === false\n ? []\n : [\n ...path.map((param) => resolver.param.path(node, param)),\n ...query.map((param) => resolver.param.query(node, param)),\n ...header.map((param) => resolver.param.headers(node, param)),\n ]\n const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)]\n const names =\n options.order === 'body-response-first'\n ? [...bodyAndResponseNames, ...paramNames, ...responseStatusNames]\n : [...paramNames, ...bodyAndResponseNames, ...responseStatusNames]\n\n const result = names.filter((name): name is string => Boolean(name) && !exclude.has(name as string))\n byResolver.set(cacheKey, result)\n return result\n}\n\nexport function resolveResponseTypes(node: ast.OperationNode, resolver: ResponseNameResolver): Array<[statusCode: number | 'default', typeName: string]> {\n const types: Array<[number | 'default', string]> = []\n\n for (const response of node.responses) {\n if (response.statusCode === 'default') {\n types.push(['default', resolver.response.response(node)])\n continue\n }\n\n const code = getStatusCodeNumber(response.statusCode)\n if (code === null) {\n continue\n }\n\n types.push([code, isSuccessStatusCode(code) ? resolver.response.response(node) : resolver.response.status(node, response.statusCode)])\n }\n\n return types\n}\n\nexport function findSuccessStatusCode(responses: Array<{ statusCode: ast.StatusCode | number | string }>): ast.StatusCode | null {\n for (const response of responses) {\n if (isSuccessStatusCode(response.statusCode)) {\n return response.statusCode as ast.StatusCode\n }\n }\n\n return null\n}\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n\n/**\n * Uppercases only the first character of `text`, leaving the rest untouched.\n * Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.\n *\n * @example\n * `capitalize('getPetById') // 'GetPetById'`\n */\nexport function capitalize(text: string): string {\n return `${text.charAt(0).toUpperCase()}${text.slice(1)}`\n}\n\n/**\n * Converts `text` to snake_case.\n *\n * @example From camelCase\n * `snakeCase('helloWorld') // 'hello_world'`\n *\n * @example From mixed separators\n * `snakeCase('Hello-World') // 'hello_world'`\n */\nexport function snakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n const processed = `${prefix} ${text} ${suffix}`.trim()\n return processed\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * Converts `text` to SCREAMING_SNAKE_CASE.\n *\n * @example From camelCase\n * `screamingSnakeCase('helloWorld') // 'HELLO_WORLD'`\n */\nexport function screamingSnakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return snakeCase(text, { prefix, suffix }).toUpperCase()\n}\n","import { camelCase } from '@internals/utils'\nimport type { Group } from 'kubb/kit'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use the camelCased group (`pet store` → `petStore`).\n *\n * A user-provided `group.name` always wins over the default namer, so callers stay in\n * control of their output folders. Returns `null` when grouping is disabled, matching the\n * per-plugin convention.\n *\n * @param group - The user-supplied group option, or `undefined` to disable grouping.\n *\n * @example\n * ```ts\n * createGroupConfig(group) // shared across every plugin\n * ```\n */\nexport function createGroupConfig(group: Group | undefined): Group | null {\n if (!group) {\n return null\n }\n\n const defaultName = (ctx: { group: string }): string => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return camelCase(ctx.group)\n }\n\n return {\n ...group,\n name: group.name ? group.name : defaultName,\n } satisfies Group\n}\n","import { buildOperationComments, buildRequestParamsSignature } from '@internals/shared'\nimport { ast } from 'kubb/kit'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport { File, Function } from 'kubb/jsx'\nimport type { KubbReactNode } from 'kubb/jsx'\n\ntype Props = {\n /**\n * Name of the handler function.\n */\n name: string\n /**\n * Name of the contract client `<op>` the handler calls.\n */\n clientName: string\n /**\n * AST operation node.\n */\n node: ast.OperationNode\n /**\n * TypeScript resolver for resolving param/data/response type names.\n */\n resolver: ResolverTs\n /**\n * The registered client plugin's `returnType`, read by the caller off `resolveClientOperation`.\n */\n returnType?: 'full' | 'data'\n}\n\nconst requestGroupOrder = ['path', 'query', 'headers', 'body'] as const\n\nexport function McpHandler({ name, clientName, node, resolver, returnType = 'full' }: Props): KubbReactNode {\n if (!ast.isHttpOperationNode(node)) return null\n\n const { signature, groups } = buildRequestParamsSignature(node, resolver, { isConfigurable: false })\n const paramsSignature = [signature, 'request: RequestHandlerExtra<ServerRequest, ServerNotification>'].filter(Boolean).join(', ')\n\n // Forward the grouped config and MCP cancellation signal through the contract client. `throwOnError: true`\n // pins the result shape, since `throwOnErrorDefault: false` would otherwise resolve to the full result.\n const callArgs = requestGroupOrder.filter((key) => groups[key])\n const callConfig = `{ ${[...callArgs, 'signal: request.signal', 'throwOnError: true'].join(', ')} }`\n const body = returnType === 'data' ? 'res' : 'res.data'\n\n const callToolResult = `return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(${body})\n }\n ],\n structuredContent: { data: ${body} }\n}`\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function\n name={name}\n async\n export\n params={paramsSignature}\n JSDoc={{\n comments: buildOperationComments(node),\n }}\n returnType={'CallToolResult'}\n >\n {`const res = await ${clientName}(${callConfig})`}\n <br />\n {callToolResult}\n </Function>\n </File.Source>\n )\n}\n","import type { ast } from 'kubb/kit'\n\nexport type ZodParam = {\n name: string\n schemaName: string\n}\n\n/**\n * Render a group param value — compose individual schemas into `z.object({ ... })`,\n * or use a schema name string directly.\n */\nexport function zodGroupExpr(entry: string | Array<ZodParam>): string {\n if (typeof entry === 'string') {\n return entry\n }\n const entries = entry.map((p) => `${JSON.stringify(p.name)}: ${p.schemaName}`)\n return `z.object({ ${entries.join(', ')} })`\n}\n\n/**\n * Convert a SchemaNode type to an inline Zod expression string.\n * Used as fallback when no named zod schema is available for a path parameter.\n */\nexport function zodExprFromSchemaNode(schema: ast.SchemaNode): string {\n const baseExpr = (() => {\n if (schema.type === 'enum') {\n const rawValues: Array<string | number | boolean> = schema.namedEnumValues?.length\n ? schema.namedEnumValues.map((v) => v.value)\n : (schema.enumValues ?? []).filter((v): v is string | number | boolean => v !== null)\n\n if (rawValues.length > 0 && rawValues.every((v) => typeof v === 'string')) {\n return `z.enum([${rawValues.map((v) => JSON.stringify(v)).join(', ')}])`\n }\n if (rawValues.length > 0) {\n const literals = rawValues.map((v) => `z.literal(${JSON.stringify(v)})`)\n return literals.length === 1 ? literals[0]! : `z.union([${literals.join(', ')}])`\n }\n return 'z.string()'\n }\n if (schema.type === 'integer') return 'z.coerce.number()'\n if (schema.type === 'number') return 'z.number()'\n if (schema.type === 'boolean') return 'z.boolean()'\n if (schema.type === 'array') return 'z.array(z.unknown())'\n return 'z.string()'\n })()\n\n return schema.nullable ? `${baseExpr}.nullable()` : baseExpr\n}\n","import { getOperationParameters } from '@internals/shared'\nimport type { ast } from 'kubb/kit'\nimport { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, functionPrinter } from '@kubb/plugin-ts'\nimport { Const, File, Function } from 'kubb/jsx'\nimport type { KubbReactNode } from 'kubb/jsx'\nimport type { ZodParam } from '../utils.ts'\nimport { zodExprFromSchemaNode, zodGroupExpr } from '../utils.ts'\n\ntype Props = {\n /**\n * Variable name for the MCP server instance (e.g. 'server').\n */\n name: string\n /**\n * Human-readable server name passed to `new McpServer({ name })`.\n */\n serverName: string\n /**\n * Semantic version string passed to `new McpServer({ version })`.\n */\n serverVersion: string\n /**\n * Operations to register as MCP tools, each carrying its handler,\n * zod schema, and AST node metadata.\n */\n operations: Array<{\n tool: {\n name: string\n title?: string\n description: string\n }\n mcp: {\n name: string\n file: ast.FileNode\n }\n zod: {\n pathParams: Array<ZodParam>\n /**\n * Query params — individual schemas to compose into `z.object({ ... })`.\n */\n queryParams?: string | Array<ZodParam> | null\n /**\n * Header params — individual schemas to compose into `z.object({ ... })`.\n */\n headerParams?: string | Array<ZodParam> | null\n requestName?: string | null\n responseName?: string | null\n }\n node: ast.OperationNode\n }>\n}\n\nconst keysPrinter = functionPrinter({ mode: 'call' })\n\nexport function Server({ name, serverName, serverVersion, operations }: Props): KubbReactNode {\n const registrations = operations\n .map(({ tool, mcp, zod, node }) => {\n const { path: pathParams } = getOperationParameters(node)\n\n // Group params into the same `{ path, query, headers, body }` shape the contract `<op>`\n // expects, so the MCP tool input mirrors every other client consumer.\n const entries: Array<{ key: string; value: string }> = []\n\n if (pathParams.length) {\n const pathFields = pathParams\n .map((p) => {\n const zodParam = zod.pathParams.find((zp) => zp.name === p.name)\n return `${JSON.stringify(p.name)}: ${zodParam ? zodParam.schemaName : zodExprFromSchemaNode(p.schema)}`\n })\n .join(', ')\n entries.push({ key: 'path', value: `z.object({ ${pathFields} })` })\n }\n\n if (zod.queryParams) {\n entries.push({ key: 'query', value: zodGroupExpr(zod.queryParams) })\n }\n\n if (zod.headerParams) {\n entries.push({ key: 'headers', value: zodGroupExpr(zod.headerParams) })\n }\n\n if (zod.requestName) {\n entries.push({ key: 'body', value: zod.requestName })\n }\n\n const paramsNode = entries.length\n ? createFunctionParameters({\n params: [\n createFunctionParameter({\n name: createObjectBindingPattern({ elements: entries.map((e) => ({ name: e.key })) }),\n optional: false,\n }),\n ],\n })\n : null\n\n const destructured = paramsNode ? (keysPrinter.print(paramsNode) ?? '') : ''\n const inputSchema = entries.length ? `{ ${entries.map((e) => `${e.key}: ${e.value}`).join(', ')} }` : null\n const outputSchema = zod.responseName\n\n const config = [\n tool.title ? `title: ${JSON.stringify(tool.title)}` : null,\n `description: ${JSON.stringify(tool.description)}`,\n outputSchema ? `outputSchema: { data: ${outputSchema} }` : null,\n ]\n .filter(Boolean)\n .join(',\\n ')\n\n if (inputSchema) {\n return `\nserver.registerTool(${JSON.stringify(tool.name)}, {\n ${config},\n inputSchema: ${inputSchema},\n}, async (${destructured}, request) => {\n return ${mcp.name}(${destructured}, request)\n})\n `\n }\n\n return `\nserver.registerTool(${JSON.stringify(tool.name)}, {\n ${config},\n}, async (request) => {\n return ${mcp.name}(request)\n})\n `\n })\n .filter(Boolean)\n .join('\\n')\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function name=\"getServer\" export>\n {`const server = new McpServer({\n name: '${serverName}',\n version: '${serverVersion}',\n})\n${registrations}\nreturn server`}\n </Function>\n\n <Const name={'server'} export>\n {'getServer()'}\n </Const>\n\n <Function name=\"startServer\" async export>\n {`try {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n\n } catch (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }`}\n </Function>\n </File.Source>\n )\n}\n","/**\n * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an\n * operation, shared so the selection rules and diagnostics stay in one place.\n *\n * Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered\n * contract client plugin (plugin-fetch or plugin-axios) and never emits its own inline client:\n *\n * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer\n * imports and calls them.\n * - `error` — no client plugin is registered, several are registered without a selector, or the\n * requested one is missing.\n *\n * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered\n * contract client plugin is picked up automatically.\n */\n\n// Canonical plugin names. They mirror the `pluginFetchName` / `pluginAxiosName` consts the plugins\n// export, kept as literals so this internal needs no plugin install deps.\nconst pluginFetchName = 'plugin-fetch'\nconst pluginAxiosName = 'plugin-axios'\n\n/**\n * The client selector accepted by a consumer's `client` option. Both call a registered contract\n * client plugin.\n */\nexport type ClientSelector = 'fetch' | 'axios'\n\n/**\n * The resolved client strategy stored in a consumer plugin's options: the generated code always\n * imports and calls a registered contract client plugin's `<op>`. The client runtime lives in\n * plugin-axios / plugin-fetch, so nothing is bundled by the consumer.\n */\nexport type ResolvedContractClient = { kind: 'contract'; pluginName: string }\n\n/**\n * The outcome of {@link resolveClient}.\n *\n * - `contract` names the contract client plugin whose `<op>` functions the consumer imports.\n * - `error` carries a setup diagnostic.\n */\nexport type ResolveClientResult = ResolvedContractClient | { kind: 'error'; message: string }\n\nconst selectorToPlugin: Record<'fetch' | 'axios', string> = {\n fetch: pluginFetchName,\n axios: pluginAxiosName,\n}\n\n// Every contract client plugin, in auto-detect priority order.\nconst contractPlugins = [pluginFetchName, pluginAxiosName] as const\n\n/**\n * Applies the `client` resolution rules. See the module comment for the strategy shape.\n *\n * @example\n * ```ts\n * resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })\n * // { kind: 'contract', pluginName: 'plugin-fetch' }\n * ```\n *\n * @example\n * ```ts\n * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })\n * // { kind: 'error', message: 'No client plugin is registered…' }\n * ```\n */\nexport function resolveClient(options: { client: ClientSelector | undefined; pluginNames: ReadonlyArray<string> }): ResolveClientResult {\n const { client, pluginNames } = options\n const has = (name: string) => pluginNames.includes(name)\n\n if (client === 'fetch' || client === 'axios') {\n const pluginName = selectorToPlugin[client]\n if (!has(pluginName)) {\n return {\n kind: 'error',\n message: `\\`client: '${client}'\\` is set but \\`@kubb/plugin-${client}\\` is not registered in \\`plugins\\`. Add it, or drop \\`client\\` to use a different client plugin.`,\n }\n }\n return { kind: 'contract', pluginName }\n }\n\n // `client` unset: auto-detect a lone registered contract client plugin.\n const registered = contractPlugins.filter(has)\n if (registered.length === 1) {\n return { kind: 'contract', pluginName: registered[0]! }\n }\n if (registered.length > 1) {\n return {\n kind: 'error',\n message: `Multiple client plugins are registered (${registered.map((name) => `\\`@kubb/${name}\\``).join(', ')}). Set \\`client: 'fetch' | 'axios'\\` to choose which client the hooks call, or register a single client plugin.`,\n }\n }\n\n return {\n kind: 'error',\n message: 'No client plugin is registered. Add `@kubb/plugin-axios` or `@kubb/plugin-fetch` to `plugins` so the generated code has an HTTP client to call.',\n }\n}\n\n/**\n * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names\n * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a\n * misconfiguration so every consumer fails fast with the same message.\n */\nexport function resolveContractClient(options: { client: ClientSelector | undefined; plugins?: ReadonlyArray<unknown> }): ResolvedContractClient {\n const { client, plugins = [] } = options\n const pluginNames = plugins.map((plugin) => (plugin as { name?: string }).name).filter((name): name is string => Boolean(name))\n const resolved = resolveClient({ client, pluginNames })\n if (resolved.kind === 'error') {\n throw new Error(resolved.message)\n }\n return resolved\n}\n","import path from 'node:path'\nimport { operationFileEntry } from '@internals/shared'\nimport type { ast, Exclude, Group, Include, NodeCache, Output, Override, Resolver } from 'kubb/kit'\n\n/**\n * The resolved contract `<op>` for one operation: the generated function name, the file it lives in,\n * the contract runtime's `.kubb/client.ts` path (where `RequestConfig` / `ResponseErrorConfig`\n * come from), and the registered client plugin's `returnType`.\n */\nexport type ClientOperation = { name: string; path: string; clientPath: string; returnType: 'full' | 'data' }\n\n/**\n * The client plugin options a dependent reads, including the filters that scope them per operation.\n */\ntype ClientPluginOptions = {\n output?: Output\n group?: Group | null\n returnType?: 'full' | 'data'\n exclude?: Array<Exclude>\n include?: Array<Include>\n override?: Array<Override<Omit<ClientPluginOptions, 'override'>>>\n}\n\n/**\n * Resolves the contract client `<op>` a consumer (query hook, MCP handler) imports, by looking up\n * the registered contract client plugin's resolver and output. Works for any contract client plugin\n * (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline\n * path), or when the client plugin's `exclude` / `include` leaves this operation out, since it then\n * emits no `<op>` to import. The plugin injects `.kubb/client.ts` at the global output root, the\n * same path consumers read `RequestConfig` / `ResponseErrorConfig` from.\n *\n * The result is cached in the current node's `cache` (`ctx.cache`) under the client plugin's name,\n * so several dependents reading the same client plugin for one operation in a single pass\n * (react-query's query/mutation/infinite generators, vue-query, swr, the MCP handler, ...) share\n * one computed result instead of each re-deriving the name and path.\n *\n * `returnType`, `output`, and `group` are the client plugin's options for this operation, after its\n * `override` entries, the same resolution its own generator sees. A dependent's generated call body\n * and import path therefore match the `<op>` actually emitted, even when an `override` changes it.\n */\nexport function resolveClientOperation(options: {\n clientPlugin: { pluginName: string } | null\n driver: {\n getPlugin: (name: string) => { options?: ClientPluginOptions } | undefined\n getResolver: (name: string) => Resolver\n }\n node: ast.OperationNode\n root: string\n output: Output\n cache: NodeCache\n}): ClientOperation | null {\n const { clientPlugin, driver, node, root, output, cache } = options\n if (!clientPlugin) return null\n\n return cache.ensureItem(`${clientPlugin.pluginName}:clientOperation`, () => {\n const resolver = driver.getResolver(clientPlugin.pluginName)\n const pluginOptions = driver.getPlugin(clientPlugin.pluginName)?.options ?? {}\n const { exclude, include, override } = pluginOptions\n const hasOperationOptions = Boolean(exclude?.length || include?.length || override?.length)\n // Kubb's resolver always has `default`; the fallback keeps partial or custom resolvers working.\n const operationOptions =\n hasOperationOptions && resolver.default ? resolver.default.options(node, { options: pluginOptions, exclude, include, override }) : pluginOptions\n if (!operationOptions) return null\n\n const file = resolver.file({\n ...operationFileEntry(node, node.operationId),\n root,\n output: operationOptions.output ?? output,\n group: operationOptions.group ?? undefined,\n })\n\n return {\n name: resolver.name(node.operationId),\n path: file.path,\n clientPath: path.resolve(root, '.kubb/client.ts'),\n returnType: operationOptions.returnType ?? 'full',\n }\n })\n}\n","import { resolveClientOperation } from '@internals/client'\nimport { resolveDependencyOperationFile } from '@internals/shared'\nimport { ast, defineGenerator } from 'kubb/kit'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { File, jsxRenderer } from 'kubb/jsx'\nimport { McpHandler } from '../components/McpHandler.tsx'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Built-in operation generator for `@kubb/plugin-mcp`. Emits one MCP tool\n * handler per OpenAPI operation. The handler takes the grouped `{ path, query,\n * headers, body }` config and forwards it to the registered client plugin's\n * (`@kubb/plugin-axios` / `@kubb/plugin-fetch`) `<op>` function.\n */\nexport const mcpGenerator = defineGenerator<PluginMcp>({\n name: 'mcp',\n renderer: jsxRenderer,\n operation(node, ctx) {\n if (!ast.isHttpOperationNode(node)) return null\n const { resolver, driver, root, config } = ctx\n const { output, client, group } = ctx.options\n\n const pluginTs = driver.getPlugin(pluginTsName)\n\n if (!pluginTs) {\n return null\n }\n\n const tsResolver = driver.getResolver(pluginTsName)\n\n // The registered contract client plugin owns the `<op>` the handler imports and calls.\n const contractOp = resolveClientOperation({ clientPlugin: { pluginName: client.pluginName }, driver, node, root, output, cache: ctx.cache })\n if (!contractOp) {\n return null\n }\n\n // The handler signature references the grouped `<Name>Options`.\n const optionsName = tsResolver.response.options(node)\n\n const meta = {\n name: resolver.handler.name(node),\n file: resolver.file({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path, root, output, group: group ?? undefined }),\n fileTs: resolveDependencyOperationFile({\n cache: ctx.cache,\n node,\n resolver: tsResolver,\n root,\n output: pluginTs.options?.output ?? output,\n group: pluginTs.options?.group,\n }),\n } as const\n\n return (\n <File\n baseName={meta.file.baseName}\n path={meta.file.path}\n meta={meta.file.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n >\n {meta.fileTs && optionsName && <File.Import name={[optionsName]} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />}\n <File.Import name={['CallToolResult', 'ServerNotification', 'ServerRequest']} path={'@modelcontextprotocol/sdk/types.js'} isTypeOnly />\n <File.Import name={['RequestHandlerExtra']} path={'@modelcontextprotocol/sdk/shared/protocol.js'} isTypeOnly />\n\n <File.Import name={[contractOp.name]} root={meta.file.path} path={contractOp.path} />\n\n <McpHandler name={meta.name} clientName={contractOp.name} node={node} resolver={tsResolver} returnType={contractOp.returnType} />\n </File>\n )\n },\n})\n","import path from 'node:path'\nimport { findSuccessStatusCode, getOperationParameters } from '@internals/shared'\nimport { ast, defineGenerator } from 'kubb/kit'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { File, jsxRenderer } from 'kubb/jsx'\nimport { Server } from '../components/Server.tsx'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Default v5 server generator for `@kubb/plugin-mcp`.\n *\n * Uses individual zod schemas for each param (e.g. `createPetsPathUuidSchema`, `createPetsQueryOffsetSchema`)\n * and `resolveResponseStatusName` for per-status response schemas.\n * Query and header params are composed into `z.object({ ... })` from individual schemas.\n */\nexport const serverGenerator = defineGenerator<PluginMcp>({\n name: 'operations',\n renderer: jsxRenderer,\n operations(nodes, ctx) {\n const { config, resolver, plugin, driver, root } = ctx\n const { output, group } = ctx.options\n\n const pluginZod = driver.getPlugin(pluginZodName)\n\n if (!pluginZod) {\n return\n }\n\n const zodResolver = driver.getResolver(pluginZodName)\n\n const name = 'server'\n const serverFilePath = path.resolve(root, output.path, 'server.ts')\n const serverFile = {\n baseName: 'server.ts' as const,\n path: serverFilePath,\n meta: { pluginName: plugin.name },\n }\n\n const jsonFilePath = path.resolve(root, output.path, '.mcp.json')\n const jsonFile = {\n baseName: '.mcp.json' as const,\n path: jsonFilePath,\n meta: { pluginName: plugin.name },\n }\n\n const operationsMapped = nodes.filter(ast.isHttpOperationNode).map((node) => {\n const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node)\n\n const mcpFile = resolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output,\n group: group ?? undefined,\n })\n\n const zodFile = zodResolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output: pluginZod.options?.output ?? output,\n group: pluginZod.options?.group ?? undefined,\n })\n\n const requestName = node.requestBody?.content?.[0]?.schema ? zodResolver.response.body(node) : null\n const successStatus = findSuccessStatusCode(node.responses)\n const responseName = successStatus ? zodResolver.response.status(node, successStatus) : null\n\n const resolveParams = (params: typeof pathParams) => params.map((p) => ({ name: p.name, schemaName: zodResolver.param.name(node, p) }))\n\n return {\n tool: {\n name: node.operationId,\n title: node.summary || undefined,\n description: node.description || `Make a ${node.method.toUpperCase()} request to ${node.path}`,\n },\n mcp: {\n name: resolver.handler.name(node),\n file: mcpFile,\n },\n zod: {\n pathParams: resolveParams(pathParams),\n queryParams: queryParams.length ? resolveParams(queryParams) : null,\n headerParams: headerParams.length ? resolveParams(headerParams) : null,\n requestName,\n responseName,\n file: zodFile,\n },\n node: node,\n }\n })\n\n const imports = operationsMapped.flatMap(({ mcp, zod }) => {\n const zodNames = [\n ...zod.pathParams.map((p) => p.schemaName),\n ...(zod.queryParams ?? []).map((p) => p.schemaName),\n ...(zod.headerParams ?? []).map((p) => p.schemaName),\n zod.requestName,\n zod.responseName,\n ].filter((name): name is string => Boolean(name))\n\n const uniqueNames = [...new Set(zodNames)].sort()\n\n return [\n <File.Import key={mcp.name} name={[mcp.name]} root={serverFile.path} path={mcp.file.path} />,\n uniqueNames.length > 0 && <File.Import key={`zod-${mcp.name}`} name={uniqueNames} root={serverFile.path} path={zod.file.path} />,\n ].filter(Boolean)\n })\n\n return (\n <>\n <File\n baseName={serverFile.baseName}\n path={serverFile.path}\n meta={serverFile.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: serverFile.path, baseName: serverFile.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: serverFile.path, baseName: serverFile.baseName } })}\n >\n <File.Import name={['McpServer']} path={'@modelcontextprotocol/sdk/server/mcp.js'} />\n <File.Import name={['z']} path={'zod'} />\n <File.Import name={['StdioServerTransport']} path={'@modelcontextprotocol/sdk/server/stdio.js'} />\n\n {imports}\n <Server name={name} serverName={ctx.meta.title ?? 'server'} serverVersion={ctx.meta.version ?? '0.0.0'} operations={operationsMapped} />\n </File>\n\n <File baseName={jsonFile.baseName} path={jsonFile.path} meta={jsonFile.meta}>\n <File.Source name={name}>\n {`\n {\n \"mcpServers\": {\n \"${ctx.meta.title || 'server'}\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"${path.relative(path.dirname(jsonFile.path), serverFile.path)}\"]\n }\n }\n }\n `}\n </File.Source>\n </File>\n </>\n )\n },\n})\n","import { camelCase } from '@internals/utils'\nimport { createResolver } from 'kubb/kit'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-mcp`. Decides the names and file\n * paths for every generated MCP tool handler. Function names get a `Handler`\n * suffix so an operation `addPet` becomes `addPetHandler`.\n *\n * @example Resolve a handler name\n * ```ts\n * import { resolverMcp } from '@kubb/plugin-mcp'\n *\n * resolverMcp.name('addPet') // 'addPetHandler'\n * ```\n */\nexport const resolverMcp = createResolver<PluginMcp>({\n pluginName: 'plugin-mcp',\n name(name) {\n return camelCase(name, { suffix: 'handler' })\n },\n handler: {\n name(node) {\n return this.name(node.operationId)\n },\n },\n})\n","import { createGroupConfig } from '@internals/shared'\n\nimport { resolveContractClient } from '@internals/client'\nimport { definePlugin, Resolver } from 'kubb/kit'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { mcpGenerator } from './generators/mcpGenerator.tsx'\nimport { serverGenerator } from './generators/serverGenerator.tsx'\nimport { resolverMcp } from './resolvers/resolverMcp.ts'\nimport type { PluginMcp, ResolverMcp } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-mcp`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginMcpName = 'plugin-mcp' satisfies PluginMcp['name']\n\n/**\n * Generates a Model Context Protocol (MCP) server from an OpenAPI spec. Every\n * operation becomes a typed MCP tool that AI assistants (Claude Desktop, Claude\n * Code, MCP-compatible clients) can call directly. Each handler calls a contract\n * client `<op>` from a registered `@kubb/plugin-axios` or `@kubb/plugin-fetch`.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb/config'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginZod } from '@kubb/plugin-zod'\n * import { pluginMcp } from '@kubb/plugin-mcp'\n *\n * export default defineConfig({\n * input: './petStore.yaml',\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginZod(),\n * pluginMcp({\n * output: { path: './mcp' },\n * baseURL: 'https://petstore.swagger.io/v2',\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginMcp = definePlugin<PluginMcp>((options) => {\n const {\n output = { path: 'mcp', barrel: { type: 'named' } },\n group,\n exclude = [],\n include,\n override = [],\n client,\n resolver: userResolver,\n macros: userMacros,\n } = options\n\n const groupConfig = createGroupConfig(group)\n\n return {\n name: pluginMcpName,\n options,\n dependencies: [pluginTsName, pluginZodName],\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n const resolver = userResolver ? Resolver.merge<ResolverMcp>(resolverMcp, userResolver) : resolverMcp\n\n ctx.setOptions({\n output,\n exclude,\n include,\n override,\n group: groupConfig,\n client: resolveContractClient({ client, plugins: ctx.config.plugins }),\n resolver,\n })\n ctx.setResolver(resolver)\n if (userMacros?.length) {\n ctx.setMacros(userMacros)\n }\n ctx.addGenerator(mcpGenerator, serverGenerator)\n },\n },\n }\n})\n\nexport default pluginMcp\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["Url","ast","File","Function","functionPrinter","createFunctionParameters","createFunctionParameter","createObjectBindingPattern","File","Function","Const","path","defineGenerator","jsxRenderer","ast","pluginTsName","File","defineGenerator","jsxRenderer","pluginZodName","path","ast","File","createResolver","definePlugin","pluginTsName","pluginZodName","Resolver"],"sources":["../../../internals/shared/src/params.ts","../../../internals/shared/src/operation.ts","../../../internals/utils/src/casing.ts","../../../internals/shared/src/group.ts","../src/components/McpHandler.tsx","../src/utils.ts","../src/components/Server.tsx","../../../internals/client/src/resolveClient.ts","../../../internals/client/src/resolveClientOperation.ts","../src/generators/mcpGenerator.tsx","../src/generators/serverGenerator.tsx","../src/resolvers/resolverMcp.ts","../src/plugin.ts"],"sourcesContent":["import type { ast } from 'kubb/kit'\n\n/**\n * Drops parameters that share the same name, keeping the first.\n *\n * A malformed spec can declare the same parameter name twice within one `in` location. Both would\n * resolve to the same output property, so emitting both would yield an object type with a duplicate\n * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:\n * parameter names flow through unchanged, so no two distinct names ever collide here anymore.\n */\nexport function dedupeParams(params: Array<ast.ParameterNode>): Array<ast.ParameterNode> {\n const seen = new Set<string>()\n\n return params.filter((param) => {\n if (seen.has(param.name)) return false\n seen.add(param.name)\n return true\n })\n}\n","import { ast, type Group, type NodeCache, type Output, type Resolver, type ResolverFileParams, Url } from 'kubb/kit'\nimport { dedupeParams } from './params.ts'\n\n/**\n * Builds the `ResolverFileParams` every operation generator passes to\n * `resolver.file`: a file named `name`, tagged by the operation's first\n * tag (or `'default'`), at the operation's path. Centralizes the entry object\n * that was repeated at dozens of call sites across the client and query plugins.\n *\n * @example\n * ```ts\n * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })\n * ```\n */\nexport function operationFileEntry(node: ast.OperationNode, name: string, extname: ResolverFileParams['extname'] = '.ts'): ResolverFileParams {\n return {\n name,\n extname,\n tag: node.tags[0] ?? 'default',\n path: node.path,\n }\n}\n\n/**\n * Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the\n * current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the\n * same dependency for the same operation in one pass (a query plugin's several hook generators, the\n * MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.\n *\n * @example Cache `plugin-ts`'s file for the current operation\n * ```ts\n * const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })\n * ```\n */\nexport function resolveDependencyOperationFile(options: {\n cache: NodeCache\n node: ast.OperationNode\n resolver: Pick<Resolver, 'file' | 'pluginName'>\n root: string\n output: Output\n group?: Group | null\n}): ast.FileNode {\n const { cache, node, resolver, root, output, group } = options\n\n return cache.ensureItem(`${resolver.pluginName}:operationFile`, () =>\n resolver.file({ ...operationFileEntry(node, node.operationId), root, output, group: group ?? undefined }),\n )\n}\n\nexport type ContentTypeInfo = {\n contentTypes: string[]\n isMultipleContentTypes: boolean\n contentTypeUnion: string\n defaultContentType: string\n hasFormData: boolean\n}\n\nexport type RequestConfigResolver = {\n response: {\n body(node: ast.OperationNode): string\n }\n}\n\nexport type ResponseStatusNameResolver = {\n response: {\n status(node: ast.OperationNode, statusCode: ast.StatusCode): string\n }\n}\n\nexport type ResponseNameResolver = ResponseStatusNameResolver & {\n response: {\n response(node: ast.OperationNode): string\n }\n}\n\nexport type OperationTypeNameResolver = RequestConfigResolver &\n ResponseNameResolver & {\n param: {\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n }\n\n/**\n * Resolver interface for building operation parameters.\n *\n * `ResolverTs` from `@kubb/plugin-ts` satisfies this interface and can be passed directly.\n */\nexport type OperationParamsResolver = {\n /**\n * Naming for an operation's parameters, grouped by location.\n */\n param: {\n /**\n * Resolves the type name for an individual parameter.\n *\n * @example Individual path parameter name\n * `resolver.param.name(node, param) // → 'DeletePetPathPetId'`\n */\n name(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped path parameters type name.\n * When the return value equals `resolver.param.name`, no indexed access is emitted.\n *\n * @example Grouped path params type name\n * `resolver.param.path(node, param) // → 'DeletePetPath'`\n */\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped query parameters type name.\n * When the return value equals `resolver.param.name`, an inline struct type is emitted instead.\n *\n * @example Grouped query params type name\n * `resolver.param.query(node, param) // → 'FindPetsByStatusQuery'`\n */\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped header parameters type name.\n * When the return value equals `resolver.param.name`, an inline struct type is emitted instead.\n *\n * @example Grouped header params type name\n * `resolver.param.headers(node, param) // → 'DeletePetHeaders'`\n */\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n /**\n * Naming for an operation's request and response types.\n */\n response: {\n /**\n * Resolves the request body type name.\n *\n * @example Request body type name\n * `resolver.response.body(node) // → 'CreatePetBody'`\n */\n body(node: ast.OperationNode): string\n }\n}\n\nexport type OperationCommentLink = 'pathTemplate' | 'urlPath' | false | ((node: ast.OperationNode) => string | undefined)\n\nexport type BuildOperationCommentsOptions = {\n link?: OperationCommentLink\n linkPosition?: 'beforeDeprecated' | 'afterDeprecated'\n splitLines?: boolean\n}\n\ntype ResponseLike = {\n statusCode: ast.StatusCode | number | string\n}\n\nexport type OperationParameterGroups = Record<ast.ParameterNode['in'], Array<ast.ParameterNode>>\n\nexport type ResolveOperationTypeNameOptions = {\n responseStatusNames?: boolean | 'error'\n exclude?: ReadonlyArray<string | undefined>\n order?: 'params-first' | 'body-response-first'\n /**\n * Include the individual `Path`/`Query`/`Headers` group type names. Set to `false` for clients\n * that reference the grouped `Options` type instead of the per-group types.\n */\n includeParams?: boolean\n}\n\nfunction getOperationLink(node: ast.OperationNode, link: OperationCommentLink): string | null {\n if (!link) {\n return null\n }\n\n if (typeof link === 'function') {\n return link(node) ?? null\n }\n\n return node.path ? `{@link ${Url.toPath(node.path)}}` : null\n}\n\n/**\n * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several\n * are present and the union, default, and form-data flags the client uses to pick one.\n */\nfunction buildContentTypeInfo(contentTypes: string[]): ContentTypeInfo {\n const isMultipleContentTypes = contentTypes.length > 1\n\n return {\n contentTypes,\n isMultipleContentTypes,\n contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(' | ') : '',\n defaultContentType: contentTypes[0] ?? 'application/json',\n hasFormData: contentTypes.some((ct) => ct === 'multipart/form-data'),\n }\n}\n\nexport function getContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? [])\n}\n\n/**\n * The request-body counterpart for the primary success response: the content types it documents and\n * whether several are present, so the client can let a caller pick which one to accept.\n */\nexport function getResponseContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [])\n}\n\nexport type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n\n/**\n * Reads the single base content type of an operation's primary success response, lowercased and\n * stripped of any `; charset=...` suffix. Returns `undefined` when the response declares zero or\n * more than one content type, since neither case has a single type to act on.\n */\nfunction getPrimarySuccessContentType(node: ast.OperationNode): string | undefined {\n const contentTypes = getPrimarySuccessResponse(node)?.content?.map((entry) => entry.contentType) ?? []\n if (contentTypes.length !== 1) return undefined\n return contentTypes[0]!.split(';')[0]!.trim().toLowerCase()\n}\n\n/**\n * Whether an operation streams its primary success response as Server-Sent Events\n * (`text/event-stream`). The client generator uses this to return a typed event stream instead of a\n * one-shot `RequestResult`.\n */\nexport function isEventStream(node: ast.OperationNode): boolean {\n return getPrimarySuccessContentType(node) === 'text/event-stream'\n}\n\n/**\n * Derives the default `responseType` for an operation from its primary success response.\n *\n * Returns a value only when that response declares a single non-JSON content type. `text/event-stream`\n * and other binary types (`application/octet-stream`, `application/pdf`, `image/*`, `audio/*`,\n * `video/*`) map to a stream or `'blob'`, and other `text/*` maps to `'text'`. Otherwise `undefined`,\n * leaving the runtime client's `Content-Type` auto-detection in charge.\n */\nexport function getResponseType(node: ast.OperationNode): ResponseType | undefined {\n const baseType = getPrimarySuccessContentType(node)\n if (!baseType) return undefined\n\n if (baseType === 'application/json' || baseType.endsWith('+json') || baseType === 'text/json') return undefined\n if (baseType === 'text/event-stream') return 'stream'\n if (baseType.startsWith('text/')) return 'text'\n if (baseType === 'application/octet-stream' || baseType === 'application/pdf' || /^(image|audio|video)\\//.test(baseType)) return 'blob'\n return undefined\n}\n\n/**\n * Maps a content type to the PascalCase suffix used to name per-content-type variants\n * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).\n */\nfunction getContentTypeSuffix(contentType: string): string {\n const baseType = contentType.split(';')[0]!.trim()\n if (baseType === 'application/json') return 'Json'\n if (baseType === 'multipart/form-data') return 'FormData'\n if (baseType === 'application/x-www-form-urlencoded') return 'FormUrlEncoded'\n const subtype = baseType.split('/').pop() ?? baseType\n const parts = subtype.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n if (parts.length === 0) return 'Unknown'\n return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join('')\n}\n\n/**\n * Appends a content-type suffix to a base name, keeping a trailing `Data` segment last\n * (e.g. `AddPetData` + `Json` → `AddPetJsonData`, `AddPetStatus200` + `Xml` → `AddPetStatus200Xml`).\n */\nexport function getPerContentTypeName(baseName: string, suffix: string): string {\n if (baseName.endsWith('Data')) {\n return suffix.endsWith('Data') ? baseName.slice(0, -4) + suffix : `${baseName.slice(0, -4)}${suffix}Data`\n }\n return baseName + suffix\n}\n\nexport type ContentVariantInput = { contentType: string; schema?: ast.SchemaNode | null; keysToOmit?: Array<string> | null }\nexport type ContentVariant = { name: string; suffix: string; schema: ast.SchemaNode; keysToOmit?: Array<string> | null; contentType: string }\n\n/**\n * Resolves per-content-type variant names for a set of content entries, deduplicating suffix\n * collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is\n * the final (possibly counter-augmented) value, so callers can derive parallel names in another\n * namespace (e.g. plugin-faker deriving the matching plugin-ts type name).\n */\nexport function resolveContentTypeVariants(entries: Array<ContentVariantInput>, baseName: string): Array<ContentVariant> {\n const usedNames = new Set<string>()\n return entries\n .filter((entry) => entry.schema)\n .map((entry) => {\n const baseSuffix = getContentTypeSuffix(entry.contentType)\n let suffix = baseSuffix\n let name = getPerContentTypeName(baseName, suffix)\n let counter = 2\n while (usedNames.has(name)) {\n suffix = `${baseSuffix}${counter++}`\n name = getPerContentTypeName(baseName, suffix)\n }\n usedNames.add(name)\n return { name, suffix, schema: entry.schema!, keysToOmit: entry.keysToOmit, contentType: entry.contentType }\n })\n}\n\nexport function buildRequestConfigType(node: ast.OperationNode): string {\n const request = getContentTypeInfo(node)\n const response = getResponseContentTypeInfo(node)\n // The request groups come from the grouped params, so `config` drops the data-shape keys to stay\n // assignable to `Options`, which omits them from `RequestConfig`.\n const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n\n // Only the ambiguous side is offered: a single-type side has nothing to pick, so it stays baked in\n // the generated call.\n const members = [\n request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null,\n response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null,\n ].filter(Boolean)\n\n return members.length ? `${configType} & { contentType?: { ${members.join('; ')} } }` : configType\n}\n\n/**\n * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,\n * `useInfiniteQuery`, `useSWR`, ...). Unlike {@link buildRequestConfigType}, it never adds a\n * `contentType?:` member: query hooks wrap GET operations, which carry no request body to select a\n * content type for.\n */\nexport function buildClientOptionType(): string {\n return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n}\n\nexport type RequestGroups = {\n path: boolean\n query: boolean\n body: boolean\n headers: boolean\n}\n\n/**\n * Which of the grouped request options an operation carries.\n */\nexport function getRequestGroups(node: ast.OperationNode): RequestGroups {\n const { path, query, header } = getOperationParameters(node)\n return {\n path: path.length > 0,\n query: query.length > 0,\n body: Boolean(node.requestBody?.content?.[0]?.schema),\n headers: header.length > 0,\n }\n}\n\nexport type RequestGroupOptionality = {\n groups: RequestGroups\n hasRequiredPath: boolean\n hasRequiredQuery: boolean\n hasRequiredHeader: boolean\n /**\n * Whether the grouped request parameter can default to `{}`. True only when no group carries a\n * required member, so every member is safe to omit.\n */\n isOptional: boolean\n}\n\n/**\n * Resolves which grouped request options an operation carries together with whether each group\n * holds a required member. The grouped parameter stays optional only when nothing inside it is\n * required, matching the generated `RequestConfig` type.\n */\nexport function getRequestGroupOptionality(node: ast.OperationNode): RequestGroupOptionality {\n const groups = getRequestGroups(node)\n const { path, query, header } = getOperationParameters(node)\n const hasRequiredPath = path.some((param) => param.required)\n const hasRequiredQuery = query.some((param) => param.required)\n const hasRequiredHeader = header.some((param) => param.required)\n\n return {\n groups,\n hasRequiredPath,\n hasRequiredQuery,\n hasRequiredHeader,\n isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body,\n }\n}\n\nexport type RequestOptionsNameResolver = RequestConfigResolver & {\n response: {\n options(node: ast.OperationNode): string\n }\n}\n\n/**\n * Builds the grouped `{ path, query, body, headers }` parameter for a generated client\n * function, typed from the operation's `Options` (minus `url`). Only the groups the\n * operation actually has are destructured. The trailing `config` parameter carries the\n * runtime `RequestConfig` overrides plus `client`.\n */\nexport function buildRequestParamsSignature(\n node: ast.OperationNode,\n resolver: RequestOptionsNameResolver,\n options: { isConfigurable?: boolean } = {},\n): { signature: string; groups: RequestGroups } {\n const { isConfigurable = true } = options\n const { groups, isOptional } = getRequestGroupOptionality(node)\n\n const names = (['path', 'query', 'body', 'headers'] as const).filter((key) => groups[key])\n\n const firstParam = names.length > 0 ? `{ ${names.join(', ')} }: ${resolver.response.options(node)}${isOptional ? ' = {}' : ''}` : null\n const configParam = isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null\n\n return {\n signature: [firstParam, configParam].filter(Boolean).join(', '),\n groups,\n }\n}\n\nexport function buildOperationComments(node: ast.OperationNode, options: BuildOperationCommentsOptions = {}): Array<string> {\n const { link = 'pathTemplate', linkPosition = 'afterDeprecated', splitLines = false } = options\n const linkComment = getOperationLink(node, link)\n const comments =\n linkPosition === 'beforeDeprecated'\n ? [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, linkComment, node.deprecated && '@deprecated']\n : [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, node.deprecated && '@deprecated', linkComment]\n\n const filteredComments = comments.filter((comment): comment is string => Boolean(comment))\n\n if (!splitLines) {\n return filteredComments\n }\n\n return filteredComments.flatMap((text) => text.split(/\\r?\\n/).map((line) => line.trim())).filter((comment): comment is string => Boolean(comment))\n}\n\nconst operationParameterGroupsByNode = new WeakMap<ast.OperationNode, OperationParameterGroups>()\n\n/**\n * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each\n * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance\n * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the\n * same parameters once per plugin.\n */\nexport function getOperationParameters(node: ast.OperationNode): OperationParameterGroups {\n const cached = operationParameterGroupsByNode.get(node)\n if (cached) return cached\n\n const groups: OperationParameterGroups = {\n path: dedupeParams(node.parameters.filter((param) => param.in === 'path')),\n query: dedupeParams(node.parameters.filter((param) => param.in === 'query')),\n header: dedupeParams(node.parameters.filter((param) => param.in === 'header')),\n cookie: dedupeParams(node.parameters.filter((param) => param.in === 'cookie')),\n }\n\n operationParameterGroupsByNode.set(node, groups)\n return groups\n}\n\n/**\n * Builds the combined `{ body, path, query, headers }` options object schema for an operation,\n * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s\n * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same\n * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod\n * printer to emit `z.object(…)` rather than a record.\n */\nexport function buildOptionsSchema(node: ast.OperationNode, resolver: OperationTypeNameResolver): ast.SchemaNode {\n const { path, query, header } = getOperationParameters(node)\n const hasBody = Boolean(node.requestBody?.content?.[0]?.schema)\n const createNever = () => ast.factory.createSchema({ type: 'never', primitive: undefined, optional: true })\n const groups = [\n { name: 'path', params: path, resolve: resolver.param.path },\n { name: 'query', params: query, resolve: resolver.param.query },\n { name: 'headers', params: header, resolve: resolver.param.headers },\n ] as const\n\n // NOTE(v5-stable): the fields were renamed from the legacy beta shape\n // (`data`/`pathParams`/`queryParams`/`headerParams`) to `body`/`path`/`query`/`headers` so the\n // type matches the runtime client. Drop this note once v5 leaves beta.\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n deprecated: node.deprecated,\n properties: [\n ast.factory.createProperty({\n name: 'body',\n required: hasBody,\n schema: hasBody ? ast.factory.createSchema({ type: 'ref', name: resolver.response.body(node) }) : createNever(),\n }),\n ...groups.map(({ name, params, resolve }) => {\n const required = params.some((param) => param.required)\n\n return ast.factory.createProperty({\n name,\n required,\n schema:\n params.length > 0\n ? ast.factory.createSchema({ type: 'ref', name: resolve.call(resolver.param, node, params[0]!), optional: !required })\n : createNever(),\n })\n }),\n ],\n })\n}\n\n/**\n * The schema a status occupies in the `<Name>Responses` record. A status that documents several\n * content types becomes a `{ contentType; data }` union so the runtime can surface the negotiated type\n * on `result.parsed`, while the standalone `<Name>StatusNNN` alias stays the plain body union that the\n * query hooks and `result.data` use.\n */\nfunction buildResponseRecordEntry(node: ast.OperationNode, res: ast.ResponseNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n const statusName = resolver.response.status(node, res.statusCode)\n const variants = (res.content ?? []).filter((entry) => entry.schema)\n if (variants.length <= 1) {\n return ast.factory.createSchema({ type: 'ref', name: statusName })\n }\n\n return ast.factory.createSchema({\n type: 'union',\n members: resolveContentTypeVariants(variants, statusName).map((variant) =>\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: [\n ast.factory.createProperty({\n name: 'contentType',\n required: true,\n schema: ast.factory.createSchema({ type: 'enum', enumValues: [variant.contentType] }),\n }),\n ast.factory.createProperty({\n name: 'data',\n required: true,\n schema: ast.factory.createSchema({ type: 'ref', name: variant.name }),\n }),\n ],\n }),\n ),\n })\n}\n\n/**\n * Builds the per-status `<Name>Responses` record for an operation, referencing the already-resolved\n * `<Name>StatusNNN` names. Shared by `@kubb/plugin-ts`'s `Responses` type and `@kubb/plugin-zod`'s\n * inferred responses schema, so both emit the same shape from the same inputs.\n *\n * Always emits the keyed record, even when an operation declares no responses. An operation with no\n * responses renders as an empty object, which keeps every consumer's import (for example the axios\n * SDK's `RequestResult<XResponses>`) resolvable instead of pointing at a missing export.\n */\nexport function buildResponses(node: ast.OperationNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: node.responses.map((res) =>\n ast.factory.createProperty({\n name: String(res.statusCode),\n required: true,\n schema: buildResponseRecordEntry(node, res, resolver),\n }),\n ),\n })\n}\n\nexport function getStatusCodeNumber(statusCode: ast.StatusCode | number | string): number | null {\n const code = Number(statusCode)\n\n return Number.isNaN(code) ? null : code\n}\n\nexport function isSuccessStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 200 && code < 300\n}\n\nexport function isErrorStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 400\n}\n\nexport function getSuccessResponses<TResponse extends ResponseLike>(responses: ReadonlyArray<TResponse>): Array<TResponse> {\n return responses.filter((response) => isSuccessStatusCode(response.statusCode))\n}\n\nexport function getOperationSuccessResponses(node: ast.OperationNode): Array<ast.ResponseNode> {\n return getSuccessResponses(node.responses)\n}\n\nexport function getPrimarySuccessResponse(node: ast.OperationNode): ast.ResponseNode | null {\n return getOperationSuccessResponses(node)[0] ?? null\n}\n\nexport function resolveErrorNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveSuccessNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveStatusCodeNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.map((response) => resolver.response.status(node, response.statusCode))\n}\n\nconst typeNamesByResolver = new WeakMap<OperationTypeNameResolver, Map<string, string[]>>()\n\nexport function resolveOperationTypeNames(\n node: ast.OperationNode,\n resolver: OperationTypeNameResolver,\n options: ResolveOperationTypeNameOptions = {},\n): string[] {\n const cacheKey = `${node.operationId}\\0${options.order ?? ''}\\0${options.responseStatusNames ?? ''}\\0${options.includeParams === false ? 'noparams' : ''}\\0${(options.exclude ?? []).join(',')}`\n let byResolver = typeNamesByResolver.get(resolver)\n if (byResolver) {\n const cached = byResolver.get(cacheKey)\n if (cached) return cached\n } else {\n byResolver = new Map()\n typeNamesByResolver.set(resolver, byResolver)\n }\n\n const { path, query, header } = getOperationParameters(node)\n const responseStatusNames =\n options.responseStatusNames === 'error'\n ? resolveErrorNames(node, resolver)\n : options.responseStatusNames === false\n ? []\n : resolveStatusCodeNames(node, resolver)\n const exclude = new Set(options.exclude ?? [])\n const paramNames =\n options.includeParams === false\n ? []\n : [\n ...path.map((param) => resolver.param.path(node, param)),\n ...query.map((param) => resolver.param.query(node, param)),\n ...header.map((param) => resolver.param.headers(node, param)),\n ]\n const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)]\n const names =\n options.order === 'body-response-first'\n ? [...bodyAndResponseNames, ...paramNames, ...responseStatusNames]\n : [...paramNames, ...bodyAndResponseNames, ...responseStatusNames]\n\n const result = names.filter((name): name is string => Boolean(name) && !exclude.has(name as string))\n byResolver.set(cacheKey, result)\n return result\n}\n\nexport function resolveResponseTypes(node: ast.OperationNode, resolver: ResponseNameResolver): Array<[statusCode: number | 'default', typeName: string]> {\n const types: Array<[number | 'default', string]> = []\n\n for (const response of node.responses) {\n if (response.statusCode === 'default') {\n types.push(['default', resolver.response.response(node)])\n continue\n }\n\n const code = getStatusCodeNumber(response.statusCode)\n if (code === null) {\n continue\n }\n\n types.push([code, isSuccessStatusCode(code) ? resolver.response.response(node) : resolver.response.status(node, response.statusCode)])\n }\n\n return types\n}\n\nexport function findSuccessStatusCode(responses: Array<{ statusCode: ast.StatusCode | number | string }>): ast.StatusCode | null {\n for (const response of responses) {\n if (isSuccessStatusCode(response.statusCode)) {\n return response.statusCode as ast.StatusCode\n }\n }\n\n return null\n}\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n\n/**\n * Uppercases only the first character of `text`, leaving the rest untouched.\n * Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.\n *\n * @example\n * `capitalize('getPetById') // 'GetPetById'`\n */\nexport function capitalize(text: string): string {\n return `${text.charAt(0).toUpperCase()}${text.slice(1)}`\n}\n\n/**\n * Converts `text` to snake_case.\n *\n * @example From camelCase\n * `snakeCase('helloWorld') // 'hello_world'`\n *\n * @example From mixed separators\n * `snakeCase('Hello-World') // 'hello_world'`\n */\nexport function snakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n const processed = `${prefix} ${text} ${suffix}`.trim()\n return processed\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * Converts `text` to SCREAMING_SNAKE_CASE.\n *\n * @example From camelCase\n * `screamingSnakeCase('helloWorld') // 'HELLO_WORLD'`\n */\nexport function screamingSnakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return snakeCase(text, { prefix, suffix }).toUpperCase()\n}\n","import { camelCase } from '@internals/utils'\nimport type { Group } from 'kubb/kit'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use the camelCased group (`pet store` → `petStore`).\n *\n * A user-provided `group.name` always wins over the default namer, so callers stay in\n * control of their output folders. Returns `null` when grouping is disabled, matching the\n * per-plugin convention.\n *\n * @param group - The user-supplied group option, or `undefined` to disable grouping.\n *\n * @example\n * ```ts\n * createGroupConfig(group) // shared across every plugin\n * ```\n */\nexport function createGroupConfig(group: Group | undefined): Group | null {\n if (!group) {\n return null\n }\n\n const defaultName = (ctx: { group: string }): string => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return camelCase(ctx.group)\n }\n\n return {\n ...group,\n name: group.name ? group.name : defaultName,\n } satisfies Group\n}\n","import { buildOperationComments, buildRequestParamsSignature } from '@internals/shared'\nimport { ast } from 'kubb/kit'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport { File, Function } from 'kubb/jsx'\nimport type { KubbReactNode } from 'kubb/jsx'\n\ntype Props = {\n /**\n * Name of the handler function.\n */\n name: string\n /**\n * Name of the contract client `<op>` the handler calls.\n */\n clientName: string\n /**\n * AST operation node.\n */\n node: ast.OperationNode\n /**\n * TypeScript resolver for resolving param/data/response type names.\n */\n resolver: ResolverTs\n /**\n * The registered client plugin's `returnType`, read by the caller off `resolveClientOperation`.\n */\n returnType?: 'full' | 'data'\n}\n\nconst requestGroupOrder = ['path', 'query', 'headers', 'body'] as const\n\nexport function McpHandler({ name, clientName, node, resolver, returnType = 'full' }: Props): KubbReactNode {\n if (!ast.isHttpOperationNode(node)) return null\n\n const { signature, groups } = buildRequestParamsSignature(node, resolver, { isConfigurable: false })\n const paramsSignature = [signature, 'request: RequestHandlerExtra<ServerRequest, ServerNotification>'].filter(Boolean).join(', ')\n\n // Forward the grouped config and MCP cancellation signal through the contract client. `throwOnError: true`\n // pins the result shape, since `throwOnErrorDefault: false` would otherwise resolve to the full result.\n const callArgs = requestGroupOrder.filter((key) => groups[key])\n const callConfig = `{ ${[...callArgs, 'signal: request.signal', 'throwOnError: true'].join(', ')} }`\n const body = returnType === 'data' ? 'res' : 'res.data'\n\n const callToolResult = `return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(${body})\n }\n ],\n structuredContent: { data: ${body} }\n}`\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function\n name={name}\n async\n export\n params={paramsSignature}\n JSDoc={{\n comments: buildOperationComments(node),\n }}\n returnType={'CallToolResult'}\n >\n {`const res = await ${clientName}(${callConfig})`}\n <br />\n {callToolResult}\n </Function>\n </File.Source>\n )\n}\n","import type { ast } from 'kubb/kit'\n\nexport type ZodParam = {\n name: string\n schemaName: string\n}\n\n/**\n * Render a group param value — compose individual schemas into `z.object({ ... })`,\n * or use a schema name string directly.\n */\nexport function zodGroupExpr(entry: string | Array<ZodParam>): string {\n if (typeof entry === 'string') {\n return entry\n }\n const entries = entry.map((p) => `${JSON.stringify(p.name)}: ${p.schemaName}`)\n return `z.object({ ${entries.join(', ')} })`\n}\n\n/**\n * Convert a SchemaNode type to an inline Zod expression string.\n * Used as fallback when no named zod schema is available for a path parameter.\n */\nexport function zodExprFromSchemaNode(schema: ast.SchemaNode): string {\n const baseExpr = (() => {\n if (schema.type === 'enum') {\n const rawValues: Array<string | number | boolean> = schema.namedEnumValues?.length\n ? schema.namedEnumValues.map((v) => v.value)\n : (schema.enumValues ?? []).filter((v): v is string | number | boolean => v !== null)\n\n if (rawValues.length > 0 && rawValues.every((v) => typeof v === 'string')) {\n return `z.enum([${rawValues.map((v) => JSON.stringify(v)).join(', ')}])`\n }\n if (rawValues.length > 0) {\n const literals = rawValues.map((v) => `z.literal(${JSON.stringify(v)})`)\n return literals.length === 1 ? literals[0]! : `z.union([${literals.join(', ')}])`\n }\n return 'z.string()'\n }\n if (schema.type === 'integer') return 'z.coerce.number()'\n if (schema.type === 'number') return 'z.number()'\n if (schema.type === 'boolean') return 'z.boolean()'\n if (schema.type === 'array') return 'z.array(z.unknown())'\n return 'z.string()'\n })()\n\n return schema.nullable ? `${baseExpr}.nullable()` : baseExpr\n}\n","import { getOperationParameters } from '@internals/shared'\nimport type { ast } from 'kubb/kit'\nimport { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, functionPrinter } from '@kubb/plugin-ts'\nimport { Const, File, Function } from 'kubb/jsx'\nimport type { KubbReactNode } from 'kubb/jsx'\nimport type { ZodParam } from '../utils.ts'\nimport { zodExprFromSchemaNode, zodGroupExpr } from '../utils.ts'\n\ntype Props = {\n /**\n * Variable name for the MCP server instance (e.g. 'server').\n */\n name: string\n /**\n * Human-readable server name passed to `new McpServer({ name })`.\n */\n serverName: string\n /**\n * Semantic version string passed to `new McpServer({ version })`.\n */\n serverVersion: string\n /**\n * Operations to register as MCP tools, each carrying its handler,\n * zod schema, and AST node metadata.\n */\n operations: Array<{\n tool: {\n name: string\n title?: string\n description: string\n }\n mcp: {\n name: string\n file: ast.FileNode\n }\n zod: {\n pathParams: Array<ZodParam>\n /**\n * Query params — individual schemas to compose into `z.object({ ... })`.\n */\n queryParams?: string | Array<ZodParam> | null\n /**\n * Header params — individual schemas to compose into `z.object({ ... })`.\n */\n headerParams?: string | Array<ZodParam> | null\n requestName?: string | null\n responseName?: string | null\n }\n node: ast.OperationNode\n }>\n}\n\nconst keysPrinter = functionPrinter({ mode: 'call' })\n\nexport function Server({ name, serverName, serverVersion, operations }: Props): KubbReactNode {\n const registrations = operations\n .map(({ tool, mcp, zod, node }) => {\n const { path: pathParams } = getOperationParameters(node)\n\n // Group params into the same `{ path, query, headers, body }` shape the contract `<op>`\n // expects, so the MCP tool input mirrors every other client consumer.\n const entries: Array<{ key: string; value: string }> = []\n\n if (pathParams.length) {\n const pathFields = pathParams\n .map((p) => {\n const zodParam = zod.pathParams.find((zp) => zp.name === p.name)\n return `${JSON.stringify(p.name)}: ${zodParam ? zodParam.schemaName : zodExprFromSchemaNode(p.schema)}`\n })\n .join(', ')\n entries.push({ key: 'path', value: `z.object({ ${pathFields} })` })\n }\n\n if (zod.queryParams) {\n entries.push({ key: 'query', value: zodGroupExpr(zod.queryParams) })\n }\n\n if (zod.headerParams) {\n entries.push({ key: 'headers', value: zodGroupExpr(zod.headerParams) })\n }\n\n if (zod.requestName) {\n entries.push({ key: 'body', value: zod.requestName })\n }\n\n const paramsNode = entries.length\n ? createFunctionParameters({\n params: [\n createFunctionParameter({\n name: createObjectBindingPattern({ elements: entries.map((e) => ({ name: e.key })) }),\n optional: false,\n }),\n ],\n })\n : null\n\n const destructured = paramsNode ? (keysPrinter.print(paramsNode) ?? '') : ''\n const inputSchema = entries.length ? `{ ${entries.map((e) => `${e.key}: ${e.value}`).join(', ')} }` : null\n const outputSchema = zod.responseName\n\n const config = [\n tool.title ? `title: ${JSON.stringify(tool.title)}` : null,\n `description: ${JSON.stringify(tool.description)}`,\n outputSchema ? `outputSchema: { data: ${outputSchema} }` : null,\n ]\n .filter(Boolean)\n .join(',\\n ')\n\n if (inputSchema) {\n return `\nserver.registerTool(${JSON.stringify(tool.name)}, {\n ${config},\n inputSchema: ${inputSchema},\n}, async (${destructured}, request) => {\n return ${mcp.name}(${destructured}, request)\n})\n `\n }\n\n return `\nserver.registerTool(${JSON.stringify(tool.name)}, {\n ${config},\n}, async (request) => {\n return ${mcp.name}(request)\n})\n `\n })\n .filter(Boolean)\n .join('\\n')\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function name=\"getServer\" export>\n {`const server = new McpServer({\n name: '${serverName}',\n version: '${serverVersion}',\n})\n${registrations}\nreturn server`}\n </Function>\n\n <Const name={'server'} export>\n {'getServer()'}\n </Const>\n\n <Function name=\"startServer\" async export>\n {`try {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n\n } catch (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }`}\n </Function>\n </File.Source>\n )\n}\n","/**\n * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an\n * operation, shared so the selection rules and diagnostics stay in one place.\n *\n * Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered\n * contract client plugin (plugin-fetch or plugin-axios) and never emits its own inline client:\n *\n * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer\n * imports and calls them.\n * - `error` — no client plugin is registered, several are registered without a selector, the\n * requested one is missing, or `client` is not a known selector.\n *\n * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered\n * contract client plugin is picked up automatically.\n */\n\n// Canonical plugin names. They mirror the `pluginFetchName` / `pluginAxiosName` consts the plugins\n// export, kept as literals so this internal needs no plugin install deps.\nconst pluginFetchName = 'plugin-fetch'\nconst pluginAxiosName = 'plugin-axios'\n\n/**\n * The client selector accepted by a consumer's `client` option. Both call a registered contract\n * client plugin.\n */\nexport type ClientSelector = 'fetch' | 'axios'\n\n/**\n * The resolved client strategy stored in a consumer plugin's options: the generated code always\n * imports and calls a registered contract client plugin's `<op>`. The client runtime lives in\n * plugin-axios / plugin-fetch, so nothing is bundled by the consumer.\n */\nexport type ResolvedContractClient = { kind: 'contract'; pluginName: string }\n\n/**\n * The outcome of {@link resolveClient}.\n *\n * - `contract` names the contract client plugin whose `<op>` functions the consumer imports.\n * - `error` carries a setup diagnostic.\n */\nexport type ResolveClientResult = ResolvedContractClient | { kind: 'error'; message: string }\n\nconst selectorToPlugin: Record<'fetch' | 'axios', string> = {\n fetch: pluginFetchName,\n axios: pluginAxiosName,\n}\n\n// Every contract client plugin, in auto-detect priority order.\nconst contractPlugins = [pluginFetchName, pluginAxiosName] as const\n\n/**\n * Applies the `client` resolution rules. See the module comment for the strategy shape.\n *\n * @example\n * ```ts\n * resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })\n * // { kind: 'contract', pluginName: 'plugin-fetch' }\n * ```\n *\n * @example\n * ```ts\n * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })\n * // { kind: 'error', message: 'No client plugin is registered…' }\n * ```\n */\nexport function resolveClient(options: { client: ClientSelector | undefined; pluginNames: ReadonlyArray<string> }): ResolveClientResult {\n const { client, pluginNames } = options\n const has = (name: string) => pluginNames.includes(name)\n\n if (client === 'fetch' || client === 'axios') {\n const pluginName = selectorToPlugin[client]\n if (!has(pluginName)) {\n return {\n kind: 'error',\n message: `\\`client: '${client}'\\` is set but \\`@kubb/plugin-${client}\\` is not registered in \\`plugins\\`. Add it, or drop \\`client\\` to use a different client plugin.`,\n }\n }\n return { kind: 'contract', pluginName }\n }\n\n // A JS config bypasses the `ClientSelector` type, so reject unknown selectors instead of auto-detecting.\n if (client !== undefined) {\n return {\n kind: 'error',\n message: `Option \\`client\\` is ${typeof client === 'string' ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios'. Drop \\`client\\` to use the registered client plugin.`,\n }\n }\n\n // `client` unset: auto-detect a lone registered contract client plugin.\n const registered = contractPlugins.filter(has)\n if (registered.length === 1) {\n return { kind: 'contract', pluginName: registered[0]! }\n }\n if (registered.length > 1) {\n return {\n kind: 'error',\n message: `Multiple client plugins are registered (${registered.map((name) => `\\`@kubb/${name}\\``).join(', ')}). Set \\`client: 'fetch' | 'axios'\\` to choose which client the hooks call, or register a single client plugin.`,\n }\n }\n\n return {\n kind: 'error',\n message: 'No client plugin is registered. Add `@kubb/plugin-axios` or `@kubb/plugin-fetch` to `plugins` so the generated code has an HTTP client to call.',\n }\n}\n\n/**\n * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names\n * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a\n * misconfiguration so every consumer fails fast with the same message.\n */\nexport function resolveContractClient(options: { client: ClientSelector | undefined; plugins?: ReadonlyArray<unknown> }): ResolvedContractClient {\n const { client, plugins = [] } = options\n const pluginNames = plugins.map((plugin) => (plugin as { name?: string }).name).filter((name): name is string => Boolean(name))\n const resolved = resolveClient({ client, pluginNames })\n if (resolved.kind === 'error') {\n throw new Error(resolved.message)\n }\n return resolved\n}\n","import path from 'node:path'\nimport { operationFileEntry } from '@internals/shared'\nimport type { ast, Exclude, Group, Include, NodeCache, Output, Override, Resolver } from 'kubb/kit'\n\n/**\n * The resolved contract `<op>` for one operation: the generated function name, the file it lives in,\n * the contract runtime's `.kubb/client.ts` path (where `RequestConfig` / `ResponseErrorConfig`\n * come from), and the registered client plugin's `returnType`.\n */\nexport type ClientOperation = { name: string; path: string; clientPath: string; returnType: 'full' | 'data' }\n\n/**\n * The client plugin options a dependent reads, including the filters that scope them per operation.\n */\ntype ClientPluginOptions = {\n output?: Output\n group?: Group | null\n returnType?: 'full' | 'data'\n exclude?: Array<Exclude>\n include?: Array<Include>\n override?: Array<Override<Omit<ClientPluginOptions, 'override'>>>\n}\n\n/**\n * Resolves the contract client `<op>` a consumer (query hook, MCP handler) imports, by looking up\n * the registered contract client plugin's resolver and output. Works for any contract client plugin\n * (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline\n * path), or when the client plugin's `exclude` / `include` leaves this operation out, since it then\n * emits no `<op>` to import. The plugin injects `.kubb/client.ts` at the global output root, the\n * same path consumers read `RequestConfig` / `ResponseErrorConfig` from.\n *\n * The result is cached in the current node's `cache` (`ctx.cache`) under the client plugin's name,\n * so several dependents reading the same client plugin for one operation in a single pass\n * (react-query's query/mutation/infinite generators, vue-query, swr, the MCP handler, ...) share\n * one computed result instead of each re-deriving the name and path.\n *\n * `returnType`, `output`, and `group` are the client plugin's options for this operation, after its\n * `override` entries, the same resolution its own generator sees. A dependent's generated call body\n * and import path therefore match the `<op>` actually emitted, even when an `override` changes it.\n */\nexport function resolveClientOperation(options: {\n clientPlugin: { pluginName: string } | null\n driver: {\n getPlugin: (name: string) => { options?: ClientPluginOptions } | undefined\n getResolver: (name: string) => Resolver\n }\n node: ast.OperationNode\n root: string\n output: Output\n cache: NodeCache\n}): ClientOperation | null {\n const { clientPlugin, driver, node, root, output, cache } = options\n if (!clientPlugin) return null\n\n return cache.ensureItem(`${clientPlugin.pluginName}:clientOperation`, () => {\n const resolver = driver.getResolver(clientPlugin.pluginName)\n const pluginOptions = driver.getPlugin(clientPlugin.pluginName)?.options ?? {}\n const { exclude, include, override } = pluginOptions\n const hasOperationOptions = Boolean(exclude?.length || include?.length || override?.length)\n // Kubb's resolver always has `default`; the fallback keeps partial or custom resolvers working.\n const operationOptions =\n hasOperationOptions && resolver.default ? resolver.default.options(node, { options: pluginOptions, exclude, include, override }) : pluginOptions\n if (!operationOptions) return null\n\n const file = resolver.file({\n ...operationFileEntry(node, node.operationId),\n root,\n output: operationOptions.output ?? output,\n group: operationOptions.group ?? undefined,\n })\n\n return {\n name: resolver.name(node.operationId),\n path: file.path,\n clientPath: path.resolve(root, '.kubb/client.ts'),\n returnType: operationOptions.returnType ?? 'full',\n }\n })\n}\n","import { resolveClientOperation } from '@internals/client'\nimport { resolveDependencyOperationFile } from '@internals/shared'\nimport { ast, defineGenerator } from 'kubb/kit'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { File, jsxRenderer } from 'kubb/jsx'\nimport { McpHandler } from '../components/McpHandler.tsx'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Built-in operation generator for `@kubb/plugin-mcp`. Emits one MCP tool\n * handler per OpenAPI operation. The handler takes the grouped `{ path, query,\n * headers, body }` config and forwards it to the registered client plugin's\n * (`@kubb/plugin-axios` / `@kubb/plugin-fetch`) `<op>` function.\n */\nexport const mcpGenerator = defineGenerator<PluginMcp>({\n name: 'mcp',\n renderer: jsxRenderer,\n operation(node, ctx) {\n if (!ast.isHttpOperationNode(node)) return null\n const { resolver, driver, root, config } = ctx\n const { output, client, group } = ctx.options\n\n const pluginTs = ctx.requirePlugin(pluginTsName)\n\n const tsResolver = driver.getResolver(pluginTsName)\n\n // The registered contract client plugin owns the `<op>` the handler imports and calls.\n const contractOp = resolveClientOperation({ clientPlugin: { pluginName: client.pluginName }, driver, node, root, output, cache: ctx.cache })\n if (!contractOp) {\n return null\n }\n\n // The handler signature references the grouped `<Name>Options`.\n const optionsName = tsResolver.response.options(node)\n\n const meta = {\n name: resolver.handler.name(node),\n file: resolver.file({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path, root, output, group: group ?? undefined }),\n fileTs: resolveDependencyOperationFile({\n cache: ctx.cache,\n node,\n resolver: tsResolver,\n root,\n output: pluginTs.options?.output ?? output,\n group: pluginTs.options?.group,\n }),\n } as const\n\n return (\n <File\n baseName={meta.file.baseName}\n path={meta.file.path}\n meta={meta.file.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n >\n {meta.fileTs && optionsName && <File.Import name={[optionsName]} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />}\n <File.Import name={['CallToolResult', 'ServerNotification', 'ServerRequest']} path={'@modelcontextprotocol/sdk/types.js'} isTypeOnly />\n <File.Import name={['RequestHandlerExtra']} path={'@modelcontextprotocol/sdk/shared/protocol.js'} isTypeOnly />\n\n <File.Import name={[contractOp.name]} root={meta.file.path} path={contractOp.path} />\n\n <McpHandler name={meta.name} clientName={contractOp.name} node={node} resolver={tsResolver} returnType={contractOp.returnType} />\n </File>\n )\n },\n})\n","import path from 'node:path'\nimport { findSuccessStatusCode, getOperationParameters } from '@internals/shared'\nimport { ast, defineGenerator } from 'kubb/kit'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { File, jsxRenderer } from 'kubb/jsx'\nimport { Server } from '../components/Server.tsx'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Default v5 server generator for `@kubb/plugin-mcp`.\n *\n * Uses individual zod schemas for each param (e.g. `createPetsPathUuidSchema`, `createPetsQueryOffsetSchema`)\n * and `resolveResponseStatusName` for per-status response schemas.\n * Query and header params are composed into `z.object({ ... })` from individual schemas.\n */\nexport const serverGenerator = defineGenerator<PluginMcp>({\n name: 'operations',\n renderer: jsxRenderer,\n operations(nodes, ctx) {\n const { config, resolver, plugin, driver, root } = ctx\n const { output, group } = ctx.options\n\n const pluginZod = ctx.requirePlugin(pluginZodName)\n\n const zodResolver = driver.getResolver(pluginZodName)\n\n const name = 'server'\n const serverFilePath = path.resolve(root, output.path, 'server.ts')\n const serverFile = {\n baseName: 'server.ts' as const,\n path: serverFilePath,\n meta: { pluginName: plugin.name },\n }\n\n const jsonFilePath = path.resolve(root, output.path, '.mcp.json')\n const jsonFile = {\n baseName: '.mcp.json' as const,\n path: jsonFilePath,\n meta: { pluginName: plugin.name },\n }\n\n const operationsMapped = nodes.filter(ast.isHttpOperationNode).map((node) => {\n const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node)\n\n const mcpFile = resolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output,\n group: group ?? undefined,\n })\n\n const zodFile = zodResolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output: pluginZod.options?.output ?? output,\n group: pluginZod.options?.group ?? undefined,\n })\n\n const requestName = node.requestBody?.content?.[0]?.schema ? zodResolver.response.body(node) : null\n const successStatus = findSuccessStatusCode(node.responses)\n const responseName = successStatus ? zodResolver.response.status(node, successStatus) : null\n\n const resolveParams = (params: typeof pathParams) => params.map((p) => ({ name: p.name, schemaName: zodResolver.param.name(node, p) }))\n\n return {\n tool: {\n name: node.operationId,\n title: node.summary || undefined,\n description: node.description || `Make a ${node.method.toUpperCase()} request to ${node.path}`,\n },\n mcp: {\n name: resolver.handler.name(node),\n file: mcpFile,\n },\n zod: {\n pathParams: resolveParams(pathParams),\n queryParams: queryParams.length ? resolveParams(queryParams) : null,\n headerParams: headerParams.length ? resolveParams(headerParams) : null,\n requestName,\n responseName,\n file: zodFile,\n },\n node: node,\n }\n })\n\n const imports = operationsMapped.flatMap(({ mcp, zod }) => {\n const zodNames = [\n ...zod.pathParams.map((p) => p.schemaName),\n ...(zod.queryParams ?? []).map((p) => p.schemaName),\n ...(zod.headerParams ?? []).map((p) => p.schemaName),\n zod.requestName,\n zod.responseName,\n ].filter((name): name is string => Boolean(name))\n\n const uniqueNames = [...new Set(zodNames)].sort()\n\n return [\n <File.Import key={mcp.name} name={[mcp.name]} root={serverFile.path} path={mcp.file.path} />,\n uniqueNames.length > 0 && <File.Import key={`zod-${mcp.name}`} name={uniqueNames} root={serverFile.path} path={zod.file.path} />,\n ].filter(Boolean)\n })\n\n return (\n <>\n <File\n baseName={serverFile.baseName}\n path={serverFile.path}\n meta={serverFile.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: serverFile.path, baseName: serverFile.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: serverFile.path, baseName: serverFile.baseName } })}\n >\n <File.Import name={['McpServer']} path={'@modelcontextprotocol/sdk/server/mcp.js'} />\n <File.Import name={['z']} path={'zod'} />\n <File.Import name={['StdioServerTransport']} path={'@modelcontextprotocol/sdk/server/stdio.js'} />\n\n {imports}\n <Server name={name} serverName={ctx.meta.title ?? 'server'} serverVersion={ctx.meta.version ?? '0.0.0'} operations={operationsMapped} />\n </File>\n\n <File baseName={jsonFile.baseName} path={jsonFile.path} meta={jsonFile.meta}>\n <File.Source name={name}>\n {`\n {\n \"mcpServers\": {\n \"${ctx.meta.title || 'server'}\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"${path.relative(path.dirname(jsonFile.path), serverFile.path)}\"]\n }\n }\n }\n `}\n </File.Source>\n </File>\n </>\n )\n },\n})\n","import { camelCase } from '@internals/utils'\nimport { createResolver } from 'kubb/kit'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-mcp`. Decides the names and file\n * paths for every generated MCP tool handler. Function names get a `Handler`\n * suffix so an operation `addPet` becomes `addPetHandler`.\n *\n * @example Resolve a handler name\n * ```ts\n * import { resolverMcp } from '@kubb/plugin-mcp'\n *\n * resolverMcp.name('addPet') // 'addPetHandler'\n * ```\n */\nexport const resolverMcp = createResolver<PluginMcp>({\n pluginName: 'plugin-mcp',\n name(name) {\n return camelCase(name, { suffix: 'handler' })\n },\n handler: {\n name(node) {\n return this.name(node.operationId)\n },\n },\n})\n","import { createGroupConfig } from '@internals/shared'\n\nimport { resolveContractClient } from '@internals/client'\nimport { definePlugin, Resolver } from 'kubb/kit'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { mcpGenerator } from './generators/mcpGenerator.tsx'\nimport { serverGenerator } from './generators/serverGenerator.tsx'\nimport { resolverMcp } from './resolvers/resolverMcp.ts'\nimport type { PluginMcp, ResolverMcp } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-mcp`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginMcpName = 'plugin-mcp' satisfies PluginMcp['name']\n\n/**\n * Generates a Model Context Protocol (MCP) server from an OpenAPI spec. Every\n * operation becomes a typed MCP tool that AI assistants (Claude Desktop, Claude\n * Code, MCP-compatible clients) can call directly. Each handler calls a contract\n * client `<op>` from a registered `@kubb/plugin-axios` or `@kubb/plugin-fetch`.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb/config'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginZod } from '@kubb/plugin-zod'\n * import { pluginMcp } from '@kubb/plugin-mcp'\n *\n * export default defineConfig({\n * input: './petStore.yaml',\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginZod(),\n * pluginMcp({\n * output: { path: './mcp' },\n * baseURL: 'https://petstore.swagger.io/v2',\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginMcp = definePlugin<PluginMcp>((options) => {\n const {\n output = { path: 'mcp', barrel: { type: 'named' } },\n group,\n exclude = [],\n include,\n override = [],\n client,\n resolver: userResolver,\n macros: userMacros,\n } = options\n\n const groupConfig = createGroupConfig(group)\n\n return {\n name: pluginMcpName,\n options,\n dependencies: [pluginTsName, pluginZodName],\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n ctx.requirePlugin(pluginTsName)\n ctx.requirePlugin(pluginZodName)\n\n const resolver = userResolver ? Resolver.merge<ResolverMcp>(resolverMcp, userResolver) : resolverMcp\n\n ctx.setOptions({\n output,\n exclude,\n include,\n override,\n group: groupConfig,\n client: resolveContractClient({ client, plugins: ctx.config.plugins }),\n resolver,\n })\n ctx.setResolver(resolver)\n if (userMacros?.length) {\n ctx.setMacros(userMacros)\n }\n ctx.addGenerator(mcpGenerator, serverGenerator)\n },\n },\n }\n})\n\nexport default pluginMcp\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -90,8 +90,8 @@ export declare function Server({ name, serverName, serverVersion, operations }:
90
90
  *
91
91
  * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
92
92
  * imports and calls them.
93
- * - `error` — no client plugin is registered, several are registered without a selector, or the
94
- * requested one is missing.
93
+ * - `error` — no client plugin is registered, several are registered without a selector, the
94
+ * requested one is missing, or `client` is not a known selector.
95
95
  *
96
96
  * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered
97
97
  * contract client plugin is picked up automatically.
package/dist/index.js CHANGED
@@ -448,8 +448,8 @@ return server`
448
448
  *
449
449
  * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
450
450
  * imports and calls them.
451
- * - `error` — no client plugin is registered, several are registered without a selector, or the
452
- * requested one is missing.
451
+ * - `error` — no client plugin is registered, several are registered without a selector, the
452
+ * requested one is missing, or `client` is not a known selector.
453
453
  *
454
454
  * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered
455
455
  * contract client plugin is picked up automatically.
@@ -490,6 +490,10 @@ function resolveClient(options) {
490
490
  pluginName
491
491
  };
492
492
  }
493
+ if (client !== void 0) return {
494
+ kind: "error",
495
+ message: `Option \`client\` is ${typeof client === "string" ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios'. Drop \`client\` to use the registered client plugin.`
496
+ };
493
497
  const registered = contractPlugins.filter(has);
494
498
  if (registered.length === 1) return {
495
499
  kind: "contract",
@@ -580,8 +584,7 @@ const mcpGenerator = defineGenerator({
580
584
  if (!ast.isHttpOperationNode(node)) return null;
581
585
  const { resolver, driver, root, config } = ctx;
582
586
  const { output, client, group } = ctx.options;
583
- const pluginTs = driver.getPlugin(pluginTsName);
584
- if (!pluginTs) return null;
587
+ const pluginTs = ctx.requirePlugin(pluginTsName);
585
588
  const tsResolver = driver.getResolver(pluginTsName);
586
589
  const contractOp = resolveClientOperation({
587
590
  clientPlugin: { pluginName: client.pluginName },
@@ -685,8 +688,7 @@ const serverGenerator = defineGenerator({
685
688
  operations(nodes, ctx) {
686
689
  const { config, resolver, plugin, driver, root } = ctx;
687
690
  const { output, group } = ctx.options;
688
- const pluginZod = driver.getPlugin(pluginZodName);
689
- if (!pluginZod) return;
691
+ const pluginZod = ctx.requirePlugin(pluginZodName);
690
692
  const zodResolver = driver.getResolver(pluginZodName);
691
693
  const name = "server";
692
694
  const serverFile = {
@@ -896,6 +898,8 @@ const pluginMcp = definePlugin((options) => {
896
898
  options,
897
899
  dependencies: [pluginTsName, pluginZodName],
898
900
  hooks: { "kubb:plugin:setup"(ctx) {
901
+ ctx.requirePlugin(pluginTsName);
902
+ ctx.requirePlugin(pluginZodName);
899
903
  const resolver = userResolver ? Resolver.merge(resolverMcp, userResolver) : resolverMcp;
900
904
  ctx.setOptions({
901
905
  output,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../internals/shared/src/params.ts","../../../internals/shared/src/operation.ts","../../../internals/utils/src/casing.ts","../../../internals/shared/src/group.ts","../src/components/McpHandler.tsx","../src/utils.ts","../src/components/Server.tsx","../../../internals/client/src/resolveClient.ts","../../../internals/client/src/resolveClientOperation.ts","../src/generators/mcpGenerator.tsx","../src/generators/serverGenerator.tsx","../src/resolvers/resolverMcp.ts","../src/plugin.ts"],"sourcesContent":["import type { ast } from 'kubb/kit'\n\n/**\n * Drops parameters that share the same name, keeping the first.\n *\n * A malformed spec can declare the same parameter name twice within one `in` location. Both would\n * resolve to the same output property, so emitting both would yield an object type with a duplicate\n * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:\n * parameter names flow through unchanged, so no two distinct names ever collide here anymore.\n */\nexport function dedupeParams(params: Array<ast.ParameterNode>): Array<ast.ParameterNode> {\n const seen = new Set<string>()\n\n return params.filter((param) => {\n if (seen.has(param.name)) return false\n seen.add(param.name)\n return true\n })\n}\n","import { ast, type Group, type NodeCache, type Output, type Resolver, type ResolverFileParams, Url } from 'kubb/kit'\nimport { dedupeParams } from './params.ts'\n\n/**\n * Builds the `ResolverFileParams` every operation generator passes to\n * `resolver.file`: a file named `name`, tagged by the operation's first\n * tag (or `'default'`), at the operation's path. Centralizes the entry object\n * that was repeated at dozens of call sites across the client and query plugins.\n *\n * @example\n * ```ts\n * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })\n * ```\n */\nexport function operationFileEntry(node: ast.OperationNode, name: string, extname: ResolverFileParams['extname'] = '.ts'): ResolverFileParams {\n return {\n name,\n extname,\n tag: node.tags[0] ?? 'default',\n path: node.path,\n }\n}\n\n/**\n * Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the\n * current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the\n * same dependency for the same operation in one pass (a query plugin's several hook generators, the\n * MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.\n *\n * @example Cache `plugin-ts`'s file for the current operation\n * ```ts\n * const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })\n * ```\n */\nexport function resolveDependencyOperationFile(options: {\n cache: NodeCache\n node: ast.OperationNode\n resolver: Pick<Resolver, 'file' | 'pluginName'>\n root: string\n output: Output\n group?: Group | null\n}): ast.FileNode {\n const { cache, node, resolver, root, output, group } = options\n\n return cache.ensureItem(`${resolver.pluginName}:operationFile`, () =>\n resolver.file({ ...operationFileEntry(node, node.operationId), root, output, group: group ?? undefined }),\n )\n}\n\nexport type ContentTypeInfo = {\n contentTypes: string[]\n isMultipleContentTypes: boolean\n contentTypeUnion: string\n defaultContentType: string\n hasFormData: boolean\n}\n\nexport type RequestConfigResolver = {\n response: {\n body(node: ast.OperationNode): string\n }\n}\n\nexport type ResponseStatusNameResolver = {\n response: {\n status(node: ast.OperationNode, statusCode: ast.StatusCode): string\n }\n}\n\nexport type ResponseNameResolver = ResponseStatusNameResolver & {\n response: {\n response(node: ast.OperationNode): string\n }\n}\n\nexport type OperationTypeNameResolver = RequestConfigResolver &\n ResponseNameResolver & {\n param: {\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n }\n\n/**\n * Resolver interface for building operation parameters.\n *\n * `ResolverTs` from `@kubb/plugin-ts` satisfies this interface and can be passed directly.\n */\nexport type OperationParamsResolver = {\n /**\n * Naming for an operation's parameters, grouped by location.\n */\n param: {\n /**\n * Resolves the type name for an individual parameter.\n *\n * @example Individual path parameter name\n * `resolver.param.name(node, param) // → 'DeletePetPathPetId'`\n */\n name(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped path parameters type name.\n * When the return value equals `resolver.param.name`, no indexed access is emitted.\n *\n * @example Grouped path params type name\n * `resolver.param.path(node, param) // → 'DeletePetPath'`\n */\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped query parameters type name.\n * When the return value equals `resolver.param.name`, an inline struct type is emitted instead.\n *\n * @example Grouped query params type name\n * `resolver.param.query(node, param) // → 'FindPetsByStatusQuery'`\n */\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped header parameters type name.\n * When the return value equals `resolver.param.name`, an inline struct type is emitted instead.\n *\n * @example Grouped header params type name\n * `resolver.param.headers(node, param) // → 'DeletePetHeaders'`\n */\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n /**\n * Naming for an operation's request and response types.\n */\n response: {\n /**\n * Resolves the request body type name.\n *\n * @example Request body type name\n * `resolver.response.body(node) // → 'CreatePetBody'`\n */\n body(node: ast.OperationNode): string\n }\n}\n\nexport type OperationCommentLink = 'pathTemplate' | 'urlPath' | false | ((node: ast.OperationNode) => string | undefined)\n\nexport type BuildOperationCommentsOptions = {\n link?: OperationCommentLink\n linkPosition?: 'beforeDeprecated' | 'afterDeprecated'\n splitLines?: boolean\n}\n\ntype ResponseLike = {\n statusCode: ast.StatusCode | number | string\n}\n\nexport type OperationParameterGroups = Record<ast.ParameterNode['in'], Array<ast.ParameterNode>>\n\nexport type ResolveOperationTypeNameOptions = {\n responseStatusNames?: boolean | 'error'\n exclude?: ReadonlyArray<string | undefined>\n order?: 'params-first' | 'body-response-first'\n /**\n * Include the individual `Path`/`Query`/`Headers` group type names. Set to `false` for clients\n * that reference the grouped `Options` type instead of the per-group types.\n */\n includeParams?: boolean\n}\n\nfunction getOperationLink(node: ast.OperationNode, link: OperationCommentLink): string | null {\n if (!link) {\n return null\n }\n\n if (typeof link === 'function') {\n return link(node) ?? null\n }\n\n return node.path ? `{@link ${Url.toPath(node.path)}}` : null\n}\n\n/**\n * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several\n * are present and the union, default, and form-data flags the client uses to pick one.\n */\nfunction buildContentTypeInfo(contentTypes: string[]): ContentTypeInfo {\n const isMultipleContentTypes = contentTypes.length > 1\n\n return {\n contentTypes,\n isMultipleContentTypes,\n contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(' | ') : '',\n defaultContentType: contentTypes[0] ?? 'application/json',\n hasFormData: contentTypes.some((ct) => ct === 'multipart/form-data'),\n }\n}\n\nexport function getContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? [])\n}\n\n/**\n * The request-body counterpart for the primary success response: the content types it documents and\n * whether several are present, so the client can let a caller pick which one to accept.\n */\nexport function getResponseContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [])\n}\n\nexport type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n\n/**\n * Reads the single base content type of an operation's primary success response, lowercased and\n * stripped of any `; charset=...` suffix. Returns `undefined` when the response declares zero or\n * more than one content type, since neither case has a single type to act on.\n */\nfunction getPrimarySuccessContentType(node: ast.OperationNode): string | undefined {\n const contentTypes = getPrimarySuccessResponse(node)?.content?.map((entry) => entry.contentType) ?? []\n if (contentTypes.length !== 1) return undefined\n return contentTypes[0]!.split(';')[0]!.trim().toLowerCase()\n}\n\n/**\n * Whether an operation streams its primary success response as Server-Sent Events\n * (`text/event-stream`). The client generator uses this to return a typed event stream instead of a\n * one-shot `RequestResult`.\n */\nexport function isEventStream(node: ast.OperationNode): boolean {\n return getPrimarySuccessContentType(node) === 'text/event-stream'\n}\n\n/**\n * Derives the default `responseType` for an operation from its primary success response.\n *\n * Returns a value only when that response declares a single non-JSON content type. `text/event-stream`\n * and other binary types (`application/octet-stream`, `application/pdf`, `image/*`, `audio/*`,\n * `video/*`) map to a stream or `'blob'`, and other `text/*` maps to `'text'`. Otherwise `undefined`,\n * leaving the runtime client's `Content-Type` auto-detection in charge.\n */\nexport function getResponseType(node: ast.OperationNode): ResponseType | undefined {\n const baseType = getPrimarySuccessContentType(node)\n if (!baseType) return undefined\n\n if (baseType === 'application/json' || baseType.endsWith('+json') || baseType === 'text/json') return undefined\n if (baseType === 'text/event-stream') return 'stream'\n if (baseType.startsWith('text/')) return 'text'\n if (baseType === 'application/octet-stream' || baseType === 'application/pdf' || /^(image|audio|video)\\//.test(baseType)) return 'blob'\n return undefined\n}\n\n/**\n * Maps a content type to the PascalCase suffix used to name per-content-type variants\n * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).\n */\nfunction getContentTypeSuffix(contentType: string): string {\n const baseType = contentType.split(';')[0]!.trim()\n if (baseType === 'application/json') return 'Json'\n if (baseType === 'multipart/form-data') return 'FormData'\n if (baseType === 'application/x-www-form-urlencoded') return 'FormUrlEncoded'\n const subtype = baseType.split('/').pop() ?? baseType\n const parts = subtype.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n if (parts.length === 0) return 'Unknown'\n return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join('')\n}\n\n/**\n * Appends a content-type suffix to a base name, keeping a trailing `Data` segment last\n * (e.g. `AddPetData` + `Json` → `AddPetJsonData`, `AddPetStatus200` + `Xml` → `AddPetStatus200Xml`).\n */\nexport function getPerContentTypeName(baseName: string, suffix: string): string {\n if (baseName.endsWith('Data')) {\n return suffix.endsWith('Data') ? baseName.slice(0, -4) + suffix : `${baseName.slice(0, -4)}${suffix}Data`\n }\n return baseName + suffix\n}\n\nexport type ContentVariantInput = { contentType: string; schema?: ast.SchemaNode | null; keysToOmit?: Array<string> | null }\nexport type ContentVariant = { name: string; suffix: string; schema: ast.SchemaNode; keysToOmit?: Array<string> | null; contentType: string }\n\n/**\n * Resolves per-content-type variant names for a set of content entries, deduplicating suffix\n * collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is\n * the final (possibly counter-augmented) value, so callers can derive parallel names in another\n * namespace (e.g. plugin-faker deriving the matching plugin-ts type name).\n */\nexport function resolveContentTypeVariants(entries: Array<ContentVariantInput>, baseName: string): Array<ContentVariant> {\n const usedNames = new Set<string>()\n return entries\n .filter((entry) => entry.schema)\n .map((entry) => {\n const baseSuffix = getContentTypeSuffix(entry.contentType)\n let suffix = baseSuffix\n let name = getPerContentTypeName(baseName, suffix)\n let counter = 2\n while (usedNames.has(name)) {\n suffix = `${baseSuffix}${counter++}`\n name = getPerContentTypeName(baseName, suffix)\n }\n usedNames.add(name)\n return { name, suffix, schema: entry.schema!, keysToOmit: entry.keysToOmit, contentType: entry.contentType }\n })\n}\n\nexport function buildRequestConfigType(node: ast.OperationNode): string {\n const request = getContentTypeInfo(node)\n const response = getResponseContentTypeInfo(node)\n // The request groups come from the grouped params, so `config` drops the data-shape keys to stay\n // assignable to `Options`, which omits them from `RequestConfig`.\n const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n\n // Only the ambiguous side is offered: a single-type side has nothing to pick, so it stays baked in\n // the generated call.\n const members = [\n request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null,\n response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null,\n ].filter(Boolean)\n\n return members.length ? `${configType} & { contentType?: { ${members.join('; ')} } }` : configType\n}\n\n/**\n * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,\n * `useInfiniteQuery`, `useSWR`, ...). Unlike {@link buildRequestConfigType}, it never adds a\n * `contentType?:` member: query hooks wrap GET operations, which carry no request body to select a\n * content type for.\n */\nexport function buildClientOptionType(): string {\n return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n}\n\nexport type RequestGroups = {\n path: boolean\n query: boolean\n body: boolean\n headers: boolean\n}\n\n/**\n * Which of the grouped request options an operation carries.\n */\nexport function getRequestGroups(node: ast.OperationNode): RequestGroups {\n const { path, query, header } = getOperationParameters(node)\n return {\n path: path.length > 0,\n query: query.length > 0,\n body: Boolean(node.requestBody?.content?.[0]?.schema),\n headers: header.length > 0,\n }\n}\n\nexport type RequestGroupOptionality = {\n groups: RequestGroups\n hasRequiredPath: boolean\n hasRequiredQuery: boolean\n hasRequiredHeader: boolean\n /**\n * Whether the grouped request parameter can default to `{}`. True only when no group carries a\n * required member, so every member is safe to omit.\n */\n isOptional: boolean\n}\n\n/**\n * Resolves which grouped request options an operation carries together with whether each group\n * holds a required member. The grouped parameter stays optional only when nothing inside it is\n * required, matching the generated `RequestConfig` type.\n */\nexport function getRequestGroupOptionality(node: ast.OperationNode): RequestGroupOptionality {\n const groups = getRequestGroups(node)\n const { path, query, header } = getOperationParameters(node)\n const hasRequiredPath = path.some((param) => param.required)\n const hasRequiredQuery = query.some((param) => param.required)\n const hasRequiredHeader = header.some((param) => param.required)\n\n return {\n groups,\n hasRequiredPath,\n hasRequiredQuery,\n hasRequiredHeader,\n isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body,\n }\n}\n\nexport type RequestOptionsNameResolver = RequestConfigResolver & {\n response: {\n options(node: ast.OperationNode): string\n }\n}\n\n/**\n * Builds the grouped `{ path, query, body, headers }` parameter for a generated client\n * function, typed from the operation's `Options` (minus `url`). Only the groups the\n * operation actually has are destructured. The trailing `config` parameter carries the\n * runtime `RequestConfig` overrides plus `client`.\n */\nexport function buildRequestParamsSignature(\n node: ast.OperationNode,\n resolver: RequestOptionsNameResolver,\n options: { isConfigurable?: boolean } = {},\n): { signature: string; groups: RequestGroups } {\n const { isConfigurable = true } = options\n const { groups, isOptional } = getRequestGroupOptionality(node)\n\n const names = (['path', 'query', 'body', 'headers'] as const).filter((key) => groups[key])\n\n const firstParam = names.length > 0 ? `{ ${names.join(', ')} }: ${resolver.response.options(node)}${isOptional ? ' = {}' : ''}` : null\n const configParam = isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null\n\n return {\n signature: [firstParam, configParam].filter(Boolean).join(', '),\n groups,\n }\n}\n\nexport function buildOperationComments(node: ast.OperationNode, options: BuildOperationCommentsOptions = {}): Array<string> {\n const { link = 'pathTemplate', linkPosition = 'afterDeprecated', splitLines = false } = options\n const linkComment = getOperationLink(node, link)\n const comments =\n linkPosition === 'beforeDeprecated'\n ? [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, linkComment, node.deprecated && '@deprecated']\n : [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, node.deprecated && '@deprecated', linkComment]\n\n const filteredComments = comments.filter((comment): comment is string => Boolean(comment))\n\n if (!splitLines) {\n return filteredComments\n }\n\n return filteredComments.flatMap((text) => text.split(/\\r?\\n/).map((line) => line.trim())).filter((comment): comment is string => Boolean(comment))\n}\n\nconst operationParameterGroupsByNode = new WeakMap<ast.OperationNode, OperationParameterGroups>()\n\n/**\n * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each\n * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance\n * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the\n * same parameters once per plugin.\n */\nexport function getOperationParameters(node: ast.OperationNode): OperationParameterGroups {\n const cached = operationParameterGroupsByNode.get(node)\n if (cached) return cached\n\n const groups: OperationParameterGroups = {\n path: dedupeParams(node.parameters.filter((param) => param.in === 'path')),\n query: dedupeParams(node.parameters.filter((param) => param.in === 'query')),\n header: dedupeParams(node.parameters.filter((param) => param.in === 'header')),\n cookie: dedupeParams(node.parameters.filter((param) => param.in === 'cookie')),\n }\n\n operationParameterGroupsByNode.set(node, groups)\n return groups\n}\n\n/**\n * Builds the combined `{ body, path, query, headers }` options object schema for an operation,\n * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s\n * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same\n * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod\n * printer to emit `z.object(…)` rather than a record.\n */\nexport function buildOptionsSchema(node: ast.OperationNode, resolver: OperationTypeNameResolver): ast.SchemaNode {\n const { path, query, header } = getOperationParameters(node)\n const hasBody = Boolean(node.requestBody?.content?.[0]?.schema)\n const createNever = () => ast.factory.createSchema({ type: 'never', primitive: undefined, optional: true })\n const groups = [\n { name: 'path', params: path, resolve: resolver.param.path },\n { name: 'query', params: query, resolve: resolver.param.query },\n { name: 'headers', params: header, resolve: resolver.param.headers },\n ] as const\n\n // NOTE(v5-stable): the fields were renamed from the legacy beta shape\n // (`data`/`pathParams`/`queryParams`/`headerParams`) to `body`/`path`/`query`/`headers` so the\n // type matches the runtime client. Drop this note once v5 leaves beta.\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n deprecated: node.deprecated,\n properties: [\n ast.factory.createProperty({\n name: 'body',\n required: hasBody,\n schema: hasBody ? ast.factory.createSchema({ type: 'ref', name: resolver.response.body(node) }) : createNever(),\n }),\n ...groups.map(({ name, params, resolve }) => {\n const required = params.some((param) => param.required)\n\n return ast.factory.createProperty({\n name,\n required,\n schema:\n params.length > 0\n ? ast.factory.createSchema({ type: 'ref', name: resolve.call(resolver.param, node, params[0]!), optional: !required })\n : createNever(),\n })\n }),\n ],\n })\n}\n\n/**\n * The schema a status occupies in the `<Name>Responses` record. A status that documents several\n * content types becomes a `{ contentType; data }` union so the runtime can surface the negotiated type\n * on `result.parsed`, while the standalone `<Name>StatusNNN` alias stays the plain body union that the\n * query hooks and `result.data` use.\n */\nfunction buildResponseRecordEntry(node: ast.OperationNode, res: ast.ResponseNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n const statusName = resolver.response.status(node, res.statusCode)\n const variants = (res.content ?? []).filter((entry) => entry.schema)\n if (variants.length <= 1) {\n return ast.factory.createSchema({ type: 'ref', name: statusName })\n }\n\n return ast.factory.createSchema({\n type: 'union',\n members: resolveContentTypeVariants(variants, statusName).map((variant) =>\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: [\n ast.factory.createProperty({\n name: 'contentType',\n required: true,\n schema: ast.factory.createSchema({ type: 'enum', enumValues: [variant.contentType] }),\n }),\n ast.factory.createProperty({\n name: 'data',\n required: true,\n schema: ast.factory.createSchema({ type: 'ref', name: variant.name }),\n }),\n ],\n }),\n ),\n })\n}\n\n/**\n * Builds the per-status `<Name>Responses` record for an operation, referencing the already-resolved\n * `<Name>StatusNNN` names. Shared by `@kubb/plugin-ts`'s `Responses` type and `@kubb/plugin-zod`'s\n * inferred responses schema, so both emit the same shape from the same inputs.\n *\n * Always emits the keyed record, even when an operation declares no responses. An operation with no\n * responses renders as an empty object, which keeps every consumer's import (for example the axios\n * SDK's `RequestResult<XResponses>`) resolvable instead of pointing at a missing export.\n */\nexport function buildResponses(node: ast.OperationNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: node.responses.map((res) =>\n ast.factory.createProperty({\n name: String(res.statusCode),\n required: true,\n schema: buildResponseRecordEntry(node, res, resolver),\n }),\n ),\n })\n}\n\nexport function getStatusCodeNumber(statusCode: ast.StatusCode | number | string): number | null {\n const code = Number(statusCode)\n\n return Number.isNaN(code) ? null : code\n}\n\nexport function isSuccessStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 200 && code < 300\n}\n\nexport function isErrorStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 400\n}\n\nexport function getSuccessResponses<TResponse extends ResponseLike>(responses: ReadonlyArray<TResponse>): Array<TResponse> {\n return responses.filter((response) => isSuccessStatusCode(response.statusCode))\n}\n\nexport function getOperationSuccessResponses(node: ast.OperationNode): Array<ast.ResponseNode> {\n return getSuccessResponses(node.responses)\n}\n\nexport function getPrimarySuccessResponse(node: ast.OperationNode): ast.ResponseNode | null {\n return getOperationSuccessResponses(node)[0] ?? null\n}\n\nexport function resolveErrorNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveSuccessNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveStatusCodeNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.map((response) => resolver.response.status(node, response.statusCode))\n}\n\nconst typeNamesByResolver = new WeakMap<OperationTypeNameResolver, Map<string, string[]>>()\n\nexport function resolveOperationTypeNames(\n node: ast.OperationNode,\n resolver: OperationTypeNameResolver,\n options: ResolveOperationTypeNameOptions = {},\n): string[] {\n const cacheKey = `${node.operationId}\\0${options.order ?? ''}\\0${options.responseStatusNames ?? ''}\\0${options.includeParams === false ? 'noparams' : ''}\\0${(options.exclude ?? []).join(',')}`\n let byResolver = typeNamesByResolver.get(resolver)\n if (byResolver) {\n const cached = byResolver.get(cacheKey)\n if (cached) return cached\n } else {\n byResolver = new Map()\n typeNamesByResolver.set(resolver, byResolver)\n }\n\n const { path, query, header } = getOperationParameters(node)\n const responseStatusNames =\n options.responseStatusNames === 'error'\n ? resolveErrorNames(node, resolver)\n : options.responseStatusNames === false\n ? []\n : resolveStatusCodeNames(node, resolver)\n const exclude = new Set(options.exclude ?? [])\n const paramNames =\n options.includeParams === false\n ? []\n : [\n ...path.map((param) => resolver.param.path(node, param)),\n ...query.map((param) => resolver.param.query(node, param)),\n ...header.map((param) => resolver.param.headers(node, param)),\n ]\n const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)]\n const names =\n options.order === 'body-response-first'\n ? [...bodyAndResponseNames, ...paramNames, ...responseStatusNames]\n : [...paramNames, ...bodyAndResponseNames, ...responseStatusNames]\n\n const result = names.filter((name): name is string => Boolean(name) && !exclude.has(name as string))\n byResolver.set(cacheKey, result)\n return result\n}\n\nexport function resolveResponseTypes(node: ast.OperationNode, resolver: ResponseNameResolver): Array<[statusCode: number | 'default', typeName: string]> {\n const types: Array<[number | 'default', string]> = []\n\n for (const response of node.responses) {\n if (response.statusCode === 'default') {\n types.push(['default', resolver.response.response(node)])\n continue\n }\n\n const code = getStatusCodeNumber(response.statusCode)\n if (code === null) {\n continue\n }\n\n types.push([code, isSuccessStatusCode(code) ? resolver.response.response(node) : resolver.response.status(node, response.statusCode)])\n }\n\n return types\n}\n\nexport function findSuccessStatusCode(responses: Array<{ statusCode: ast.StatusCode | number | string }>): ast.StatusCode | null {\n for (const response of responses) {\n if (isSuccessStatusCode(response.statusCode)) {\n return response.statusCode as ast.StatusCode\n }\n }\n\n return null\n}\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n\n/**\n * Uppercases only the first character of `text`, leaving the rest untouched.\n * Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.\n *\n * @example\n * `capitalize('getPetById') // 'GetPetById'`\n */\nexport function capitalize(text: string): string {\n return `${text.charAt(0).toUpperCase()}${text.slice(1)}`\n}\n\n/**\n * Converts `text` to snake_case.\n *\n * @example From camelCase\n * `snakeCase('helloWorld') // 'hello_world'`\n *\n * @example From mixed separators\n * `snakeCase('Hello-World') // 'hello_world'`\n */\nexport function snakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n const processed = `${prefix} ${text} ${suffix}`.trim()\n return processed\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * Converts `text` to SCREAMING_SNAKE_CASE.\n *\n * @example From camelCase\n * `screamingSnakeCase('helloWorld') // 'HELLO_WORLD'`\n */\nexport function screamingSnakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return snakeCase(text, { prefix, suffix }).toUpperCase()\n}\n","import { camelCase } from '@internals/utils'\nimport type { Group } from 'kubb/kit'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use the camelCased group (`pet store` → `petStore`).\n *\n * A user-provided `group.name` always wins over the default namer, so callers stay in\n * control of their output folders. Returns `null` when grouping is disabled, matching the\n * per-plugin convention.\n *\n * @param group - The user-supplied group option, or `undefined` to disable grouping.\n *\n * @example\n * ```ts\n * createGroupConfig(group) // shared across every plugin\n * ```\n */\nexport function createGroupConfig(group: Group | undefined): Group | null {\n if (!group) {\n return null\n }\n\n const defaultName = (ctx: { group: string }): string => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return camelCase(ctx.group)\n }\n\n return {\n ...group,\n name: group.name ? group.name : defaultName,\n } satisfies Group\n}\n","import { buildOperationComments, buildRequestParamsSignature } from '@internals/shared'\nimport { ast } from 'kubb/kit'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport { File, Function } from 'kubb/jsx'\nimport type { KubbReactNode } from 'kubb/jsx'\n\ntype Props = {\n /**\n * Name of the handler function.\n */\n name: string\n /**\n * Name of the contract client `<op>` the handler calls.\n */\n clientName: string\n /**\n * AST operation node.\n */\n node: ast.OperationNode\n /**\n * TypeScript resolver for resolving param/data/response type names.\n */\n resolver: ResolverTs\n /**\n * The registered client plugin's `returnType`, read by the caller off `resolveClientOperation`.\n */\n returnType?: 'full' | 'data'\n}\n\nconst requestGroupOrder = ['path', 'query', 'headers', 'body'] as const\n\nexport function McpHandler({ name, clientName, node, resolver, returnType = 'full' }: Props): KubbReactNode {\n if (!ast.isHttpOperationNode(node)) return null\n\n const { signature, groups } = buildRequestParamsSignature(node, resolver, { isConfigurable: false })\n const paramsSignature = [signature, 'request: RequestHandlerExtra<ServerRequest, ServerNotification>'].filter(Boolean).join(', ')\n\n // Forward the grouped config and MCP cancellation signal through the contract client. `throwOnError: true`\n // pins the result shape, since `throwOnErrorDefault: false` would otherwise resolve to the full result.\n const callArgs = requestGroupOrder.filter((key) => groups[key])\n const callConfig = `{ ${[...callArgs, 'signal: request.signal', 'throwOnError: true'].join(', ')} }`\n const body = returnType === 'data' ? 'res' : 'res.data'\n\n const callToolResult = `return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(${body})\n }\n ],\n structuredContent: { data: ${body} }\n}`\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function\n name={name}\n async\n export\n params={paramsSignature}\n JSDoc={{\n comments: buildOperationComments(node),\n }}\n returnType={'CallToolResult'}\n >\n {`const res = await ${clientName}(${callConfig})`}\n <br />\n {callToolResult}\n </Function>\n </File.Source>\n )\n}\n","import type { ast } from 'kubb/kit'\n\nexport type ZodParam = {\n name: string\n schemaName: string\n}\n\n/**\n * Render a group param value — compose individual schemas into `z.object({ ... })`,\n * or use a schema name string directly.\n */\nexport function zodGroupExpr(entry: string | Array<ZodParam>): string {\n if (typeof entry === 'string') {\n return entry\n }\n const entries = entry.map((p) => `${JSON.stringify(p.name)}: ${p.schemaName}`)\n return `z.object({ ${entries.join(', ')} })`\n}\n\n/**\n * Convert a SchemaNode type to an inline Zod expression string.\n * Used as fallback when no named zod schema is available for a path parameter.\n */\nexport function zodExprFromSchemaNode(schema: ast.SchemaNode): string {\n const baseExpr = (() => {\n if (schema.type === 'enum') {\n const rawValues: Array<string | number | boolean> = schema.namedEnumValues?.length\n ? schema.namedEnumValues.map((v) => v.value)\n : (schema.enumValues ?? []).filter((v): v is string | number | boolean => v !== null)\n\n if (rawValues.length > 0 && rawValues.every((v) => typeof v === 'string')) {\n return `z.enum([${rawValues.map((v) => JSON.stringify(v)).join(', ')}])`\n }\n if (rawValues.length > 0) {\n const literals = rawValues.map((v) => `z.literal(${JSON.stringify(v)})`)\n return literals.length === 1 ? literals[0]! : `z.union([${literals.join(', ')}])`\n }\n return 'z.string()'\n }\n if (schema.type === 'integer') return 'z.coerce.number()'\n if (schema.type === 'number') return 'z.number()'\n if (schema.type === 'boolean') return 'z.boolean()'\n if (schema.type === 'array') return 'z.array(z.unknown())'\n return 'z.string()'\n })()\n\n return schema.nullable ? `${baseExpr}.nullable()` : baseExpr\n}\n","import { getOperationParameters } from '@internals/shared'\nimport type { ast } from 'kubb/kit'\nimport { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, functionPrinter } from '@kubb/plugin-ts'\nimport { Const, File, Function } from 'kubb/jsx'\nimport type { KubbReactNode } from 'kubb/jsx'\nimport type { ZodParam } from '../utils.ts'\nimport { zodExprFromSchemaNode, zodGroupExpr } from '../utils.ts'\n\ntype Props = {\n /**\n * Variable name for the MCP server instance (e.g. 'server').\n */\n name: string\n /**\n * Human-readable server name passed to `new McpServer({ name })`.\n */\n serverName: string\n /**\n * Semantic version string passed to `new McpServer({ version })`.\n */\n serverVersion: string\n /**\n * Operations to register as MCP tools, each carrying its handler,\n * zod schema, and AST node metadata.\n */\n operations: Array<{\n tool: {\n name: string\n title?: string\n description: string\n }\n mcp: {\n name: string\n file: ast.FileNode\n }\n zod: {\n pathParams: Array<ZodParam>\n /**\n * Query params — individual schemas to compose into `z.object({ ... })`.\n */\n queryParams?: string | Array<ZodParam> | null\n /**\n * Header params — individual schemas to compose into `z.object({ ... })`.\n */\n headerParams?: string | Array<ZodParam> | null\n requestName?: string | null\n responseName?: string | null\n }\n node: ast.OperationNode\n }>\n}\n\nconst keysPrinter = functionPrinter({ mode: 'call' })\n\nexport function Server({ name, serverName, serverVersion, operations }: Props): KubbReactNode {\n const registrations = operations\n .map(({ tool, mcp, zod, node }) => {\n const { path: pathParams } = getOperationParameters(node)\n\n // Group params into the same `{ path, query, headers, body }` shape the contract `<op>`\n // expects, so the MCP tool input mirrors every other client consumer.\n const entries: Array<{ key: string; value: string }> = []\n\n if (pathParams.length) {\n const pathFields = pathParams\n .map((p) => {\n const zodParam = zod.pathParams.find((zp) => zp.name === p.name)\n return `${JSON.stringify(p.name)}: ${zodParam ? zodParam.schemaName : zodExprFromSchemaNode(p.schema)}`\n })\n .join(', ')\n entries.push({ key: 'path', value: `z.object({ ${pathFields} })` })\n }\n\n if (zod.queryParams) {\n entries.push({ key: 'query', value: zodGroupExpr(zod.queryParams) })\n }\n\n if (zod.headerParams) {\n entries.push({ key: 'headers', value: zodGroupExpr(zod.headerParams) })\n }\n\n if (zod.requestName) {\n entries.push({ key: 'body', value: zod.requestName })\n }\n\n const paramsNode = entries.length\n ? createFunctionParameters({\n params: [\n createFunctionParameter({\n name: createObjectBindingPattern({ elements: entries.map((e) => ({ name: e.key })) }),\n optional: false,\n }),\n ],\n })\n : null\n\n const destructured = paramsNode ? (keysPrinter.print(paramsNode) ?? '') : ''\n const inputSchema = entries.length ? `{ ${entries.map((e) => `${e.key}: ${e.value}`).join(', ')} }` : null\n const outputSchema = zod.responseName\n\n const config = [\n tool.title ? `title: ${JSON.stringify(tool.title)}` : null,\n `description: ${JSON.stringify(tool.description)}`,\n outputSchema ? `outputSchema: { data: ${outputSchema} }` : null,\n ]\n .filter(Boolean)\n .join(',\\n ')\n\n if (inputSchema) {\n return `\nserver.registerTool(${JSON.stringify(tool.name)}, {\n ${config},\n inputSchema: ${inputSchema},\n}, async (${destructured}, request) => {\n return ${mcp.name}(${destructured}, request)\n})\n `\n }\n\n return `\nserver.registerTool(${JSON.stringify(tool.name)}, {\n ${config},\n}, async (request) => {\n return ${mcp.name}(request)\n})\n `\n })\n .filter(Boolean)\n .join('\\n')\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function name=\"getServer\" export>\n {`const server = new McpServer({\n name: '${serverName}',\n version: '${serverVersion}',\n})\n${registrations}\nreturn server`}\n </Function>\n\n <Const name={'server'} export>\n {'getServer()'}\n </Const>\n\n <Function name=\"startServer\" async export>\n {`try {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n\n } catch (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }`}\n </Function>\n </File.Source>\n )\n}\n","/**\n * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an\n * operation, shared so the selection rules and diagnostics stay in one place.\n *\n * Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered\n * contract client plugin (plugin-fetch or plugin-axios) and never emits its own inline client:\n *\n * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer\n * imports and calls them.\n * - `error` — no client plugin is registered, several are registered without a selector, or the\n * requested one is missing.\n *\n * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered\n * contract client plugin is picked up automatically.\n */\n\n// Canonical plugin names. They mirror the `pluginFetchName` / `pluginAxiosName` consts the plugins\n// export, kept as literals so this internal needs no plugin install deps.\nconst pluginFetchName = 'plugin-fetch'\nconst pluginAxiosName = 'plugin-axios'\n\n/**\n * The client selector accepted by a consumer's `client` option. Both call a registered contract\n * client plugin.\n */\nexport type ClientSelector = 'fetch' | 'axios'\n\n/**\n * The resolved client strategy stored in a consumer plugin's options: the generated code always\n * imports and calls a registered contract client plugin's `<op>`. The client runtime lives in\n * plugin-axios / plugin-fetch, so nothing is bundled by the consumer.\n */\nexport type ResolvedContractClient = { kind: 'contract'; pluginName: string }\n\n/**\n * The outcome of {@link resolveClient}.\n *\n * - `contract` names the contract client plugin whose `<op>` functions the consumer imports.\n * - `error` carries a setup diagnostic.\n */\nexport type ResolveClientResult = ResolvedContractClient | { kind: 'error'; message: string }\n\nconst selectorToPlugin: Record<'fetch' | 'axios', string> = {\n fetch: pluginFetchName,\n axios: pluginAxiosName,\n}\n\n// Every contract client plugin, in auto-detect priority order.\nconst contractPlugins = [pluginFetchName, pluginAxiosName] as const\n\n/**\n * Applies the `client` resolution rules. See the module comment for the strategy shape.\n *\n * @example\n * ```ts\n * resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })\n * // { kind: 'contract', pluginName: 'plugin-fetch' }\n * ```\n *\n * @example\n * ```ts\n * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })\n * // { kind: 'error', message: 'No client plugin is registered…' }\n * ```\n */\nexport function resolveClient(options: { client: ClientSelector | undefined; pluginNames: ReadonlyArray<string> }): ResolveClientResult {\n const { client, pluginNames } = options\n const has = (name: string) => pluginNames.includes(name)\n\n if (client === 'fetch' || client === 'axios') {\n const pluginName = selectorToPlugin[client]\n if (!has(pluginName)) {\n return {\n kind: 'error',\n message: `\\`client: '${client}'\\` is set but \\`@kubb/plugin-${client}\\` is not registered in \\`plugins\\`. Add it, or drop \\`client\\` to use a different client plugin.`,\n }\n }\n return { kind: 'contract', pluginName }\n }\n\n // `client` unset: auto-detect a lone registered contract client plugin.\n const registered = contractPlugins.filter(has)\n if (registered.length === 1) {\n return { kind: 'contract', pluginName: registered[0]! }\n }\n if (registered.length > 1) {\n return {\n kind: 'error',\n message: `Multiple client plugins are registered (${registered.map((name) => `\\`@kubb/${name}\\``).join(', ')}). Set \\`client: 'fetch' | 'axios'\\` to choose which client the hooks call, or register a single client plugin.`,\n }\n }\n\n return {\n kind: 'error',\n message: 'No client plugin is registered. Add `@kubb/plugin-axios` or `@kubb/plugin-fetch` to `plugins` so the generated code has an HTTP client to call.',\n }\n}\n\n/**\n * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names\n * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a\n * misconfiguration so every consumer fails fast with the same message.\n */\nexport function resolveContractClient(options: { client: ClientSelector | undefined; plugins?: ReadonlyArray<unknown> }): ResolvedContractClient {\n const { client, plugins = [] } = options\n const pluginNames = plugins.map((plugin) => (plugin as { name?: string }).name).filter((name): name is string => Boolean(name))\n const resolved = resolveClient({ client, pluginNames })\n if (resolved.kind === 'error') {\n throw new Error(resolved.message)\n }\n return resolved\n}\n","import path from 'node:path'\nimport { operationFileEntry } from '@internals/shared'\nimport type { ast, Exclude, Group, Include, NodeCache, Output, Override, Resolver } from 'kubb/kit'\n\n/**\n * The resolved contract `<op>` for one operation: the generated function name, the file it lives in,\n * the contract runtime's `.kubb/client.ts` path (where `RequestConfig` / `ResponseErrorConfig`\n * come from), and the registered client plugin's `returnType`.\n */\nexport type ClientOperation = { name: string; path: string; clientPath: string; returnType: 'full' | 'data' }\n\n/**\n * The client plugin options a dependent reads, including the filters that scope them per operation.\n */\ntype ClientPluginOptions = {\n output?: Output\n group?: Group | null\n returnType?: 'full' | 'data'\n exclude?: Array<Exclude>\n include?: Array<Include>\n override?: Array<Override<Omit<ClientPluginOptions, 'override'>>>\n}\n\n/**\n * Resolves the contract client `<op>` a consumer (query hook, MCP handler) imports, by looking up\n * the registered contract client plugin's resolver and output. Works for any contract client plugin\n * (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline\n * path), or when the client plugin's `exclude` / `include` leaves this operation out, since it then\n * emits no `<op>` to import. The plugin injects `.kubb/client.ts` at the global output root, the\n * same path consumers read `RequestConfig` / `ResponseErrorConfig` from.\n *\n * The result is cached in the current node's `cache` (`ctx.cache`) under the client plugin's name,\n * so several dependents reading the same client plugin for one operation in a single pass\n * (react-query's query/mutation/infinite generators, vue-query, swr, the MCP handler, ...) share\n * one computed result instead of each re-deriving the name and path.\n *\n * `returnType`, `output`, and `group` are the client plugin's options for this operation, after its\n * `override` entries, the same resolution its own generator sees. A dependent's generated call body\n * and import path therefore match the `<op>` actually emitted, even when an `override` changes it.\n */\nexport function resolveClientOperation(options: {\n clientPlugin: { pluginName: string } | null\n driver: {\n getPlugin: (name: string) => { options?: ClientPluginOptions } | undefined\n getResolver: (name: string) => Resolver\n }\n node: ast.OperationNode\n root: string\n output: Output\n cache: NodeCache\n}): ClientOperation | null {\n const { clientPlugin, driver, node, root, output, cache } = options\n if (!clientPlugin) return null\n\n return cache.ensureItem(`${clientPlugin.pluginName}:clientOperation`, () => {\n const resolver = driver.getResolver(clientPlugin.pluginName)\n const pluginOptions = driver.getPlugin(clientPlugin.pluginName)?.options ?? {}\n const { exclude, include, override } = pluginOptions\n const hasOperationOptions = Boolean(exclude?.length || include?.length || override?.length)\n // Kubb's resolver always has `default`; the fallback keeps partial or custom resolvers working.\n const operationOptions =\n hasOperationOptions && resolver.default ? resolver.default.options(node, { options: pluginOptions, exclude, include, override }) : pluginOptions\n if (!operationOptions) return null\n\n const file = resolver.file({\n ...operationFileEntry(node, node.operationId),\n root,\n output: operationOptions.output ?? output,\n group: operationOptions.group ?? undefined,\n })\n\n return {\n name: resolver.name(node.operationId),\n path: file.path,\n clientPath: path.resolve(root, '.kubb/client.ts'),\n returnType: operationOptions.returnType ?? 'full',\n }\n })\n}\n","import { resolveClientOperation } from '@internals/client'\nimport { resolveDependencyOperationFile } from '@internals/shared'\nimport { ast, defineGenerator } from 'kubb/kit'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { File, jsxRenderer } from 'kubb/jsx'\nimport { McpHandler } from '../components/McpHandler.tsx'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Built-in operation generator for `@kubb/plugin-mcp`. Emits one MCP tool\n * handler per OpenAPI operation. The handler takes the grouped `{ path, query,\n * headers, body }` config and forwards it to the registered client plugin's\n * (`@kubb/plugin-axios` / `@kubb/plugin-fetch`) `<op>` function.\n */\nexport const mcpGenerator = defineGenerator<PluginMcp>({\n name: 'mcp',\n renderer: jsxRenderer,\n operation(node, ctx) {\n if (!ast.isHttpOperationNode(node)) return null\n const { resolver, driver, root, config } = ctx\n const { output, client, group } = ctx.options\n\n const pluginTs = driver.getPlugin(pluginTsName)\n\n if (!pluginTs) {\n return null\n }\n\n const tsResolver = driver.getResolver(pluginTsName)\n\n // The registered contract client plugin owns the `<op>` the handler imports and calls.\n const contractOp = resolveClientOperation({ clientPlugin: { pluginName: client.pluginName }, driver, node, root, output, cache: ctx.cache })\n if (!contractOp) {\n return null\n }\n\n // The handler signature references the grouped `<Name>Options`.\n const optionsName = tsResolver.response.options(node)\n\n const meta = {\n name: resolver.handler.name(node),\n file: resolver.file({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path, root, output, group: group ?? undefined }),\n fileTs: resolveDependencyOperationFile({\n cache: ctx.cache,\n node,\n resolver: tsResolver,\n root,\n output: pluginTs.options?.output ?? output,\n group: pluginTs.options?.group,\n }),\n } as const\n\n return (\n <File\n baseName={meta.file.baseName}\n path={meta.file.path}\n meta={meta.file.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n >\n {meta.fileTs && optionsName && <File.Import name={[optionsName]} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />}\n <File.Import name={['CallToolResult', 'ServerNotification', 'ServerRequest']} path={'@modelcontextprotocol/sdk/types.js'} isTypeOnly />\n <File.Import name={['RequestHandlerExtra']} path={'@modelcontextprotocol/sdk/shared/protocol.js'} isTypeOnly />\n\n <File.Import name={[contractOp.name]} root={meta.file.path} path={contractOp.path} />\n\n <McpHandler name={meta.name} clientName={contractOp.name} node={node} resolver={tsResolver} returnType={contractOp.returnType} />\n </File>\n )\n },\n})\n","import path from 'node:path'\nimport { findSuccessStatusCode, getOperationParameters } from '@internals/shared'\nimport { ast, defineGenerator } from 'kubb/kit'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { File, jsxRenderer } from 'kubb/jsx'\nimport { Server } from '../components/Server.tsx'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Default v5 server generator for `@kubb/plugin-mcp`.\n *\n * Uses individual zod schemas for each param (e.g. `createPetsPathUuidSchema`, `createPetsQueryOffsetSchema`)\n * and `resolveResponseStatusName` for per-status response schemas.\n * Query and header params are composed into `z.object({ ... })` from individual schemas.\n */\nexport const serverGenerator = defineGenerator<PluginMcp>({\n name: 'operations',\n renderer: jsxRenderer,\n operations(nodes, ctx) {\n const { config, resolver, plugin, driver, root } = ctx\n const { output, group } = ctx.options\n\n const pluginZod = driver.getPlugin(pluginZodName)\n\n if (!pluginZod) {\n return\n }\n\n const zodResolver = driver.getResolver(pluginZodName)\n\n const name = 'server'\n const serverFilePath = path.resolve(root, output.path, 'server.ts')\n const serverFile = {\n baseName: 'server.ts' as const,\n path: serverFilePath,\n meta: { pluginName: plugin.name },\n }\n\n const jsonFilePath = path.resolve(root, output.path, '.mcp.json')\n const jsonFile = {\n baseName: '.mcp.json' as const,\n path: jsonFilePath,\n meta: { pluginName: plugin.name },\n }\n\n const operationsMapped = nodes.filter(ast.isHttpOperationNode).map((node) => {\n const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node)\n\n const mcpFile = resolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output,\n group: group ?? undefined,\n })\n\n const zodFile = zodResolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output: pluginZod.options?.output ?? output,\n group: pluginZod.options?.group ?? undefined,\n })\n\n const requestName = node.requestBody?.content?.[0]?.schema ? zodResolver.response.body(node) : null\n const successStatus = findSuccessStatusCode(node.responses)\n const responseName = successStatus ? zodResolver.response.status(node, successStatus) : null\n\n const resolveParams = (params: typeof pathParams) => params.map((p) => ({ name: p.name, schemaName: zodResolver.param.name(node, p) }))\n\n return {\n tool: {\n name: node.operationId,\n title: node.summary || undefined,\n description: node.description || `Make a ${node.method.toUpperCase()} request to ${node.path}`,\n },\n mcp: {\n name: resolver.handler.name(node),\n file: mcpFile,\n },\n zod: {\n pathParams: resolveParams(pathParams),\n queryParams: queryParams.length ? resolveParams(queryParams) : null,\n headerParams: headerParams.length ? resolveParams(headerParams) : null,\n requestName,\n responseName,\n file: zodFile,\n },\n node: node,\n }\n })\n\n const imports = operationsMapped.flatMap(({ mcp, zod }) => {\n const zodNames = [\n ...zod.pathParams.map((p) => p.schemaName),\n ...(zod.queryParams ?? []).map((p) => p.schemaName),\n ...(zod.headerParams ?? []).map((p) => p.schemaName),\n zod.requestName,\n zod.responseName,\n ].filter((name): name is string => Boolean(name))\n\n const uniqueNames = [...new Set(zodNames)].sort()\n\n return [\n <File.Import key={mcp.name} name={[mcp.name]} root={serverFile.path} path={mcp.file.path} />,\n uniqueNames.length > 0 && <File.Import key={`zod-${mcp.name}`} name={uniqueNames} root={serverFile.path} path={zod.file.path} />,\n ].filter(Boolean)\n })\n\n return (\n <>\n <File\n baseName={serverFile.baseName}\n path={serverFile.path}\n meta={serverFile.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: serverFile.path, baseName: serverFile.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: serverFile.path, baseName: serverFile.baseName } })}\n >\n <File.Import name={['McpServer']} path={'@modelcontextprotocol/sdk/server/mcp.js'} />\n <File.Import name={['z']} path={'zod'} />\n <File.Import name={['StdioServerTransport']} path={'@modelcontextprotocol/sdk/server/stdio.js'} />\n\n {imports}\n <Server name={name} serverName={ctx.meta.title ?? 'server'} serverVersion={ctx.meta.version ?? '0.0.0'} operations={operationsMapped} />\n </File>\n\n <File baseName={jsonFile.baseName} path={jsonFile.path} meta={jsonFile.meta}>\n <File.Source name={name}>\n {`\n {\n \"mcpServers\": {\n \"${ctx.meta.title || 'server'}\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"${path.relative(path.dirname(jsonFile.path), serverFile.path)}\"]\n }\n }\n }\n `}\n </File.Source>\n </File>\n </>\n )\n },\n})\n","import { camelCase } from '@internals/utils'\nimport { createResolver } from 'kubb/kit'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-mcp`. Decides the names and file\n * paths for every generated MCP tool handler. Function names get a `Handler`\n * suffix so an operation `addPet` becomes `addPetHandler`.\n *\n * @example Resolve a handler name\n * ```ts\n * import { resolverMcp } from '@kubb/plugin-mcp'\n *\n * resolverMcp.name('addPet') // 'addPetHandler'\n * ```\n */\nexport const resolverMcp = createResolver<PluginMcp>({\n pluginName: 'plugin-mcp',\n name(name) {\n return camelCase(name, { suffix: 'handler' })\n },\n handler: {\n name(node) {\n return this.name(node.operationId)\n },\n },\n})\n","import { createGroupConfig } from '@internals/shared'\n\nimport { resolveContractClient } from '@internals/client'\nimport { definePlugin, Resolver } from 'kubb/kit'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { mcpGenerator } from './generators/mcpGenerator.tsx'\nimport { serverGenerator } from './generators/serverGenerator.tsx'\nimport { resolverMcp } from './resolvers/resolverMcp.ts'\nimport type { PluginMcp, ResolverMcp } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-mcp`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginMcpName = 'plugin-mcp' satisfies PluginMcp['name']\n\n/**\n * Generates a Model Context Protocol (MCP) server from an OpenAPI spec. Every\n * operation becomes a typed MCP tool that AI assistants (Claude Desktop, Claude\n * Code, MCP-compatible clients) can call directly. Each handler calls a contract\n * client `<op>` from a registered `@kubb/plugin-axios` or `@kubb/plugin-fetch`.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb/config'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginZod } from '@kubb/plugin-zod'\n * import { pluginMcp } from '@kubb/plugin-mcp'\n *\n * export default defineConfig({\n * input: './petStore.yaml',\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginZod(),\n * pluginMcp({\n * output: { path: './mcp' },\n * baseURL: 'https://petstore.swagger.io/v2',\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginMcp = definePlugin<PluginMcp>((options) => {\n const {\n output = { path: 'mcp', barrel: { type: 'named' } },\n group,\n exclude = [],\n include,\n override = [],\n client,\n resolver: userResolver,\n macros: userMacros,\n } = options\n\n const groupConfig = createGroupConfig(group)\n\n return {\n name: pluginMcpName,\n options,\n dependencies: [pluginTsName, pluginZodName],\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n const resolver = userResolver ? Resolver.merge<ResolverMcp>(resolverMcp, userResolver) : resolverMcp\n\n ctx.setOptions({\n output,\n exclude,\n include,\n override,\n group: groupConfig,\n client: resolveContractClient({ client, plugins: ctx.config.plugins }),\n resolver,\n })\n ctx.setResolver(resolver)\n if (userMacros?.length) {\n ctx.setMacros(userMacros)\n }\n ctx.addGenerator(mcpGenerator, serverGenerator)\n },\n },\n }\n})\n\nexport default pluginMcp\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../internals/shared/src/params.ts","../../../internals/shared/src/operation.ts","../../../internals/utils/src/casing.ts","../../../internals/shared/src/group.ts","../src/components/McpHandler.tsx","../src/utils.ts","../src/components/Server.tsx","../../../internals/client/src/resolveClient.ts","../../../internals/client/src/resolveClientOperation.ts","../src/generators/mcpGenerator.tsx","../src/generators/serverGenerator.tsx","../src/resolvers/resolverMcp.ts","../src/plugin.ts"],"sourcesContent":["import type { ast } from 'kubb/kit'\n\n/**\n * Drops parameters that share the same name, keeping the first.\n *\n * A malformed spec can declare the same parameter name twice within one `in` location. Both would\n * resolve to the same output property, so emitting both would yield an object type with a duplicate\n * member, which TypeScript rejects. This is a defensive guard against that case, not a casing guard:\n * parameter names flow through unchanged, so no two distinct names ever collide here anymore.\n */\nexport function dedupeParams(params: Array<ast.ParameterNode>): Array<ast.ParameterNode> {\n const seen = new Set<string>()\n\n return params.filter((param) => {\n if (seen.has(param.name)) return false\n seen.add(param.name)\n return true\n })\n}\n","import { ast, type Group, type NodeCache, type Output, type Resolver, type ResolverFileParams, Url } from 'kubb/kit'\nimport { dedupeParams } from './params.ts'\n\n/**\n * Builds the `ResolverFileParams` every operation generator passes to\n * `resolver.file`: a file named `name`, tagged by the operation's first\n * tag (or `'default'`), at the operation's path. Centralizes the entry object\n * that was repeated at dozens of call sites across the client and query plugins.\n *\n * @example\n * ```ts\n * resolver.file(operationFileEntry(node, node.operationId), { root, output, group })\n * ```\n */\nexport function operationFileEntry(node: ast.OperationNode, name: string, extname: ResolverFileParams['extname'] = '.ts'): ResolverFileParams {\n return {\n name,\n extname,\n tag: node.tags[0] ?? 'default',\n path: node.path,\n }\n}\n\n/**\n * Resolves a dependency plugin's generated file for `node.operationId`, cached in `cache` (the\n * current node's `ctx.cache`) under the resolver's own plugin name. Several dependents reading the\n * same dependency for the same operation in one pass (a query plugin's several hook generators, the\n * MCP handler, ...) share one computed name and path instead of each calling `resolver.file` again.\n *\n * @example Cache `plugin-ts`'s file for the current operation\n * ```ts\n * const fileTs = resolveDependencyOperationFile({ cache: ctx.cache, node, resolver: tsResolver, root, output })\n * ```\n */\nexport function resolveDependencyOperationFile(options: {\n cache: NodeCache\n node: ast.OperationNode\n resolver: Pick<Resolver, 'file' | 'pluginName'>\n root: string\n output: Output\n group?: Group | null\n}): ast.FileNode {\n const { cache, node, resolver, root, output, group } = options\n\n return cache.ensureItem(`${resolver.pluginName}:operationFile`, () =>\n resolver.file({ ...operationFileEntry(node, node.operationId), root, output, group: group ?? undefined }),\n )\n}\n\nexport type ContentTypeInfo = {\n contentTypes: string[]\n isMultipleContentTypes: boolean\n contentTypeUnion: string\n defaultContentType: string\n hasFormData: boolean\n}\n\nexport type RequestConfigResolver = {\n response: {\n body(node: ast.OperationNode): string\n }\n}\n\nexport type ResponseStatusNameResolver = {\n response: {\n status(node: ast.OperationNode, statusCode: ast.StatusCode): string\n }\n}\n\nexport type ResponseNameResolver = ResponseStatusNameResolver & {\n response: {\n response(node: ast.OperationNode): string\n }\n}\n\nexport type OperationTypeNameResolver = RequestConfigResolver &\n ResponseNameResolver & {\n param: {\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n }\n\n/**\n * Resolver interface for building operation parameters.\n *\n * `ResolverTs` from `@kubb/plugin-ts` satisfies this interface and can be passed directly.\n */\nexport type OperationParamsResolver = {\n /**\n * Naming for an operation's parameters, grouped by location.\n */\n param: {\n /**\n * Resolves the type name for an individual parameter.\n *\n * @example Individual path parameter name\n * `resolver.param.name(node, param) // → 'DeletePetPathPetId'`\n */\n name(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped path parameters type name.\n * When the return value equals `resolver.param.name`, no indexed access is emitted.\n *\n * @example Grouped path params type name\n * `resolver.param.path(node, param) // → 'DeletePetPath'`\n */\n path(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped query parameters type name.\n * When the return value equals `resolver.param.name`, an inline struct type is emitted instead.\n *\n * @example Grouped query params type name\n * `resolver.param.query(node, param) // → 'FindPetsByStatusQuery'`\n */\n query(node: ast.OperationNode, param: ast.ParameterNode): string\n /**\n * Resolves the grouped header parameters type name.\n * When the return value equals `resolver.param.name`, an inline struct type is emitted instead.\n *\n * @example Grouped header params type name\n * `resolver.param.headers(node, param) // → 'DeletePetHeaders'`\n */\n headers(node: ast.OperationNode, param: ast.ParameterNode): string\n }\n /**\n * Naming for an operation's request and response types.\n */\n response: {\n /**\n * Resolves the request body type name.\n *\n * @example Request body type name\n * `resolver.response.body(node) // → 'CreatePetBody'`\n */\n body(node: ast.OperationNode): string\n }\n}\n\nexport type OperationCommentLink = 'pathTemplate' | 'urlPath' | false | ((node: ast.OperationNode) => string | undefined)\n\nexport type BuildOperationCommentsOptions = {\n link?: OperationCommentLink\n linkPosition?: 'beforeDeprecated' | 'afterDeprecated'\n splitLines?: boolean\n}\n\ntype ResponseLike = {\n statusCode: ast.StatusCode | number | string\n}\n\nexport type OperationParameterGroups = Record<ast.ParameterNode['in'], Array<ast.ParameterNode>>\n\nexport type ResolveOperationTypeNameOptions = {\n responseStatusNames?: boolean | 'error'\n exclude?: ReadonlyArray<string | undefined>\n order?: 'params-first' | 'body-response-first'\n /**\n * Include the individual `Path`/`Query`/`Headers` group type names. Set to `false` for clients\n * that reference the grouped `Options` type instead of the per-group types.\n */\n includeParams?: boolean\n}\n\nfunction getOperationLink(node: ast.OperationNode, link: OperationCommentLink): string | null {\n if (!link) {\n return null\n }\n\n if (typeof link === 'function') {\n return link(node) ?? null\n }\n\n return node.path ? `{@link ${Url.toPath(node.path)}}` : null\n}\n\n/**\n * Derives the shared `ContentTypeInfo` shape from a list of content types, tracking whether several\n * are present and the union, default, and form-data flags the client uses to pick one.\n */\nfunction buildContentTypeInfo(contentTypes: string[]): ContentTypeInfo {\n const isMultipleContentTypes = contentTypes.length > 1\n\n return {\n contentTypes,\n isMultipleContentTypes,\n contentTypeUnion: isMultipleContentTypes ? contentTypes.map((ct) => JSON.stringify(ct)).join(' | ') : '',\n defaultContentType: contentTypes[0] ?? 'application/json',\n hasFormData: contentTypes.some((ct) => ct === 'multipart/form-data'),\n }\n}\n\nexport function getContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(node.requestBody?.content?.map((e) => e.contentType) ?? [])\n}\n\n/**\n * The request-body counterpart for the primary success response: the content types it documents and\n * whether several are present, so the client can let a caller pick which one to accept.\n */\nexport function getResponseContentTypeInfo(node: ast.OperationNode): ContentTypeInfo {\n return buildContentTypeInfo(getPrimarySuccessResponse(node)?.content?.map((e) => e.contentType) ?? [])\n}\n\nexport type ResponseType = 'arraybuffer' | 'blob' | 'document' | 'json' | 'text' | 'stream'\n\n/**\n * Reads the single base content type of an operation's primary success response, lowercased and\n * stripped of any `; charset=...` suffix. Returns `undefined` when the response declares zero or\n * more than one content type, since neither case has a single type to act on.\n */\nfunction getPrimarySuccessContentType(node: ast.OperationNode): string | undefined {\n const contentTypes = getPrimarySuccessResponse(node)?.content?.map((entry) => entry.contentType) ?? []\n if (contentTypes.length !== 1) return undefined\n return contentTypes[0]!.split(';')[0]!.trim().toLowerCase()\n}\n\n/**\n * Whether an operation streams its primary success response as Server-Sent Events\n * (`text/event-stream`). The client generator uses this to return a typed event stream instead of a\n * one-shot `RequestResult`.\n */\nexport function isEventStream(node: ast.OperationNode): boolean {\n return getPrimarySuccessContentType(node) === 'text/event-stream'\n}\n\n/**\n * Derives the default `responseType` for an operation from its primary success response.\n *\n * Returns a value only when that response declares a single non-JSON content type. `text/event-stream`\n * and other binary types (`application/octet-stream`, `application/pdf`, `image/*`, `audio/*`,\n * `video/*`) map to a stream or `'blob'`, and other `text/*` maps to `'text'`. Otherwise `undefined`,\n * leaving the runtime client's `Content-Type` auto-detection in charge.\n */\nexport function getResponseType(node: ast.OperationNode): ResponseType | undefined {\n const baseType = getPrimarySuccessContentType(node)\n if (!baseType) return undefined\n\n if (baseType === 'application/json' || baseType.endsWith('+json') || baseType === 'text/json') return undefined\n if (baseType === 'text/event-stream') return 'stream'\n if (baseType.startsWith('text/')) return 'text'\n if (baseType === 'application/octet-stream' || baseType === 'application/pdf' || /^(image|audio|video)\\//.test(baseType)) return 'blob'\n return undefined\n}\n\n/**\n * Maps a content type to the PascalCase suffix used to name per-content-type variants\n * (e.g. `application/json` → `Json`, `application/xml` → `Xml`, `multipart/form-data` → `FormData`).\n */\nfunction getContentTypeSuffix(contentType: string): string {\n const baseType = contentType.split(';')[0]!.trim()\n if (baseType === 'application/json') return 'Json'\n if (baseType === 'multipart/form-data') return 'FormData'\n if (baseType === 'application/x-www-form-urlencoded') return 'FormUrlEncoded'\n const subtype = baseType.split('/').pop() ?? baseType\n const parts = subtype.split(/[^a-zA-Z0-9]+/).filter(Boolean)\n if (parts.length === 0) return 'Unknown'\n return parts.map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join('')\n}\n\n/**\n * Appends a content-type suffix to a base name, keeping a trailing `Data` segment last\n * (e.g. `AddPetData` + `Json` → `AddPetJsonData`, `AddPetStatus200` + `Xml` → `AddPetStatus200Xml`).\n */\nexport function getPerContentTypeName(baseName: string, suffix: string): string {\n if (baseName.endsWith('Data')) {\n return suffix.endsWith('Data') ? baseName.slice(0, -4) + suffix : `${baseName.slice(0, -4)}${suffix}Data`\n }\n return baseName + suffix\n}\n\nexport type ContentVariantInput = { contentType: string; schema?: ast.SchemaNode | null; keysToOmit?: Array<string> | null }\nexport type ContentVariant = { name: string; suffix: string; schema: ast.SchemaNode; keysToOmit?: Array<string> | null; contentType: string }\n\n/**\n * Resolves per-content-type variant names for a set of content entries, deduplicating suffix\n * collisions with a numeric counter. Entries without a schema are skipped. The returned `suffix` is\n * the final (possibly counter-augmented) value, so callers can derive parallel names in another\n * namespace (e.g. plugin-faker deriving the matching plugin-ts type name).\n */\nexport function resolveContentTypeVariants(entries: Array<ContentVariantInput>, baseName: string): Array<ContentVariant> {\n const usedNames = new Set<string>()\n return entries\n .filter((entry) => entry.schema)\n .map((entry) => {\n const baseSuffix = getContentTypeSuffix(entry.contentType)\n let suffix = baseSuffix\n let name = getPerContentTypeName(baseName, suffix)\n let counter = 2\n while (usedNames.has(name)) {\n suffix = `${baseSuffix}${counter++}`\n name = getPerContentTypeName(baseName, suffix)\n }\n usedNames.add(name)\n return { name, suffix, schema: entry.schema!, keysToOmit: entry.keysToOmit, contentType: entry.contentType }\n })\n}\n\nexport function buildRequestConfigType(node: ast.OperationNode): string {\n const request = getContentTypeInfo(node)\n const response = getResponseContentTypeInfo(node)\n // The request groups come from the grouped params, so `config` drops the data-shape keys to stay\n // assignable to `Options`, which omits them from `RequestConfig`.\n const configType = `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n\n // Only the ambiguous side is offered: a single-type side has nothing to pick, so it stays baked in\n // the generated call.\n const members = [\n request.isMultipleContentTypes ? `request?: ${request.contentTypeUnion}` : null,\n response.isMultipleContentTypes ? `response?: ${response.contentTypeUnion}` : null,\n ].filter(Boolean)\n\n return members.length ? `${configType} & { contentType?: { ${members.join('; ')} } }` : configType\n}\n\n/**\n * Builds the `client?:` option type shared by the generated query hooks (`useQuery`,\n * `useInfiniteQuery`, `useSWR`, ...). Unlike {@link buildRequestConfigType}, it never adds a\n * `contentType?:` member: query hooks wrap GET operations, which carry no request body to select a\n * content type for.\n */\nexport function buildClientOptionType(): string {\n return `Partial<Omit<RequestConfig, 'path' | 'query' | 'body' | 'headers' | 'url'>>`\n}\n\nexport type RequestGroups = {\n path: boolean\n query: boolean\n body: boolean\n headers: boolean\n}\n\n/**\n * Which of the grouped request options an operation carries.\n */\nexport function getRequestGroups(node: ast.OperationNode): RequestGroups {\n const { path, query, header } = getOperationParameters(node)\n return {\n path: path.length > 0,\n query: query.length > 0,\n body: Boolean(node.requestBody?.content?.[0]?.schema),\n headers: header.length > 0,\n }\n}\n\nexport type RequestGroupOptionality = {\n groups: RequestGroups\n hasRequiredPath: boolean\n hasRequiredQuery: boolean\n hasRequiredHeader: boolean\n /**\n * Whether the grouped request parameter can default to `{}`. True only when no group carries a\n * required member, so every member is safe to omit.\n */\n isOptional: boolean\n}\n\n/**\n * Resolves which grouped request options an operation carries together with whether each group\n * holds a required member. The grouped parameter stays optional only when nothing inside it is\n * required, matching the generated `RequestConfig` type.\n */\nexport function getRequestGroupOptionality(node: ast.OperationNode): RequestGroupOptionality {\n const groups = getRequestGroups(node)\n const { path, query, header } = getOperationParameters(node)\n const hasRequiredPath = path.some((param) => param.required)\n const hasRequiredQuery = query.some((param) => param.required)\n const hasRequiredHeader = header.some((param) => param.required)\n\n return {\n groups,\n hasRequiredPath,\n hasRequiredQuery,\n hasRequiredHeader,\n isOptional: !hasRequiredPath && !hasRequiredQuery && !hasRequiredHeader && !groups.body,\n }\n}\n\nexport type RequestOptionsNameResolver = RequestConfigResolver & {\n response: {\n options(node: ast.OperationNode): string\n }\n}\n\n/**\n * Builds the grouped `{ path, query, body, headers }` parameter for a generated client\n * function, typed from the operation's `Options` (minus `url`). Only the groups the\n * operation actually has are destructured. The trailing `config` parameter carries the\n * runtime `RequestConfig` overrides plus `client`.\n */\nexport function buildRequestParamsSignature(\n node: ast.OperationNode,\n resolver: RequestOptionsNameResolver,\n options: { isConfigurable?: boolean } = {},\n): { signature: string; groups: RequestGroups } {\n const { isConfigurable = true } = options\n const { groups, isOptional } = getRequestGroupOptionality(node)\n\n const names = (['path', 'query', 'body', 'headers'] as const).filter((key) => groups[key])\n\n const firstParam = names.length > 0 ? `{ ${names.join(', ')} }: ${resolver.response.options(node)}${isOptional ? ' = {}' : ''}` : null\n const configParam = isConfigurable ? `config: ${buildRequestConfigType(node)} = {}` : null\n\n return {\n signature: [firstParam, configParam].filter(Boolean).join(', '),\n groups,\n }\n}\n\nexport function buildOperationComments(node: ast.OperationNode, options: BuildOperationCommentsOptions = {}): Array<string> {\n const { link = 'pathTemplate', linkPosition = 'afterDeprecated', splitLines = false } = options\n const linkComment = getOperationLink(node, link)\n const comments =\n linkPosition === 'beforeDeprecated'\n ? [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, linkComment, node.deprecated && '@deprecated']\n : [node.description && `@description ${node.description}`, node.summary && `@summary ${node.summary}`, node.deprecated && '@deprecated', linkComment]\n\n const filteredComments = comments.filter((comment): comment is string => Boolean(comment))\n\n if (!splitLines) {\n return filteredComments\n }\n\n return filteredComments.flatMap((text) => text.split(/\\r?\\n/).map((line) => line.trim())).filter((comment): comment is string => Boolean(comment))\n}\n\nconst operationParameterGroupsByNode = new WeakMap<ast.OperationNode, OperationParameterGroups>()\n\n/**\n * Groups an operation's parameters by location (`path`/`query`/`header`/`cookie`), deduping each\n * group by name. Every plugin generator visiting the same `OperationNode` shares one AST instance\n * (see `KubbDriver`), so the result is cached per node to avoid re-filtering and re-deduping the\n * same parameters once per plugin.\n */\nexport function getOperationParameters(node: ast.OperationNode): OperationParameterGroups {\n const cached = operationParameterGroupsByNode.get(node)\n if (cached) return cached\n\n const groups: OperationParameterGroups = {\n path: dedupeParams(node.parameters.filter((param) => param.in === 'path')),\n query: dedupeParams(node.parameters.filter((param) => param.in === 'query')),\n header: dedupeParams(node.parameters.filter((param) => param.in === 'header')),\n cookie: dedupeParams(node.parameters.filter((param) => param.in === 'cookie')),\n }\n\n operationParameterGroupsByNode.set(node, groups)\n return groups\n}\n\n/**\n * Builds the combined `{ body, path, query, headers }` options object schema for an operation,\n * referencing the already-resolved body and grouped param names. Shared by `@kubb/plugin-ts`'s\n * `Options` type and `@kubb/plugin-zod`'s inferred options schema, so both printers emit the same\n * shape from the same inputs. `primitive: 'object'` is a no-op for the TS printer and tells the Zod\n * printer to emit `z.object(…)` rather than a record.\n */\nexport function buildOptionsSchema(node: ast.OperationNode, resolver: OperationTypeNameResolver): ast.SchemaNode {\n const { path, query, header } = getOperationParameters(node)\n const hasBody = Boolean(node.requestBody?.content?.[0]?.schema)\n const createNever = () => ast.factory.createSchema({ type: 'never', primitive: undefined, optional: true })\n const groups = [\n { name: 'path', params: path, resolve: resolver.param.path },\n { name: 'query', params: query, resolve: resolver.param.query },\n { name: 'headers', params: header, resolve: resolver.param.headers },\n ] as const\n\n // NOTE(v5-stable): the fields were renamed from the legacy beta shape\n // (`data`/`pathParams`/`queryParams`/`headerParams`) to `body`/`path`/`query`/`headers` so the\n // type matches the runtime client. Drop this note once v5 leaves beta.\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n deprecated: node.deprecated,\n properties: [\n ast.factory.createProperty({\n name: 'body',\n required: hasBody,\n schema: hasBody ? ast.factory.createSchema({ type: 'ref', name: resolver.response.body(node) }) : createNever(),\n }),\n ...groups.map(({ name, params, resolve }) => {\n const required = params.some((param) => param.required)\n\n return ast.factory.createProperty({\n name,\n required,\n schema:\n params.length > 0\n ? ast.factory.createSchema({ type: 'ref', name: resolve.call(resolver.param, node, params[0]!), optional: !required })\n : createNever(),\n })\n }),\n ],\n })\n}\n\n/**\n * The schema a status occupies in the `<Name>Responses` record. A status that documents several\n * content types becomes a `{ contentType; data }` union so the runtime can surface the negotiated type\n * on `result.parsed`, while the standalone `<Name>StatusNNN` alias stays the plain body union that the\n * query hooks and `result.data` use.\n */\nfunction buildResponseRecordEntry(node: ast.OperationNode, res: ast.ResponseNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n const statusName = resolver.response.status(node, res.statusCode)\n const variants = (res.content ?? []).filter((entry) => entry.schema)\n if (variants.length <= 1) {\n return ast.factory.createSchema({ type: 'ref', name: statusName })\n }\n\n return ast.factory.createSchema({\n type: 'union',\n members: resolveContentTypeVariants(variants, statusName).map((variant) =>\n ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: [\n ast.factory.createProperty({\n name: 'contentType',\n required: true,\n schema: ast.factory.createSchema({ type: 'enum', enumValues: [variant.contentType] }),\n }),\n ast.factory.createProperty({\n name: 'data',\n required: true,\n schema: ast.factory.createSchema({ type: 'ref', name: variant.name }),\n }),\n ],\n }),\n ),\n })\n}\n\n/**\n * Builds the per-status `<Name>Responses` record for an operation, referencing the already-resolved\n * `<Name>StatusNNN` names. Shared by `@kubb/plugin-ts`'s `Responses` type and `@kubb/plugin-zod`'s\n * inferred responses schema, so both emit the same shape from the same inputs.\n *\n * Always emits the keyed record, even when an operation declares no responses. An operation with no\n * responses renders as an empty object, which keeps every consumer's import (for example the axios\n * SDK's `RequestResult<XResponses>`) resolvable instead of pointing at a missing export.\n */\nexport function buildResponses(node: ast.OperationNode, resolver: ResponseStatusNameResolver): ast.SchemaNode {\n return ast.factory.createSchema({\n type: 'object',\n primitive: 'object',\n properties: node.responses.map((res) =>\n ast.factory.createProperty({\n name: String(res.statusCode),\n required: true,\n schema: buildResponseRecordEntry(node, res, resolver),\n }),\n ),\n })\n}\n\nexport function getStatusCodeNumber(statusCode: ast.StatusCode | number | string): number | null {\n const code = Number(statusCode)\n\n return Number.isNaN(code) ? null : code\n}\n\nexport function isSuccessStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 200 && code < 300\n}\n\nexport function isErrorStatusCode(statusCode: ast.StatusCode | number | string): boolean {\n const code = getStatusCodeNumber(statusCode)\n\n return code !== null && code >= 400\n}\n\nexport function getSuccessResponses<TResponse extends ResponseLike>(responses: ReadonlyArray<TResponse>): Array<TResponse> {\n return responses.filter((response) => isSuccessStatusCode(response.statusCode))\n}\n\nexport function getOperationSuccessResponses(node: ast.OperationNode): Array<ast.ResponseNode> {\n return getSuccessResponses(node.responses)\n}\n\nexport function getPrimarySuccessResponse(node: ast.OperationNode): ast.ResponseNode | null {\n return getOperationSuccessResponses(node)[0] ?? null\n}\n\nexport function resolveErrorNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isErrorStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveSuccessNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.filter((response) => isSuccessStatusCode(response.statusCode)).map((response) => resolver.response.status(node, response.statusCode))\n}\n\nexport function resolveStatusCodeNames(node: ast.OperationNode, resolver: ResponseStatusNameResolver): string[] {\n return node.responses.map((response) => resolver.response.status(node, response.statusCode))\n}\n\nconst typeNamesByResolver = new WeakMap<OperationTypeNameResolver, Map<string, string[]>>()\n\nexport function resolveOperationTypeNames(\n node: ast.OperationNode,\n resolver: OperationTypeNameResolver,\n options: ResolveOperationTypeNameOptions = {},\n): string[] {\n const cacheKey = `${node.operationId}\\0${options.order ?? ''}\\0${options.responseStatusNames ?? ''}\\0${options.includeParams === false ? 'noparams' : ''}\\0${(options.exclude ?? []).join(',')}`\n let byResolver = typeNamesByResolver.get(resolver)\n if (byResolver) {\n const cached = byResolver.get(cacheKey)\n if (cached) return cached\n } else {\n byResolver = new Map()\n typeNamesByResolver.set(resolver, byResolver)\n }\n\n const { path, query, header } = getOperationParameters(node)\n const responseStatusNames =\n options.responseStatusNames === 'error'\n ? resolveErrorNames(node, resolver)\n : options.responseStatusNames === false\n ? []\n : resolveStatusCodeNames(node, resolver)\n const exclude = new Set(options.exclude ?? [])\n const paramNames =\n options.includeParams === false\n ? []\n : [\n ...path.map((param) => resolver.param.path(node, param)),\n ...query.map((param) => resolver.param.query(node, param)),\n ...header.map((param) => resolver.param.headers(node, param)),\n ]\n const bodyAndResponseNames = [node.requestBody?.content?.[0]?.schema ? resolver.response.body(node) : null, resolver.response.response(node)]\n const names =\n options.order === 'body-response-first'\n ? [...bodyAndResponseNames, ...paramNames, ...responseStatusNames]\n : [...paramNames, ...bodyAndResponseNames, ...responseStatusNames]\n\n const result = names.filter((name): name is string => Boolean(name) && !exclude.has(name as string))\n byResolver.set(cacheKey, result)\n return result\n}\n\nexport function resolveResponseTypes(node: ast.OperationNode, resolver: ResponseNameResolver): Array<[statusCode: number | 'default', typeName: string]> {\n const types: Array<[number | 'default', string]> = []\n\n for (const response of node.responses) {\n if (response.statusCode === 'default') {\n types.push(['default', resolver.response.response(node)])\n continue\n }\n\n const code = getStatusCodeNumber(response.statusCode)\n if (code === null) {\n continue\n }\n\n types.push([code, isSuccessStatusCode(code) ? resolver.response.response(node) : resolver.response.status(node, response.statusCode)])\n }\n\n return types\n}\n\nexport function findSuccessStatusCode(responses: Array<{ statusCode: ast.StatusCode | number | string }>): ast.StatusCode | null {\n for (const response of responses) {\n if (isSuccessStatusCode(response.statusCode)) {\n return response.statusCode as ast.StatusCode\n }\n }\n\n return null\n}\n","type Options = {\n /**\n * Text prepended before casing is applied.\n */\n prefix?: string\n /**\n * Text appended before casing is applied.\n */\n suffix?: string\n}\n\n/**\n * Shared implementation for camelCase and PascalCase conversion.\n * Splits on common word boundaries (spaces, hyphens, underscores, dots, slashes, colons)\n * and capitalizes each word according to `pascal`.\n *\n * When `pascal` is `true` the first word is also capitalized (PascalCase), otherwise only subsequent words are.\n */\nfunction toCamelOrPascal(text: string, pascal: boolean): string {\n return text\n .trim()\n .replace(/([a-z\\d])([A-Z])/g, '$1 $2')\n .replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2')\n .replace(/(\\d)([a-z])/g, '$1 $2')\n .split(/[\\s\\-_./\\\\:]+/)\n .filter(Boolean)\n .map((word, i) => {\n if (word.length > 1 && word === word.toUpperCase()) return word\n const head = i === 0 && !pascal ? word.charAt(0).toLowerCase() : word.charAt(0).toUpperCase()\n return head + word.slice(1)\n })\n .join('')\n .replace(/[^a-zA-Z0-9]/g, '')\n}\n\n/**\n * Converts `text` to camelCase.\n *\n * @example Word boundaries\n * `camelCase('hello-world') // 'helloWorld'`\n *\n * @example With a prefix\n * `camelCase('tag', { prefix: 'create' }) // 'createTag'`\n */\nexport function camelCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false)\n}\n\n/**\n * Converts `text` to PascalCase.\n *\n * @example Word boundaries\n * `pascalCase('hello-world') // 'HelloWorld'`\n *\n * @example With a suffix\n * `pascalCase('tag', { suffix: 'schema' }) // 'TagSchema'`\n */\nexport function pascalCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return toCamelOrPascal(`${prefix} ${text} ${suffix}`, true)\n}\n\n/**\n * Uppercases only the first character of `text`, leaving the rest untouched.\n * Unlike {@link pascalCase} it never re-splits word boundaries or strips characters.\n *\n * @example\n * `capitalize('getPetById') // 'GetPetById'`\n */\nexport function capitalize(text: string): string {\n return `${text.charAt(0).toUpperCase()}${text.slice(1)}`\n}\n\n/**\n * Converts `text` to snake_case.\n *\n * @example From camelCase\n * `snakeCase('helloWorld') // 'hello_world'`\n *\n * @example From mixed separators\n * `snakeCase('Hello-World') // 'hello_world'`\n */\nexport function snakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n const processed = `${prefix} ${text} ${suffix}`.trim()\n return processed\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .toLowerCase()\n .split('_')\n .filter(Boolean)\n .join('_')\n}\n\n/**\n * Converts `text` to SCREAMING_SNAKE_CASE.\n *\n * @example From camelCase\n * `screamingSnakeCase('helloWorld') // 'HELLO_WORLD'`\n */\nexport function screamingSnakeCase(text: string, { prefix = '', suffix = '' }: Options = {}): string {\n return snakeCase(text, { prefix, suffix }).toUpperCase()\n}\n","import { camelCase } from '@internals/utils'\nimport type { Group } from 'kubb/kit'\n\n/**\n * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the\n * shared default naming so every plugin groups output consistently:\n *\n * - `path` groups use the second path segment (`/pet/findByStatus` → `pet`).\n * - other groups use the camelCased group (`pet store` → `petStore`).\n *\n * A user-provided `group.name` always wins over the default namer, so callers stay in\n * control of their output folders. Returns `null` when grouping is disabled, matching the\n * per-plugin convention.\n *\n * @param group - The user-supplied group option, or `undefined` to disable grouping.\n *\n * @example\n * ```ts\n * createGroupConfig(group) // shared across every plugin\n * ```\n */\nexport function createGroupConfig(group: Group | undefined): Group | null {\n if (!group) {\n return null\n }\n\n const defaultName = (ctx: { group: string }): string => {\n if (group.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n\n return camelCase(ctx.group)\n }\n\n return {\n ...group,\n name: group.name ? group.name : defaultName,\n } satisfies Group\n}\n","import { buildOperationComments, buildRequestParamsSignature } from '@internals/shared'\nimport { ast } from 'kubb/kit'\nimport type { ResolverTs } from '@kubb/plugin-ts'\nimport { File, Function } from 'kubb/jsx'\nimport type { KubbReactNode } from 'kubb/jsx'\n\ntype Props = {\n /**\n * Name of the handler function.\n */\n name: string\n /**\n * Name of the contract client `<op>` the handler calls.\n */\n clientName: string\n /**\n * AST operation node.\n */\n node: ast.OperationNode\n /**\n * TypeScript resolver for resolving param/data/response type names.\n */\n resolver: ResolverTs\n /**\n * The registered client plugin's `returnType`, read by the caller off `resolveClientOperation`.\n */\n returnType?: 'full' | 'data'\n}\n\nconst requestGroupOrder = ['path', 'query', 'headers', 'body'] as const\n\nexport function McpHandler({ name, clientName, node, resolver, returnType = 'full' }: Props): KubbReactNode {\n if (!ast.isHttpOperationNode(node)) return null\n\n const { signature, groups } = buildRequestParamsSignature(node, resolver, { isConfigurable: false })\n const paramsSignature = [signature, 'request: RequestHandlerExtra<ServerRequest, ServerNotification>'].filter(Boolean).join(', ')\n\n // Forward the grouped config and MCP cancellation signal through the contract client. `throwOnError: true`\n // pins the result shape, since `throwOnErrorDefault: false` would otherwise resolve to the full result.\n const callArgs = requestGroupOrder.filter((key) => groups[key])\n const callConfig = `{ ${[...callArgs, 'signal: request.signal', 'throwOnError: true'].join(', ')} }`\n const body = returnType === 'data' ? 'res' : 'res.data'\n\n const callToolResult = `return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(${body})\n }\n ],\n structuredContent: { data: ${body} }\n}`\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function\n name={name}\n async\n export\n params={paramsSignature}\n JSDoc={{\n comments: buildOperationComments(node),\n }}\n returnType={'CallToolResult'}\n >\n {`const res = await ${clientName}(${callConfig})`}\n <br />\n {callToolResult}\n </Function>\n </File.Source>\n )\n}\n","import type { ast } from 'kubb/kit'\n\nexport type ZodParam = {\n name: string\n schemaName: string\n}\n\n/**\n * Render a group param value — compose individual schemas into `z.object({ ... })`,\n * or use a schema name string directly.\n */\nexport function zodGroupExpr(entry: string | Array<ZodParam>): string {\n if (typeof entry === 'string') {\n return entry\n }\n const entries = entry.map((p) => `${JSON.stringify(p.name)}: ${p.schemaName}`)\n return `z.object({ ${entries.join(', ')} })`\n}\n\n/**\n * Convert a SchemaNode type to an inline Zod expression string.\n * Used as fallback when no named zod schema is available for a path parameter.\n */\nexport function zodExprFromSchemaNode(schema: ast.SchemaNode): string {\n const baseExpr = (() => {\n if (schema.type === 'enum') {\n const rawValues: Array<string | number | boolean> = schema.namedEnumValues?.length\n ? schema.namedEnumValues.map((v) => v.value)\n : (schema.enumValues ?? []).filter((v): v is string | number | boolean => v !== null)\n\n if (rawValues.length > 0 && rawValues.every((v) => typeof v === 'string')) {\n return `z.enum([${rawValues.map((v) => JSON.stringify(v)).join(', ')}])`\n }\n if (rawValues.length > 0) {\n const literals = rawValues.map((v) => `z.literal(${JSON.stringify(v)})`)\n return literals.length === 1 ? literals[0]! : `z.union([${literals.join(', ')}])`\n }\n return 'z.string()'\n }\n if (schema.type === 'integer') return 'z.coerce.number()'\n if (schema.type === 'number') return 'z.number()'\n if (schema.type === 'boolean') return 'z.boolean()'\n if (schema.type === 'array') return 'z.array(z.unknown())'\n return 'z.string()'\n })()\n\n return schema.nullable ? `${baseExpr}.nullable()` : baseExpr\n}\n","import { getOperationParameters } from '@internals/shared'\nimport type { ast } from 'kubb/kit'\nimport { createFunctionParameter, createFunctionParameters, createObjectBindingPattern, functionPrinter } from '@kubb/plugin-ts'\nimport { Const, File, Function } from 'kubb/jsx'\nimport type { KubbReactNode } from 'kubb/jsx'\nimport type { ZodParam } from '../utils.ts'\nimport { zodExprFromSchemaNode, zodGroupExpr } from '../utils.ts'\n\ntype Props = {\n /**\n * Variable name for the MCP server instance (e.g. 'server').\n */\n name: string\n /**\n * Human-readable server name passed to `new McpServer({ name })`.\n */\n serverName: string\n /**\n * Semantic version string passed to `new McpServer({ version })`.\n */\n serverVersion: string\n /**\n * Operations to register as MCP tools, each carrying its handler,\n * zod schema, and AST node metadata.\n */\n operations: Array<{\n tool: {\n name: string\n title?: string\n description: string\n }\n mcp: {\n name: string\n file: ast.FileNode\n }\n zod: {\n pathParams: Array<ZodParam>\n /**\n * Query params — individual schemas to compose into `z.object({ ... })`.\n */\n queryParams?: string | Array<ZodParam> | null\n /**\n * Header params — individual schemas to compose into `z.object({ ... })`.\n */\n headerParams?: string | Array<ZodParam> | null\n requestName?: string | null\n responseName?: string | null\n }\n node: ast.OperationNode\n }>\n}\n\nconst keysPrinter = functionPrinter({ mode: 'call' })\n\nexport function Server({ name, serverName, serverVersion, operations }: Props): KubbReactNode {\n const registrations = operations\n .map(({ tool, mcp, zod, node }) => {\n const { path: pathParams } = getOperationParameters(node)\n\n // Group params into the same `{ path, query, headers, body }` shape the contract `<op>`\n // expects, so the MCP tool input mirrors every other client consumer.\n const entries: Array<{ key: string; value: string }> = []\n\n if (pathParams.length) {\n const pathFields = pathParams\n .map((p) => {\n const zodParam = zod.pathParams.find((zp) => zp.name === p.name)\n return `${JSON.stringify(p.name)}: ${zodParam ? zodParam.schemaName : zodExprFromSchemaNode(p.schema)}`\n })\n .join(', ')\n entries.push({ key: 'path', value: `z.object({ ${pathFields} })` })\n }\n\n if (zod.queryParams) {\n entries.push({ key: 'query', value: zodGroupExpr(zod.queryParams) })\n }\n\n if (zod.headerParams) {\n entries.push({ key: 'headers', value: zodGroupExpr(zod.headerParams) })\n }\n\n if (zod.requestName) {\n entries.push({ key: 'body', value: zod.requestName })\n }\n\n const paramsNode = entries.length\n ? createFunctionParameters({\n params: [\n createFunctionParameter({\n name: createObjectBindingPattern({ elements: entries.map((e) => ({ name: e.key })) }),\n optional: false,\n }),\n ],\n })\n : null\n\n const destructured = paramsNode ? (keysPrinter.print(paramsNode) ?? '') : ''\n const inputSchema = entries.length ? `{ ${entries.map((e) => `${e.key}: ${e.value}`).join(', ')} }` : null\n const outputSchema = zod.responseName\n\n const config = [\n tool.title ? `title: ${JSON.stringify(tool.title)}` : null,\n `description: ${JSON.stringify(tool.description)}`,\n outputSchema ? `outputSchema: { data: ${outputSchema} }` : null,\n ]\n .filter(Boolean)\n .join(',\\n ')\n\n if (inputSchema) {\n return `\nserver.registerTool(${JSON.stringify(tool.name)}, {\n ${config},\n inputSchema: ${inputSchema},\n}, async (${destructured}, request) => {\n return ${mcp.name}(${destructured}, request)\n})\n `\n }\n\n return `\nserver.registerTool(${JSON.stringify(tool.name)}, {\n ${config},\n}, async (request) => {\n return ${mcp.name}(request)\n})\n `\n })\n .filter(Boolean)\n .join('\\n')\n\n return (\n <File.Source name={name} isExportable isIndexable>\n <Function name=\"getServer\" export>\n {`const server = new McpServer({\n name: '${serverName}',\n version: '${serverVersion}',\n})\n${registrations}\nreturn server`}\n </Function>\n\n <Const name={'server'} export>\n {'getServer()'}\n </Const>\n\n <Function name=\"startServer\" async export>\n {`try {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n\n } catch (error) {\n console.error('Failed to start server:', error)\n process.exit(1)\n }`}\n </Function>\n </File.Source>\n )\n}\n","/**\n * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an\n * operation, shared so the selection rules and diagnostics stay in one place.\n *\n * Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered\n * contract client plugin (plugin-fetch or plugin-axios) and never emits its own inline client:\n *\n * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer\n * imports and calls them.\n * - `error` — no client plugin is registered, several are registered without a selector, the\n * requested one is missing, or `client` is not a known selector.\n *\n * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered\n * contract client plugin is picked up automatically.\n */\n\n// Canonical plugin names. They mirror the `pluginFetchName` / `pluginAxiosName` consts the plugins\n// export, kept as literals so this internal needs no plugin install deps.\nconst pluginFetchName = 'plugin-fetch'\nconst pluginAxiosName = 'plugin-axios'\n\n/**\n * The client selector accepted by a consumer's `client` option. Both call a registered contract\n * client plugin.\n */\nexport type ClientSelector = 'fetch' | 'axios'\n\n/**\n * The resolved client strategy stored in a consumer plugin's options: the generated code always\n * imports and calls a registered contract client plugin's `<op>`. The client runtime lives in\n * plugin-axios / plugin-fetch, so nothing is bundled by the consumer.\n */\nexport type ResolvedContractClient = { kind: 'contract'; pluginName: string }\n\n/**\n * The outcome of {@link resolveClient}.\n *\n * - `contract` names the contract client plugin whose `<op>` functions the consumer imports.\n * - `error` carries a setup diagnostic.\n */\nexport type ResolveClientResult = ResolvedContractClient | { kind: 'error'; message: string }\n\nconst selectorToPlugin: Record<'fetch' | 'axios', string> = {\n fetch: pluginFetchName,\n axios: pluginAxiosName,\n}\n\n// Every contract client plugin, in auto-detect priority order.\nconst contractPlugins = [pluginFetchName, pluginAxiosName] as const\n\n/**\n * Applies the `client` resolution rules. See the module comment for the strategy shape.\n *\n * @example\n * ```ts\n * resolveClient({ client: 'fetch', pluginNames: ['plugin-ts', 'plugin-fetch'] })\n * // { kind: 'contract', pluginName: 'plugin-fetch' }\n * ```\n *\n * @example\n * ```ts\n * resolveClient({ client: undefined, pluginNames: ['plugin-ts'] })\n * // { kind: 'error', message: 'No client plugin is registered…' }\n * ```\n */\nexport function resolveClient(options: { client: ClientSelector | undefined; pluginNames: ReadonlyArray<string> }): ResolveClientResult {\n const { client, pluginNames } = options\n const has = (name: string) => pluginNames.includes(name)\n\n if (client === 'fetch' || client === 'axios') {\n const pluginName = selectorToPlugin[client]\n if (!has(pluginName)) {\n return {\n kind: 'error',\n message: `\\`client: '${client}'\\` is set but \\`@kubb/plugin-${client}\\` is not registered in \\`plugins\\`. Add it, or drop \\`client\\` to use a different client plugin.`,\n }\n }\n return { kind: 'contract', pluginName }\n }\n\n // A JS config bypasses the `ClientSelector` type, so reject unknown selectors instead of auto-detecting.\n if (client !== undefined) {\n return {\n kind: 'error',\n message: `Option \\`client\\` is ${typeof client === 'string' ? `'${client}'` : String(client)}, but it must be one of 'fetch', 'axios'. Drop \\`client\\` to use the registered client plugin.`,\n }\n }\n\n // `client` unset: auto-detect a lone registered contract client plugin.\n const registered = contractPlugins.filter(has)\n if (registered.length === 1) {\n return { kind: 'contract', pluginName: registered[0]! }\n }\n if (registered.length > 1) {\n return {\n kind: 'error',\n message: `Multiple client plugins are registered (${registered.map((name) => `\\`@kubb/${name}\\``).join(', ')}). Set \\`client: 'fetch' | 'axios'\\` to choose which client the hooks call, or register a single client plugin.`,\n }\n }\n\n return {\n kind: 'error',\n message: 'No client plugin is registered. Add `@kubb/plugin-axios` or `@kubb/plugin-fetch` to `plugins` so the generated code has an HTTP client to call.',\n }\n}\n\n/**\n * Resolves the contract client during a consumer plugin's setup hook. Extracts the plugin names\n * from the raw `plugins` config, applies {@link resolveClient}, and throws the diagnostic on a\n * misconfiguration so every consumer fails fast with the same message.\n */\nexport function resolveContractClient(options: { client: ClientSelector | undefined; plugins?: ReadonlyArray<unknown> }): ResolvedContractClient {\n const { client, plugins = [] } = options\n const pluginNames = plugins.map((plugin) => (plugin as { name?: string }).name).filter((name): name is string => Boolean(name))\n const resolved = resolveClient({ client, pluginNames })\n if (resolved.kind === 'error') {\n throw new Error(resolved.message)\n }\n return resolved\n}\n","import path from 'node:path'\nimport { operationFileEntry } from '@internals/shared'\nimport type { ast, Exclude, Group, Include, NodeCache, Output, Override, Resolver } from 'kubb/kit'\n\n/**\n * The resolved contract `<op>` for one operation: the generated function name, the file it lives in,\n * the contract runtime's `.kubb/client.ts` path (where `RequestConfig` / `ResponseErrorConfig`\n * come from), and the registered client plugin's `returnType`.\n */\nexport type ClientOperation = { name: string; path: string; clientPath: string; returnType: 'full' | 'data' }\n\n/**\n * The client plugin options a dependent reads, including the filters that scope them per operation.\n */\ntype ClientPluginOptions = {\n output?: Output\n group?: Group | null\n returnType?: 'full' | 'data'\n exclude?: Array<Exclude>\n include?: Array<Include>\n override?: Array<Override<Omit<ClientPluginOptions, 'override'>>>\n}\n\n/**\n * Resolves the contract client `<op>` a consumer (query hook, MCP handler) imports, by looking up\n * the registered contract client plugin's resolver and output. Works for any contract client plugin\n * (plugin-fetch or plugin-axios). Returns `null` when no contract plugin is in play (the inline\n * path), or when the client plugin's `exclude` / `include` leaves this operation out, since it then\n * emits no `<op>` to import. The plugin injects `.kubb/client.ts` at the global output root, the\n * same path consumers read `RequestConfig` / `ResponseErrorConfig` from.\n *\n * The result is cached in the current node's `cache` (`ctx.cache`) under the client plugin's name,\n * so several dependents reading the same client plugin for one operation in a single pass\n * (react-query's query/mutation/infinite generators, vue-query, swr, the MCP handler, ...) share\n * one computed result instead of each re-deriving the name and path.\n *\n * `returnType`, `output`, and `group` are the client plugin's options for this operation, after its\n * `override` entries, the same resolution its own generator sees. A dependent's generated call body\n * and import path therefore match the `<op>` actually emitted, even when an `override` changes it.\n */\nexport function resolveClientOperation(options: {\n clientPlugin: { pluginName: string } | null\n driver: {\n getPlugin: (name: string) => { options?: ClientPluginOptions } | undefined\n getResolver: (name: string) => Resolver\n }\n node: ast.OperationNode\n root: string\n output: Output\n cache: NodeCache\n}): ClientOperation | null {\n const { clientPlugin, driver, node, root, output, cache } = options\n if (!clientPlugin) return null\n\n return cache.ensureItem(`${clientPlugin.pluginName}:clientOperation`, () => {\n const resolver = driver.getResolver(clientPlugin.pluginName)\n const pluginOptions = driver.getPlugin(clientPlugin.pluginName)?.options ?? {}\n const { exclude, include, override } = pluginOptions\n const hasOperationOptions = Boolean(exclude?.length || include?.length || override?.length)\n // Kubb's resolver always has `default`; the fallback keeps partial or custom resolvers working.\n const operationOptions =\n hasOperationOptions && resolver.default ? resolver.default.options(node, { options: pluginOptions, exclude, include, override }) : pluginOptions\n if (!operationOptions) return null\n\n const file = resolver.file({\n ...operationFileEntry(node, node.operationId),\n root,\n output: operationOptions.output ?? output,\n group: operationOptions.group ?? undefined,\n })\n\n return {\n name: resolver.name(node.operationId),\n path: file.path,\n clientPath: path.resolve(root, '.kubb/client.ts'),\n returnType: operationOptions.returnType ?? 'full',\n }\n })\n}\n","import { resolveClientOperation } from '@internals/client'\nimport { resolveDependencyOperationFile } from '@internals/shared'\nimport { ast, defineGenerator } from 'kubb/kit'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { File, jsxRenderer } from 'kubb/jsx'\nimport { McpHandler } from '../components/McpHandler.tsx'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Built-in operation generator for `@kubb/plugin-mcp`. Emits one MCP tool\n * handler per OpenAPI operation. The handler takes the grouped `{ path, query,\n * headers, body }` config and forwards it to the registered client plugin's\n * (`@kubb/plugin-axios` / `@kubb/plugin-fetch`) `<op>` function.\n */\nexport const mcpGenerator = defineGenerator<PluginMcp>({\n name: 'mcp',\n renderer: jsxRenderer,\n operation(node, ctx) {\n if (!ast.isHttpOperationNode(node)) return null\n const { resolver, driver, root, config } = ctx\n const { output, client, group } = ctx.options\n\n const pluginTs = ctx.requirePlugin(pluginTsName)\n\n const tsResolver = driver.getResolver(pluginTsName)\n\n // The registered contract client plugin owns the `<op>` the handler imports and calls.\n const contractOp = resolveClientOperation({ clientPlugin: { pluginName: client.pluginName }, driver, node, root, output, cache: ctx.cache })\n if (!contractOp) {\n return null\n }\n\n // The handler signature references the grouped `<Name>Options`.\n const optionsName = tsResolver.response.options(node)\n\n const meta = {\n name: resolver.handler.name(node),\n file: resolver.file({ name: node.operationId, extname: '.ts', tag: node.tags[0] ?? 'default', path: node.path, root, output, group: group ?? undefined }),\n fileTs: resolveDependencyOperationFile({\n cache: ctx.cache,\n node,\n resolver: tsResolver,\n root,\n output: pluginTs.options?.output ?? output,\n group: pluginTs.options?.group,\n }),\n } as const\n\n return (\n <File\n baseName={meta.file.baseName}\n path={meta.file.path}\n meta={meta.file.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: meta.file.path, baseName: meta.file.baseName } })}\n >\n {meta.fileTs && optionsName && <File.Import name={[optionsName]} root={meta.file.path} path={meta.fileTs.path} isTypeOnly />}\n <File.Import name={['CallToolResult', 'ServerNotification', 'ServerRequest']} path={'@modelcontextprotocol/sdk/types.js'} isTypeOnly />\n <File.Import name={['RequestHandlerExtra']} path={'@modelcontextprotocol/sdk/shared/protocol.js'} isTypeOnly />\n\n <File.Import name={[contractOp.name]} root={meta.file.path} path={contractOp.path} />\n\n <McpHandler name={meta.name} clientName={contractOp.name} node={node} resolver={tsResolver} returnType={contractOp.returnType} />\n </File>\n )\n },\n})\n","import path from 'node:path'\nimport { findSuccessStatusCode, getOperationParameters } from '@internals/shared'\nimport { ast, defineGenerator } from 'kubb/kit'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { File, jsxRenderer } from 'kubb/jsx'\nimport { Server } from '../components/Server.tsx'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Default v5 server generator for `@kubb/plugin-mcp`.\n *\n * Uses individual zod schemas for each param (e.g. `createPetsPathUuidSchema`, `createPetsQueryOffsetSchema`)\n * and `resolveResponseStatusName` for per-status response schemas.\n * Query and header params are composed into `z.object({ ... })` from individual schemas.\n */\nexport const serverGenerator = defineGenerator<PluginMcp>({\n name: 'operations',\n renderer: jsxRenderer,\n operations(nodes, ctx) {\n const { config, resolver, plugin, driver, root } = ctx\n const { output, group } = ctx.options\n\n const pluginZod = ctx.requirePlugin(pluginZodName)\n\n const zodResolver = driver.getResolver(pluginZodName)\n\n const name = 'server'\n const serverFilePath = path.resolve(root, output.path, 'server.ts')\n const serverFile = {\n baseName: 'server.ts' as const,\n path: serverFilePath,\n meta: { pluginName: plugin.name },\n }\n\n const jsonFilePath = path.resolve(root, output.path, '.mcp.json')\n const jsonFile = {\n baseName: '.mcp.json' as const,\n path: jsonFilePath,\n meta: { pluginName: plugin.name },\n }\n\n const operationsMapped = nodes.filter(ast.isHttpOperationNode).map((node) => {\n const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node)\n\n const mcpFile = resolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output,\n group: group ?? undefined,\n })\n\n const zodFile = zodResolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output: pluginZod.options?.output ?? output,\n group: pluginZod.options?.group ?? undefined,\n })\n\n const requestName = node.requestBody?.content?.[0]?.schema ? zodResolver.response.body(node) : null\n const successStatus = findSuccessStatusCode(node.responses)\n const responseName = successStatus ? zodResolver.response.status(node, successStatus) : null\n\n const resolveParams = (params: typeof pathParams) => params.map((p) => ({ name: p.name, schemaName: zodResolver.param.name(node, p) }))\n\n return {\n tool: {\n name: node.operationId,\n title: node.summary || undefined,\n description: node.description || `Make a ${node.method.toUpperCase()} request to ${node.path}`,\n },\n mcp: {\n name: resolver.handler.name(node),\n file: mcpFile,\n },\n zod: {\n pathParams: resolveParams(pathParams),\n queryParams: queryParams.length ? resolveParams(queryParams) : null,\n headerParams: headerParams.length ? resolveParams(headerParams) : null,\n requestName,\n responseName,\n file: zodFile,\n },\n node: node,\n }\n })\n\n const imports = operationsMapped.flatMap(({ mcp, zod }) => {\n const zodNames = [\n ...zod.pathParams.map((p) => p.schemaName),\n ...(zod.queryParams ?? []).map((p) => p.schemaName),\n ...(zod.headerParams ?? []).map((p) => p.schemaName),\n zod.requestName,\n zod.responseName,\n ].filter((name): name is string => Boolean(name))\n\n const uniqueNames = [...new Set(zodNames)].sort()\n\n return [\n <File.Import key={mcp.name} name={[mcp.name]} root={serverFile.path} path={mcp.file.path} />,\n uniqueNames.length > 0 && <File.Import key={`zod-${mcp.name}`} name={uniqueNames} root={serverFile.path} path={zod.file.path} />,\n ].filter(Boolean)\n })\n\n return (\n <>\n <File\n baseName={serverFile.baseName}\n path={serverFile.path}\n meta={serverFile.meta}\n banner={resolver.default.banner(ctx.meta, { output, config, file: { path: serverFile.path, baseName: serverFile.baseName } })}\n footer={resolver.default.footer(ctx.meta, { output, config, file: { path: serverFile.path, baseName: serverFile.baseName } })}\n >\n <File.Import name={['McpServer']} path={'@modelcontextprotocol/sdk/server/mcp.js'} />\n <File.Import name={['z']} path={'zod'} />\n <File.Import name={['StdioServerTransport']} path={'@modelcontextprotocol/sdk/server/stdio.js'} />\n\n {imports}\n <Server name={name} serverName={ctx.meta.title ?? 'server'} serverVersion={ctx.meta.version ?? '0.0.0'} operations={operationsMapped} />\n </File>\n\n <File baseName={jsonFile.baseName} path={jsonFile.path} meta={jsonFile.meta}>\n <File.Source name={name}>\n {`\n {\n \"mcpServers\": {\n \"${ctx.meta.title || 'server'}\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\"tsx\", \"${path.relative(path.dirname(jsonFile.path), serverFile.path)}\"]\n }\n }\n }\n `}\n </File.Source>\n </File>\n </>\n )\n },\n})\n","import { camelCase } from '@internals/utils'\nimport { createResolver } from 'kubb/kit'\nimport type { PluginMcp } from '../types.ts'\n\n/**\n * Default resolver used by `@kubb/plugin-mcp`. Decides the names and file\n * paths for every generated MCP tool handler. Function names get a `Handler`\n * suffix so an operation `addPet` becomes `addPetHandler`.\n *\n * @example Resolve a handler name\n * ```ts\n * import { resolverMcp } from '@kubb/plugin-mcp'\n *\n * resolverMcp.name('addPet') // 'addPetHandler'\n * ```\n */\nexport const resolverMcp = createResolver<PluginMcp>({\n pluginName: 'plugin-mcp',\n name(name) {\n return camelCase(name, { suffix: 'handler' })\n },\n handler: {\n name(node) {\n return this.name(node.operationId)\n },\n },\n})\n","import { createGroupConfig } from '@internals/shared'\n\nimport { resolveContractClient } from '@internals/client'\nimport { definePlugin, Resolver } from 'kubb/kit'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { mcpGenerator } from './generators/mcpGenerator.tsx'\nimport { serverGenerator } from './generators/serverGenerator.tsx'\nimport { resolverMcp } from './resolvers/resolverMcp.ts'\nimport type { PluginMcp, ResolverMcp } from './types.ts'\n\n/**\n * Canonical plugin name for `@kubb/plugin-mcp`. Used for driver lookups and\n * cross-plugin dependency references.\n */\nexport const pluginMcpName = 'plugin-mcp' satisfies PluginMcp['name']\n\n/**\n * Generates a Model Context Protocol (MCP) server from an OpenAPI spec. Every\n * operation becomes a typed MCP tool that AI assistants (Claude Desktop, Claude\n * Code, MCP-compatible clients) can call directly. Each handler calls a contract\n * client `<op>` from a registered `@kubb/plugin-axios` or `@kubb/plugin-fetch`.\n *\n * @example\n * ```ts\n * import { defineConfig } from 'kubb/config'\n * import { pluginTs } from '@kubb/plugin-ts'\n * import { pluginZod } from '@kubb/plugin-zod'\n * import { pluginMcp } from '@kubb/plugin-mcp'\n *\n * export default defineConfig({\n * input: './petStore.yaml',\n * output: { path: './src/gen' },\n * plugins: [\n * pluginTs(),\n * pluginZod(),\n * pluginMcp({\n * output: { path: './mcp' },\n * baseURL: 'https://petstore.swagger.io/v2',\n * }),\n * ],\n * })\n * ```\n */\nexport const pluginMcp = definePlugin<PluginMcp>((options) => {\n const {\n output = { path: 'mcp', barrel: { type: 'named' } },\n group,\n exclude = [],\n include,\n override = [],\n client,\n resolver: userResolver,\n macros: userMacros,\n } = options\n\n const groupConfig = createGroupConfig(group)\n\n return {\n name: pluginMcpName,\n options,\n dependencies: [pluginTsName, pluginZodName],\n hooks: {\n 'kubb:plugin:setup'(ctx) {\n ctx.requirePlugin(pluginTsName)\n ctx.requirePlugin(pluginZodName)\n\n const resolver = userResolver ? Resolver.merge<ResolverMcp>(resolverMcp, userResolver) : resolverMcp\n\n ctx.setOptions({\n output,\n exclude,\n include,\n override,\n group: groupConfig,\n client: resolveContractClient({ client, plugins: ctx.config.plugins }),\n resolver,\n })\n ctx.setResolver(resolver)\n if (userMacros?.length) {\n ctx.setMacros(userMacros)\n }\n ctx.addGenerator(mcpGenerator, serverGenerator)\n },\n },\n }\n})\n\nexport default pluginMcp\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubb/plugin-mcp",
3
- "version": "5.0.7",
3
+ "version": "5.0.9",
4
4
  "description": "Generate Model Context Protocol (MCP) tool definitions with Kubb. Expose your REST APIs as AI-callable tools for LLMs, Claude, ChatGPT, and other AI assistants.",
5
5
  "keywords": [
6
6
  "ai",
@@ -60,20 +60,20 @@
60
60
  "registry": "https://registry.npmjs.org/"
61
61
  },
62
62
  "dependencies": {
63
- "@kubb/plugin-ts": "^5.0.3",
64
- "@kubb/plugin-zod": "^5.4.2"
63
+ "@kubb/plugin-ts": "^5.0.6",
64
+ "@kubb/plugin-zod": "^5.4.4"
65
65
  },
66
66
  "devDependencies": {
67
67
  "@internals/client": "0.0.0",
68
68
  "@internals/shared": "0.0.0",
69
69
  "@internals/utils": "0.0.0",
70
- "@modelcontextprotocol/sdk": "^1.30.1",
71
- "kubb": "^5.4.2",
70
+ "@modelcontextprotocol/sdk": "^1.32.1",
71
+ "kubb": "^5.6.3",
72
72
  "zod": "^4.6.5"
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@modelcontextprotocol/sdk": "^1.0.0",
76
- "kubb": "^5.4.2",
76
+ "kubb": "^5.6.3",
77
77
  "zod": "^4.0.0"
78
78
  },
79
79
  "peerDependenciesMeta": {
@@ -90,10 +90,7 @@
90
90
  "scripts": {
91
91
  "build": "tsdown",
92
92
  "clean": "node -e \"require('node:fs').rmSync('./dist', {recursive:true,force:true})\"",
93
- "lint": "oxlint .",
94
- "lint:fix": "oxlint --fix .",
95
93
  "start": "tsdown --watch",
96
- "test": "vitest --passWithNoTests",
97
- "typecheck": "tsc -p ./tsconfig.json --noEmit --emitDeclarationOnly false"
94
+ "typecheck": "tsc"
98
95
  }
99
96
  }