@kubb/plugin-mcp 5.0.0-alpha.33 → 5.0.0-alpha.35
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/dist/index.cjs +71 -104
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -11
- package/dist/index.js +69 -103
- package/dist/index.js.map +1 -1
- package/package.json +7 -8
- package/src/components/McpHandler.tsx +4 -5
- package/src/components/Server.tsx +7 -8
- package/src/generators/mcpGenerator.tsx +8 -7
- package/src/generators/serverGenerator.tsx +8 -7
- package/src/generators/serverGeneratorLegacy.tsx +8 -7
- package/src/plugin.ts +70 -95
- package/src/types.ts +2 -2
- package/src/utils.ts +21 -5
- package/src/presets.ts +0 -25
package/dist/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import "./chunk--u3MIqq1.js";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { ast, defineGenerator, definePlugin, defineResolver } from "@kubb/core";
|
|
4
4
|
import { functionPrinter, pluginTsName } from "@kubb/plugin-ts";
|
|
5
|
-
import { Const, File, Function as Function$1 } from "@kubb/renderer-jsx";
|
|
5
|
+
import { Const, File, Function as Function$1, jsxRenderer } from "@kubb/renderer-jsx";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "@kubb/renderer-jsx/jsx-runtime";
|
|
7
|
-
import { createPlugin, defineGenerator, definePresets, defineResolver, getPreset, mergeGenerators } from "@kubb/core";
|
|
8
7
|
import { pluginZodName } from "@kubb/plugin-zod";
|
|
9
8
|
import { pluginClientName } from "@kubb/plugin-client";
|
|
10
9
|
import { source } from "@kubb/plugin-client/templates/clients/axios.source";
|
|
@@ -270,6 +269,15 @@ function getParamsMapping(params) {
|
|
|
270
269
|
function zodExprFromSchemaNode(schema) {
|
|
271
270
|
let expr;
|
|
272
271
|
switch (schema.type) {
|
|
272
|
+
case "enum": {
|
|
273
|
+
const rawValues = schema.namedEnumValues?.length ? schema.namedEnumValues.map((v) => v.value) : (schema.enumValues ?? []).filter((v) => v !== null);
|
|
274
|
+
if (rawValues.length > 0 && rawValues.every((v) => typeof v === "string")) expr = `z.enum([${rawValues.map((v) => JSON.stringify(v)).join(", ")}])`;
|
|
275
|
+
else if (rawValues.length > 0) {
|
|
276
|
+
const literals = rawValues.map((v) => `z.literal(${JSON.stringify(v)})`);
|
|
277
|
+
expr = literals.length === 1 ? literals[0] : `z.union([${literals.join(", ")}])`;
|
|
278
|
+
} else expr = "z.string()";
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
273
281
|
case "integer":
|
|
274
282
|
expr = "z.coerce.number()";
|
|
275
283
|
break;
|
|
@@ -300,7 +308,7 @@ function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasin
|
|
|
300
308
|
const urlPath = new URLPath(node.path);
|
|
301
309
|
const contentType = node.requestBody?.contentType;
|
|
302
310
|
const isFormData = contentType === "multipart/form-data";
|
|
303
|
-
const casedParams = caseParams(node.parameters, paramsCasing);
|
|
311
|
+
const casedParams = ast.caseParams(node.parameters, paramsCasing);
|
|
304
312
|
const queryParams = casedParams.filter((p) => p.in === "query");
|
|
305
313
|
const headerParams = casedParams.filter((p) => p.in === "header");
|
|
306
314
|
const originalPathParams = node.parameters.filter((p) => p.in === "path");
|
|
@@ -314,7 +322,7 @@ function McpHandler({ name, node, resolver, baseURL, dataReturnType, paramsCasin
|
|
|
314
322
|
`ResponseErrorConfig<${errorResponses.length > 0 ? errorResponses.join(" | ") : "Error"}>`,
|
|
315
323
|
requestName || "unknown"
|
|
316
324
|
].filter(Boolean);
|
|
317
|
-
const paramsNode = createOperationParams(node, {
|
|
325
|
+
const paramsNode = ast.createOperationParams(node, {
|
|
318
326
|
paramsType: "object",
|
|
319
327
|
pathParamsType: "inline",
|
|
320
328
|
resolver,
|
|
@@ -408,7 +416,7 @@ function Server({ name, serverName, serverVersion, paramsCasing, operations }) {
|
|
|
408
416
|
`
|
|
409
417
|
}),
|
|
410
418
|
operations.map(({ tool, mcp, zod, node }) => {
|
|
411
|
-
const pathParams = caseParams(node.parameters, paramsCasing).filter((p) => p.in === "path");
|
|
419
|
+
const pathParams = ast.caseParams(node.parameters, paramsCasing).filter((p) => p.in === "path");
|
|
412
420
|
const pathEntries = [];
|
|
413
421
|
const otherEntries = [];
|
|
414
422
|
for (const p of pathParams) {
|
|
@@ -432,7 +440,7 @@ function Server({ name, serverName, serverVersion, paramsCasing, operations }) {
|
|
|
432
440
|
});
|
|
433
441
|
otherEntries.sort((a, b) => a.key.localeCompare(b.key));
|
|
434
442
|
const entries = [...pathEntries, ...otherEntries];
|
|
435
|
-
const paramsNode = entries.length ? createFunctionParameters({ params: [createParameterGroup({ properties: entries.map((e) => createFunctionParameter({
|
|
443
|
+
const paramsNode = entries.length ? ast.createFunctionParameters({ params: [ast.createParameterGroup({ properties: entries.map((e) => ast.createFunctionParameter({
|
|
436
444
|
name: e.key,
|
|
437
445
|
optional: false
|
|
438
446
|
})) })] }) : void 0;
|
|
@@ -480,12 +488,13 @@ server.registerTool(${JSON.stringify(tool.name)}, {
|
|
|
480
488
|
//#region src/generators/mcpGenerator.tsx
|
|
481
489
|
const mcpGenerator = defineGenerator({
|
|
482
490
|
name: "mcp",
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
const {
|
|
491
|
+
renderer: jsxRenderer,
|
|
492
|
+
operation(node, ctx) {
|
|
493
|
+
const { resolver, driver, root } = ctx;
|
|
494
|
+
const { output, client, paramsCasing, group } = ctx.options;
|
|
486
495
|
const pluginTs = driver.getPlugin(pluginTsName);
|
|
487
496
|
if (!pluginTs?.resolver) return null;
|
|
488
|
-
const casedParams = caseParams(node.parameters, paramsCasing);
|
|
497
|
+
const casedParams = ast.caseParams(node.parameters, paramsCasing);
|
|
489
498
|
const pathParams = casedParams.filter((p) => p.in === "path");
|
|
490
499
|
const queryParams = casedParams.filter((p) => p.in === "query");
|
|
491
500
|
const headerParams = casedParams.filter((p) => p.in === "header");
|
|
@@ -606,9 +615,10 @@ const mcpGenerator = defineGenerator({
|
|
|
606
615
|
*/
|
|
607
616
|
const serverGenerator = defineGenerator({
|
|
608
617
|
name: "operations",
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
const {
|
|
618
|
+
renderer: jsxRenderer,
|
|
619
|
+
operations(nodes, ctx) {
|
|
620
|
+
const { adapter, config, resolver, plugin, driver, root } = ctx;
|
|
621
|
+
const { output, paramsCasing, group } = ctx.options;
|
|
612
622
|
const pluginZod = driver.getPlugin(pluginZodName);
|
|
613
623
|
if (!pluginZod?.resolver) return;
|
|
614
624
|
const name = "server";
|
|
@@ -623,7 +633,7 @@ const serverGenerator = defineGenerator({
|
|
|
623
633
|
meta: { pluginName: plugin.name }
|
|
624
634
|
};
|
|
625
635
|
const operationsMapped = nodes.map((node) => {
|
|
626
|
-
const casedParams = caseParams(node.parameters, paramsCasing);
|
|
636
|
+
const casedParams = ast.caseParams(node.parameters, paramsCasing);
|
|
627
637
|
const pathParams = casedParams.filter((p) => p.in === "path");
|
|
628
638
|
const queryParams = casedParams.filter((p) => p.in === "query");
|
|
629
639
|
const headerParams = casedParams.filter((p) => p.in === "header");
|
|
@@ -760,9 +770,10 @@ const serverGenerator = defineGenerator({
|
|
|
760
770
|
*/
|
|
761
771
|
const serverGeneratorLegacy = defineGenerator({
|
|
762
772
|
name: "operations",
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
const {
|
|
773
|
+
renderer: jsxRenderer,
|
|
774
|
+
operations(nodes, ctx) {
|
|
775
|
+
const { adapter, config, resolver, plugin, driver, root } = ctx;
|
|
776
|
+
const { output, paramsCasing, group } = ctx.options;
|
|
766
777
|
const pluginZod = driver.getPlugin(pluginZodName);
|
|
767
778
|
if (!pluginZod?.resolver) return;
|
|
768
779
|
const name = "server";
|
|
@@ -777,7 +788,7 @@ const serverGeneratorLegacy = defineGenerator({
|
|
|
777
788
|
meta: { pluginName: plugin.name }
|
|
778
789
|
};
|
|
779
790
|
const operationsMapped = nodes.map((node) => {
|
|
780
|
-
const casedParams = caseParams(node.parameters, paramsCasing);
|
|
791
|
+
const casedParams = ast.caseParams(node.parameters, paramsCasing);
|
|
781
792
|
const queryParams = casedParams.filter((p) => p.in === "query");
|
|
782
793
|
const headerParams = casedParams.filter((p) => p.in === "header");
|
|
783
794
|
const mcpFile = resolver.resolveFile({
|
|
@@ -898,9 +909,6 @@ const serverGeneratorLegacy = defineGenerator({
|
|
|
898
909
|
}
|
|
899
910
|
});
|
|
900
911
|
//#endregion
|
|
901
|
-
//#region package.json
|
|
902
|
-
var version = "5.0.0-alpha.33";
|
|
903
|
-
//#endregion
|
|
904
912
|
//#region src/resolvers/resolverMcp.ts
|
|
905
913
|
/**
|
|
906
914
|
* Resolver for `@kubb/plugin-mcp` that provides the default naming
|
|
@@ -926,65 +934,38 @@ const resolverMcp = defineResolver(() => ({
|
|
|
926
934
|
}
|
|
927
935
|
}));
|
|
928
936
|
//#endregion
|
|
929
|
-
//#region src/presets.ts
|
|
930
|
-
/**
|
|
931
|
-
* Built-in preset registry for `@kubb/plugin-mcp`.
|
|
932
|
-
*
|
|
933
|
-
* - `default` — v5 naming with individual zod schemas and per-status responses.
|
|
934
|
-
* - `kubbV4` — legacy naming with grouped zod schemas and combined responses.
|
|
935
|
-
*/
|
|
936
|
-
const presets = definePresets({
|
|
937
|
-
default: {
|
|
938
|
-
name: "default",
|
|
939
|
-
resolver: resolverMcp,
|
|
940
|
-
generators: [mcpGenerator, serverGenerator]
|
|
941
|
-
},
|
|
942
|
-
kubbV4: {
|
|
943
|
-
name: "kubbV4",
|
|
944
|
-
resolver: resolverMcp,
|
|
945
|
-
generators: [mcpGenerator, serverGeneratorLegacy]
|
|
946
|
-
}
|
|
947
|
-
});
|
|
948
|
-
//#endregion
|
|
949
937
|
//#region src/plugin.ts
|
|
950
938
|
const pluginMcpName = "plugin-mcp";
|
|
951
|
-
const pluginMcp =
|
|
939
|
+
const pluginMcp = definePlugin((options) => {
|
|
952
940
|
const { output = {
|
|
953
941
|
path: "mcp",
|
|
954
942
|
barrelType: "named"
|
|
955
|
-
}, group, exclude = [], include, override = [], paramsCasing, client,
|
|
943
|
+
}, group, exclude = [], include, override = [], paramsCasing, client, resolver: userResolver, transformer: userTransformer, generators: userGenerators = [], compatibilityPreset = "default" } = options;
|
|
944
|
+
const defaultServerGenerator = compatibilityPreset === "kubbV4" ? serverGeneratorLegacy : serverGenerator;
|
|
956
945
|
const clientName = client?.client ?? "axios";
|
|
957
946
|
const clientImportPath = client?.importPath ?? (!client?.bundle ? `@kubb/plugin-client/clients/${clientName}` : void 0);
|
|
958
|
-
const
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
}
|
|
965
|
-
const mergedGenerator = mergeGenerators(preset.generators ?? []);
|
|
947
|
+
const groupConfig = group ? {
|
|
948
|
+
...group,
|
|
949
|
+
name: group.name ? group.name : (ctx) => {
|
|
950
|
+
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
951
|
+
return `${camelCase(ctx.group)}Requests`;
|
|
952
|
+
}
|
|
953
|
+
} : void 0;
|
|
966
954
|
return {
|
|
967
955
|
name: pluginMcpName,
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
return {
|
|
956
|
+
options,
|
|
957
|
+
dependencies: [pluginTsName, pluginZodName],
|
|
958
|
+
hooks: { "kubb:plugin:setup"(ctx) {
|
|
959
|
+
const resolver = userResolver ? {
|
|
960
|
+
...resolverMcp,
|
|
961
|
+
...userResolver
|
|
962
|
+
} : resolverMcp;
|
|
963
|
+
ctx.setOptions({
|
|
977
964
|
output,
|
|
978
965
|
exclude,
|
|
979
966
|
include,
|
|
980
967
|
override,
|
|
981
|
-
group:
|
|
982
|
-
...group,
|
|
983
|
-
name: group.name ? group.name : (ctx) => {
|
|
984
|
-
if (group.type === "path") return `${ctx.group.split("/")[1]}`;
|
|
985
|
-
return `${camelCase(ctx.group)}Requests`;
|
|
986
|
-
}
|
|
987
|
-
} : void 0,
|
|
968
|
+
group: groupConfig,
|
|
988
969
|
paramsCasing,
|
|
989
970
|
client: {
|
|
990
971
|
client: clientName,
|
|
@@ -995,51 +976,36 @@ const pluginMcp = createPlugin((options) => {
|
|
|
995
976
|
baseURL: client?.baseURL,
|
|
996
977
|
paramsCasing: client?.paramsCasing
|
|
997
978
|
},
|
|
998
|
-
resolver
|
|
999
|
-
};
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
async operations(nodes, options) {
|
|
1009
|
-
return mergedGenerator.operations?.call(this, nodes, options);
|
|
1010
|
-
},
|
|
1011
|
-
async buildStart() {
|
|
1012
|
-
const { adapter, driver } = this;
|
|
1013
|
-
const root = this.root;
|
|
1014
|
-
const baseURL = adapter?.inputNode?.meta?.baseURL;
|
|
1015
|
-
if (baseURL) this.plugin.options.client.baseURL = this.plugin.options.client.baseURL || baseURL;
|
|
1016
|
-
const hasClientPlugin = !!driver.getPlugin(pluginClientName);
|
|
1017
|
-
if (this.plugin.options.client.bundle && !hasClientPlugin && !this.plugin.options.client.importPath) await this.addFile(createFile({
|
|
979
|
+
resolver
|
|
980
|
+
});
|
|
981
|
+
ctx.setResolver(resolver);
|
|
982
|
+
if (userTransformer) ctx.setTransformer(userTransformer);
|
|
983
|
+
ctx.addGenerator(mcpGenerator);
|
|
984
|
+
ctx.addGenerator(defaultServerGenerator);
|
|
985
|
+
for (const gen of userGenerators) ctx.addGenerator(gen);
|
|
986
|
+
const root = path.resolve(ctx.config.root, ctx.config.output.path);
|
|
987
|
+
const hasClientPlugin = ctx.config.plugins?.some((p) => p.name === pluginClientName);
|
|
988
|
+
if (client?.bundle && !hasClientPlugin && !clientImportPath) ctx.injectFile({
|
|
1018
989
|
baseName: "fetch.ts",
|
|
1019
990
|
path: path.resolve(root, ".kubb/fetch.ts"),
|
|
1020
|
-
sources: [createSource({
|
|
991
|
+
sources: [ast.createSource({
|
|
1021
992
|
name: "fetch",
|
|
1022
|
-
nodes: [createText(
|
|
993
|
+
nodes: [ast.createText(clientName === "fetch" ? source$1 : source)],
|
|
1023
994
|
isExportable: true,
|
|
1024
995
|
isIndexable: true
|
|
1025
|
-
})]
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
}));
|
|
1029
|
-
if (!hasClientPlugin) await this.addFile(createFile({
|
|
996
|
+
})]
|
|
997
|
+
});
|
|
998
|
+
if (!hasClientPlugin) ctx.injectFile({
|
|
1030
999
|
baseName: "config.ts",
|
|
1031
1000
|
path: path.resolve(root, ".kubb/config.ts"),
|
|
1032
|
-
sources: [createSource({
|
|
1001
|
+
sources: [ast.createSource({
|
|
1033
1002
|
name: "config",
|
|
1034
|
-
nodes: [createText(source$2)],
|
|
1003
|
+
nodes: [ast.createText(source$2)],
|
|
1035
1004
|
isExportable: false,
|
|
1036
1005
|
isIndexable: false
|
|
1037
|
-
})]
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
}));
|
|
1041
|
-
await this.openInStudio({ ast: true });
|
|
1042
|
-
}
|
|
1006
|
+
})]
|
|
1007
|
+
});
|
|
1008
|
+
} }
|
|
1043
1009
|
};
|
|
1044
1010
|
});
|
|
1045
1011
|
//#endregion
|