@kubb/plugin-mcp 5.0.0-alpha.9 → 5.0.0-beta.100

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["mcpGenerator","serverGenerator","pluginOasName","pluginTsName","pluginZodName","path","camelCase","pluginClientName","fetchClientSource","axiosClientSource","configSource","OperationGenerator"],"sources":["../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { camelCase } from '@internals/utils'\nimport { createPlugin, type Group, getBarrelFiles, getMode } from '@kubb/core'\nimport { pluginClientName } from '@kubb/plugin-client'\nimport { source as axiosClientSource } from '@kubb/plugin-client/templates/clients/axios.source'\nimport { source as fetchClientSource } from '@kubb/plugin-client/templates/clients/fetch.source'\nimport { source as configSource } from '@kubb/plugin-client/templates/config.source'\nimport { OperationGenerator, pluginOasName } from '@kubb/plugin-oas'\nimport { pluginTsName } from '@kubb/plugin-ts'\nimport { pluginZodName } from '@kubb/plugin-zod'\nimport { mcpGenerator, serverGenerator } from './generators'\nimport type { PluginMcp } from './types.ts'\n\nexport const pluginMcpName = 'plugin-mcp' satisfies PluginMcp['name']\n\nexport const pluginMcp = createPlugin<PluginMcp>((options) => {\n const {\n output = { path: 'mcp', barrelType: 'named' },\n group,\n exclude = [],\n include,\n override = [],\n transformers = {},\n generators = [mcpGenerator, serverGenerator].filter(Boolean),\n contentType,\n paramsCasing,\n client,\n } = options\n\n const clientName = client?.client ?? 'axios'\n const clientImportPath = client?.importPath ?? (!client?.bundle ? `@kubb/plugin-client/clients/${clientName}` : undefined)\n\n return {\n name: pluginMcpName,\n options: {\n output,\n group,\n paramsCasing,\n client: {\n client: clientName,\n clientType: client?.clientType ?? 'function',\n importPath: clientImportPath,\n dataReturnType: client?.dataReturnType ?? 'data',\n bundle: client?.bundle,\n baseURL: client?.baseURL,\n paramsCasing: client?.paramsCasing,\n },\n },\n pre: [pluginOasName, pluginTsName, pluginZodName].filter(Boolean),\n resolvePath(baseName, pathMode, options) {\n const root = path.resolve(this.config.root, this.config.output.path)\n const mode = pathMode ?? getMode(path.resolve(root, output.path))\n\n if (mode === 'single') {\n /**\n * when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend\n * Other plugins then need to call addOrAppend instead of just add from the fileManager class\n */\n return path.resolve(root, output.path)\n }\n\n if (group && (options?.group?.path || options?.group?.tag)) {\n const groupName: Group['name'] = group?.name\n ? group.name\n : (ctx) => {\n if (group?.type === 'path') {\n return `${ctx.group.split('/')[1]}`\n }\n return `${camelCase(ctx.group)}Requests`\n }\n\n return path.resolve(\n root,\n output.path,\n groupName({\n group: group.type === 'path' ? options.group.path! : options.group.tag!,\n }),\n baseName,\n )\n }\n\n return path.resolve(root, output.path, baseName)\n },\n resolveName(name, type) {\n const resolvedName = camelCase(name, {\n isFile: type === 'file',\n })\n\n if (type) {\n return transformers?.name?.(resolvedName, type) || resolvedName\n }\n\n return resolvedName\n },\n async install() {\n const root = path.resolve(this.config.root, this.config.output.path)\n const mode = getMode(path.resolve(root, output.path))\n const oas = await this.getOas()\n const baseURL = await this.getBaseURL()\n\n if (baseURL) {\n this.plugin.options.client.baseURL = baseURL\n }\n\n const hasClientPlugin = !!this.driver.getPluginByName(pluginClientName)\n\n if (this.plugin.options.client.bundle && !hasClientPlugin && !this.plugin.options.client.importPath) {\n // pre add bundled fetch\n await this.addFile({\n baseName: 'fetch.ts',\n path: path.resolve(root, '.kubb/fetch.ts'),\n sources: [\n {\n name: 'fetch',\n value: this.plugin.options.client.client === 'fetch' ? fetchClientSource : axiosClientSource,\n isExportable: true,\n isIndexable: true,\n },\n ],\n imports: [],\n exports: [],\n })\n }\n\n if (!hasClientPlugin) {\n await this.addFile({\n baseName: 'config.ts',\n path: path.resolve(root, '.kubb/config.ts'),\n sources: [\n {\n name: 'config',\n value: configSource,\n isExportable: false,\n isIndexable: false,\n },\n ],\n imports: [],\n exports: [],\n })\n }\n\n const operationGenerator = new OperationGenerator(this.plugin.options, {\n fabric: this.fabric,\n oas,\n driver: this.driver,\n events: this.events,\n plugin: this.plugin,\n contentType,\n exclude,\n include,\n override,\n mode,\n })\n\n const files = await operationGenerator.build(...generators)\n await this.upsertFile(...files)\n\n const barrelFiles = await getBarrelFiles(this.fabric.files, {\n type: output.barrelType ?? 'named',\n root,\n output,\n meta: {\n pluginName: this.plugin.name,\n },\n })\n\n await this.upsertFile(...barrelFiles)\n },\n }\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["Url","ast","File","Function","File","Function","Const","path","jsxRenderer","ast","pluginTsName","File","jsxRenderer","pluginZodName","path","ast","File","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 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\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\nexport function getOperationParameters(node: ast.OperationNode): OperationParameterGroups {\n return {\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\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\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\nconst requestGroupOrder = ['path', 'query', 'headers', 'body'] as const\n\nexport function McpHandler({ name, clientName, node, resolver }: 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 same grouped config the contract `<op>` expects, so MCP behaves like every other\n // client consumer instead of re-implementing request building. The `<op>` always takes one\n // required options object, so a param-less operation still passes an empty `{}`.\n const callArgs = requestGroupOrder.filter((key) => groups[key])\n const callConfig = callArgs.length ? `{ ${callArgs.join(', ')} }` : '{}'\n\n const callToolResult = `return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(res.data)\n }\n ],\n structuredContent: { data: res.data }\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={'Promise<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, Group, Output, Resolver } from 'kubb/kit'\n\n/**\n * The resolved contract `<op>` for one operation: the generated function name, the file it lives in,\n * and the contract runtime's `.kubb/client.ts` path (where `RequestConfig` / `ResponseErrorConfig`\n * come from).\n */\nexport type ClientOperation = { name: string; path: string; clientPath: string }\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). The plugin injects `.kubb/client.ts` at the global output root, the same path consumers\n * read `RequestConfig` / `ResponseErrorConfig` from.\n */\nexport function resolveClientOperation(options: {\n clientPlugin: { pluginName: string } | null\n driver: {\n getPlugin: (name: string) => { options?: { output?: Output; group?: Group | null } } | undefined\n getResolver: (name: string) => Resolver\n }\n node: ast.OperationNode\n root: string\n output: Output\n}): ClientOperation | null {\n const { clientPlugin, driver, node, root, output } = options\n if (!clientPlugin) return null\n\n const resolver = driver.getResolver(clientPlugin.pluginName)\n const plugin = driver.getPlugin(clientPlugin.pluginName)\n const file = resolver.file({\n ...operationFileEntry(node, node.operationId),\n root,\n output: plugin?.options?.output ?? output,\n group: plugin?.options?.group ?? undefined,\n })\n\n return { name: resolver.name(node.operationId), path: file.path, clientPath: path.resolve(root, '.kubb/client.ts') }\n}\n","import { resolveClientOperation } from '@internals/client'\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 } = 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 })\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: tsResolver.file({\n name: node.operationId,\n extname: '.ts',\n tag: node.tags[0] ?? 'default',\n path: node.path,\n root,\n output: pluginTs.options?.output ?? output,\n group: pluginTs.options?.group ?? undefined,\n }),\n } as const\n\n return (\n <File baseName={meta.file.baseName} path={meta.file.path} meta={meta.file.meta}>\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'} isTypeOnly />\n <File.Import name={['RequestHandlerExtra']} path={'@modelcontextprotocol/sdk/shared/protocol'} 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} />\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'} />\n <File.Import name={['z']} path={'zod'} />\n <File.Import name={['StdioServerTransport']} path={'@modelcontextprotocol/sdk/server/stdio'} />\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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"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,258 @@
1
- import { t as __name } from "./chunk--u3MIqq1.js";
2
- import { n as PluginMcp, t as Options } from "./types-DXZDZ3vf.js";
3
- import * as _kubb_core0 from "@kubb/core";
4
-
1
+ import { t as __name } from "./rolldown-runtime-C0LytTxp.js";
2
+ import { Exclude, Group, Include, Output, OutputOptions, Override, PluginFactoryOptions, Resolver, ResolverPatch, ast } from "kubb/kit";
3
+ import { KubbReactNode } from "kubb/jsx";
4
+ import { ResolverTs } from "@kubb/plugin-ts";
5
+ import "@kubb/plugin-zod";
6
+ //#region src/components/McpHandler.d.ts
7
+ type Props$1 = {
8
+ /**
9
+ * Name of the handler function.
10
+ */
11
+ name: string;
12
+ /**
13
+ * Name of the contract client `<op>` the handler calls.
14
+ */
15
+ clientName: string;
16
+ /**
17
+ * AST operation node.
18
+ */
19
+ node: ast.OperationNode;
20
+ /**
21
+ * TypeScript resolver for resolving param/data/response type names.
22
+ */
23
+ resolver: ResolverTs;
24
+ };
25
+ declare function McpHandler({ name, clientName, node, resolver }: Props$1): KubbReactNode;
26
+ //#endregion
27
+ //#region src/utils.d.ts
28
+ type ZodParam = {
29
+ name: string;
30
+ schemaName: string;
31
+ };
32
+ //#endregion
33
+ //#region src/components/Server.d.ts
34
+ type Props = {
35
+ /**
36
+ * Variable name for the MCP server instance (e.g. 'server').
37
+ */
38
+ name: string;
39
+ /**
40
+ * Human-readable server name passed to `new McpServer({ name })`.
41
+ */
42
+ serverName: string;
43
+ /**
44
+ * Semantic version string passed to `new McpServer({ version })`.
45
+ */
46
+ serverVersion: string;
47
+ /**
48
+ * Operations to register as MCP tools, each carrying its handler,
49
+ * zod schema, and AST node metadata.
50
+ */
51
+ operations: Array<{
52
+ tool: {
53
+ name: string;
54
+ title?: string;
55
+ description: string;
56
+ };
57
+ mcp: {
58
+ name: string;
59
+ file: ast.FileNode;
60
+ };
61
+ zod: {
62
+ pathParams: Array<ZodParam>;
63
+ /**
64
+ * Query params — individual schemas to compose into `z.object({ ... })`.
65
+ */
66
+ queryParams?: string | Array<ZodParam> | null;
67
+ /**
68
+ * Header params — individual schemas to compose into `z.object({ ... })`.
69
+ */
70
+ headerParams?: string | Array<ZodParam> | null;
71
+ requestName?: string | null;
72
+ responseName?: string | null;
73
+ };
74
+ node: ast.OperationNode;
75
+ }>;
76
+ };
77
+ declare function Server({ name, serverName, serverVersion, operations }: Props): KubbReactNode;
78
+ //#endregion
79
+ //#region ../../internals/client/src/resolveClient.d.ts
80
+ /**
81
+ * Resolves which client plugin a consumer (react-query, vue-query, swr, mcp) should call for an
82
+ * operation, shared so the selection rules and diagnostics stay in one place.
83
+ *
84
+ * Every client runtime lives in a dedicated client plugin, so a consumer always calls a registered
85
+ * contract client plugin (plugin-fetch or plugin-axios) and never emits its own inline client:
86
+ *
87
+ * - `contract` — a registered contract client plugin owns the `<op>` functions and the consumer
88
+ * imports and calls them.
89
+ * - `error` — no client plugin is registered, several are registered without a selector, or the
90
+ * requested one is missing.
91
+ *
92
+ * The `client` string selects explicitly (`'fetch'` / `'axios'`); when it is unset a lone registered
93
+ * contract client plugin is picked up automatically.
94
+ */
95
+ /**
96
+ * The client selector accepted by a consumer's `client` option. Both call a registered contract
97
+ * client plugin.
98
+ */
99
+ type ClientSelector = 'fetch' | 'axios';
100
+ //#endregion
101
+ //#region src/types.d.ts
102
+ /**
103
+ * Resolver for MCP that provides naming methods for handler functions.
104
+ */
105
+ type ResolverMcp = Resolver & {
106
+ /**
107
+ * Naming for the generated MCP tool handler functions.
108
+ */
109
+ handler: {
110
+ /**
111
+ * Resolves the handler function name for an operation.
112
+ *
113
+ * @example Resolving handler function names
114
+ * `resolver.handler.name(operationNode) // -> 'showPetByIdHandler'`
115
+ */
116
+ name(node: ast.OperationNode): string;
117
+ };
118
+ };
119
+ /**
120
+ * Where the generated MCP tool handlers are written and how they are exported, plus the optional
121
+ * `group` strategy. The `group` option organizes `output.mode: 'directory'` output into per-tag or per-path subdirectories.
122
+ *
123
+ * @default { path: 'mcp', barrel: { type: 'named' } }
124
+ */
125
+ type Options = OutputOptions & {
126
+ /**
127
+ * Selects the HTTP client each MCP handler calls. Every client plugin speaks the `RequestResult`
128
+ * contract, so each handler calls a contract `<op>` that takes one grouped `{ path, query, headers,
129
+ * body }` object.
130
+ *
131
+ * `'fetch'` / `'axios'` calls the `@kubb/plugin-fetch` / `@kubb/plugin-axios` functions. When a
132
+ * single client plugin (plugin-fetch or plugin-axios) is registered it is auto-detected, so the
133
+ * string is only needed to disambiguate several client plugins. Register one of those plugins.
134
+ * Options such as `baseURL` live there.
135
+ */
136
+ client?: ClientSelector;
137
+ /**
138
+ * Skip operations matching at least one entry in the list.
139
+ */
140
+ exclude?: Array<Exclude>;
141
+ /**
142
+ * Restrict generation to operations matching at least one entry in the list.
143
+ */
144
+ include?: Array<Include>;
145
+ /**
146
+ * Apply a different options object to operations matching a pattern.
147
+ */
148
+ override?: Array<Override<ResolvedOptions>>;
149
+ /**
150
+ * Override how handler names and file paths are built. Methods you omit fall
151
+ * back to the default `resolverMcp`.
152
+ */
153
+ resolver?: ResolverPatch<ResolverMcp>;
154
+ /**
155
+ * Macros applied to each operation node before printing.
156
+ */
157
+ macros?: Array<ast.Macro>;
158
+ };
159
+ /**
160
+ * The resolved client strategy for the generated handlers, computed once during setup. The handlers
161
+ * always import and call a registered contract client plugin's `<op>`.
162
+ */
163
+ type ResolvedClient = {
164
+ kind: 'contract';
165
+ pluginName: string;
166
+ };
167
+ type ResolvedOptions = {
168
+ output: Output;
169
+ exclude: Array<Exclude>;
170
+ include: Array<Include> | undefined;
171
+ override: Array<Override<ResolvedOptions>>;
172
+ group: Group | null;
173
+ /**
174
+ * The resolved client strategy the generators branch on.
175
+ */
176
+ client: ResolvedClient;
177
+ resolver: ResolverMcp;
178
+ };
179
+ type PluginMcp = PluginFactoryOptions<'plugin-mcp', Options, ResolvedOptions, ResolverMcp>;
180
+ declare global {
181
+ namespace Kubb {
182
+ interface PluginRegistry {
183
+ 'plugin-mcp': PluginMcp;
184
+ }
185
+ }
186
+ }
187
+ //#endregion
188
+ //#region src/generators/mcpGenerator.d.ts
189
+ /**
190
+ * Built-in operation generator for `@kubb/plugin-mcp`. Emits one MCP tool
191
+ * handler per OpenAPI operation. The handler takes the grouped `{ path, query,
192
+ * headers, body }` config and forwards it to the registered client plugin's
193
+ * (`@kubb/plugin-axios` / `@kubb/plugin-fetch`) `<op>` function.
194
+ */
195
+ declare const mcpGenerator: import("kubb/kit").Generator<PluginMcp, unknown>;
196
+ //#endregion
197
+ //#region src/generators/serverGenerator.d.ts
198
+ /**
199
+ * Default v5 server generator for `@kubb/plugin-mcp`.
200
+ *
201
+ * Uses individual zod schemas for each param (e.g. `createPetsPathUuidSchema`, `createPetsQueryOffsetSchema`)
202
+ * and `resolveResponseStatusName` for per-status response schemas.
203
+ * Query and header params are composed into `z.object({ ... })` from individual schemas.
204
+ */
205
+ declare const serverGenerator: import("kubb/kit").Generator<PluginMcp, unknown>;
206
+ //#endregion
5
207
  //#region src/plugin.d.ts
208
+ /**
209
+ * Canonical plugin name for `@kubb/plugin-mcp`. Used for driver lookups and
210
+ * cross-plugin dependency references.
211
+ */
6
212
  declare const pluginMcpName = "plugin-mcp";
7
- declare const pluginMcp: (options?: Options | undefined) => _kubb_core0.UserPluginWithLifeCycle<PluginMcp>;
213
+ /**
214
+ * Generates a Model Context Protocol (MCP) server from an OpenAPI spec. Every
215
+ * operation becomes a typed MCP tool that AI assistants (Claude Desktop, Claude
216
+ * Code, MCP-compatible clients) can call directly. Each handler calls a contract
217
+ * client `<op>` from a registered `@kubb/plugin-axios` or `@kubb/plugin-fetch`.
218
+ *
219
+ * @example
220
+ * ```ts
221
+ * import { defineConfig } from 'kubb/config'
222
+ * import { pluginTs } from '@kubb/plugin-ts'
223
+ * import { pluginZod } from '@kubb/plugin-zod'
224
+ * import { pluginMcp } from '@kubb/plugin-mcp'
225
+ *
226
+ * export default defineConfig({
227
+ * input: './petStore.yaml',
228
+ * output: { path: './src/gen' },
229
+ * plugins: [
230
+ * pluginTs(),
231
+ * pluginZod(),
232
+ * pluginMcp({
233
+ * output: { path: './mcp' },
234
+ * baseURL: 'https://petstore.swagger.io/v2',
235
+ * }),
236
+ * ],
237
+ * })
238
+ * ```
239
+ */
240
+ declare const pluginMcp: (options?: Options | undefined) => import("kubb/kit").Plugin<PluginMcp>;
241
+ //#endregion
242
+ //#region src/resolvers/resolverMcp.d.ts
243
+ /**
244
+ * Default resolver used by `@kubb/plugin-mcp`. Decides the names and file
245
+ * paths for every generated MCP tool handler. Function names get a `Handler`
246
+ * suffix so an operation `addPet` becomes `addPetHandler`.
247
+ *
248
+ * @example Resolve a handler name
249
+ * ```ts
250
+ * import { resolverMcp } from '@kubb/plugin-mcp'
251
+ *
252
+ * resolverMcp.name('addPet') // 'addPetHandler'
253
+ * ```
254
+ */
255
+ declare const resolverMcp: ResolverMcp;
8
256
  //#endregion
9
- export { type PluginMcp, pluginMcp, pluginMcpName };
257
+ export { McpHandler, type PluginMcp, type ResolverMcp, Server, pluginMcp as default, pluginMcp, mcpGenerator, pluginMcpName, resolverMcp, serverGenerator };
10
258
  //# sourceMappingURL=index.d.ts.map