@kubb/plugin-mcp 5.1.0 → 5.1.2

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/plugin-mcp" target="_blank">Documentation</a>
13
+ <a href="https://kubb.dev/extensions/kubb-labs/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/plugin-mcp) for configuration options and examples.
41
+ See the [full documentation](https://kubb.dev/extensions/kubb-labs/plugin-mcp) for configuration options and examples.
42
42
 
43
43
  ## Supporting Kubb
44
44
 
package/dist/index.cjs CHANGED
@@ -261,6 +261,27 @@ function camelCase(text, { prefix = "", suffix = "" } = {}) {
261
261
  return toCamelOrPascal(`${prefix} ${text} ${suffix}`, false);
262
262
  }
263
263
  //#endregion
264
+ //#region ../../internals/utils/src/fs.ts
265
+ function toSlash(p) {
266
+ if (p.startsWith("\\\\?\\")) return p;
267
+ return p.replaceAll("\\", "/");
268
+ }
269
+ /**
270
+ * Returns the relative path from `rootDir` to `filePath`, always using forward slashes
271
+ * and prefixed with `./` when not already traversing upward.
272
+ *
273
+ * @example
274
+ * ```ts
275
+ * getRelativePath('/src/components', '/src/components/Button.tsx') // './Button.tsx'
276
+ * getRelativePath('/src/components', '/src/utils/helpers.ts') // '../utils/helpers.ts'
277
+ * ```
278
+ */
279
+ function getRelativePath(rootDir, filePath) {
280
+ if (!rootDir || !filePath) throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ""} ${filePath || ""}`);
281
+ const relativePath = node_path.posix.relative(toSlash(rootDir), toSlash(filePath));
282
+ return relativePath.startsWith("../") ? relativePath : `./${relativePath}`;
283
+ }
284
+ //#endregion
264
285
  //#region ../../internals/shared/src/group.ts
265
286
  /**
266
287
  * Builds the `group` config a Kubb plugin passes to `ctx.setOptions`, applying the
@@ -718,11 +739,21 @@ const serverGenerator = (0, kubb_kit.defineGenerator)({
718
739
  path: node_path.default.resolve(root, output.path, "server.ts"),
719
740
  meta: { pluginName: plugin.name }
720
741
  };
742
+ const startFile = {
743
+ baseName: "start.ts",
744
+ path: node_path.default.resolve(root, output.path, "start.ts"),
745
+ meta: { pluginName: plugin.name }
746
+ };
721
747
  const jsonFile = {
722
748
  baseName: ".mcp.json",
723
749
  path: node_path.default.resolve(root, output.path, ".mcp.json"),
724
750
  meta: { pluginName: plugin.name }
725
751
  };
752
+ const mcpConfig = { mcpServers: { [ctx.meta.title || "server"]: {
753
+ type: "stdio",
754
+ command: "npx",
755
+ args: ["tsx", getRelativePath(node_path.default.resolve(config.root), startFile.path)]
756
+ } } };
726
757
  const operationsMapped = nodes.filter(kubb_kit.ast.isHttpOperationNode).map((node) => {
727
758
  const { path: pathParams, query: queryParams, header: headerParams } = getOperationParameters(node);
728
759
  const mcpFile = resolver.file({
@@ -790,76 +821,98 @@ const serverGenerator = (0, kubb_kit.defineGenerator)({
790
821
  path: zod.file.path
791
822
  }, `zod-${mcp.name}`)].filter(Boolean);
792
823
  });
793
- return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
794
- baseName: serverFile.baseName,
795
- path: serverFile.path,
796
- meta: serverFile.meta,
797
- banner: resolver.default.banner(ctx.meta, {
798
- output,
799
- config,
800
- file: {
801
- path: serverFile.path,
802
- baseName: serverFile.baseName
803
- }
804
- }),
805
- footer: resolver.default.footer(ctx.meta, {
806
- output,
807
- config,
808
- file: {
809
- path: serverFile.path,
810
- baseName: serverFile.baseName
811
- }
812
- }),
813
- children: [
814
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
815
- name: ["McpServer"],
816
- path: "@modelcontextprotocol/server"
824
+ return /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx_jsx_runtime.Fragment, { children: [
825
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
826
+ baseName: serverFile.baseName,
827
+ path: serverFile.path,
828
+ meta: serverFile.meta,
829
+ banner: resolver.default.banner(ctx.meta, {
830
+ output,
831
+ config,
832
+ file: {
833
+ path: serverFile.path,
834
+ baseName: serverFile.baseName
835
+ }
817
836
  }),
818
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
819
- name: ["serveStdio"],
820
- path: "@modelcontextprotocol/server/stdio"
837
+ footer: resolver.default.footer(ctx.meta, {
838
+ output,
839
+ config,
840
+ file: {
841
+ path: serverFile.path,
842
+ baseName: serverFile.baseName
843
+ }
821
844
  }),
822
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
823
- name: ["z"],
824
- path: "zod"
845
+ children: [
846
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
847
+ name: ["McpServer"],
848
+ path: "@modelcontextprotocol/server"
849
+ }),
850
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
851
+ name: ["serveStdio"],
852
+ path: "@modelcontextprotocol/server/stdio"
853
+ }),
854
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
855
+ name: ["z"],
856
+ path: "zod"
857
+ }),
858
+ imports,
859
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Server, {
860
+ serverName: ctx.meta.title ?? "server",
861
+ serverVersion: ctx.meta.version ?? "0.0.0",
862
+ operations: operationsMapped
863
+ })
864
+ ]
865
+ }),
866
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsxs)(kubb_jsx.File, {
867
+ baseName: startFile.baseName,
868
+ path: startFile.path,
869
+ meta: startFile.meta,
870
+ banner: resolver.default.banner(ctx.meta, {
871
+ output,
872
+ config,
873
+ file: {
874
+ path: startFile.path,
875
+ baseName: startFile.baseName
876
+ }
825
877
  }),
826
- imports,
827
- /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(Server, {
828
- serverName: ctx.meta.title ?? "server",
829
- serverVersion: ctx.meta.version ?? "0.0.0",
830
- operations: operationsMapped
878
+ footer: resolver.default.footer(ctx.meta, {
879
+ output,
880
+ config,
881
+ file: {
882
+ path: startFile.path,
883
+ baseName: startFile.baseName
884
+ }
885
+ }),
886
+ children: [/* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Import, {
887
+ name: ["startServer"],
888
+ root: startFile.path,
889
+ path: serverFile.path
890
+ }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
891
+ name: "start",
892
+ children: "void startServer()"
893
+ })]
894
+ }),
895
+ /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File, {
896
+ baseName: jsonFile.baseName,
897
+ path: jsonFile.path,
898
+ meta: jsonFile.meta,
899
+ children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
900
+ name,
901
+ children: `${JSON.stringify(mcpConfig, null, 2)}\n`
831
902
  })
832
- ]
833
- }), /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File, {
834
- baseName: jsonFile.baseName,
835
- path: jsonFile.path,
836
- meta: jsonFile.meta,
837
- children: /* @__PURE__ */ (0, kubb_jsx_jsx_runtime.jsx)(kubb_jsx.File.Source, {
838
- name,
839
- children: `
840
- {
841
- "mcpServers": {
842
- "${ctx.meta.title || "server"}": {
843
- "type": "stdio",
844
- "command": "npx",
845
- "args": ["tsx", "${node_path.default.relative(node_path.default.dirname(jsonFile.path), serverFile.path)}"]
846
- }
847
- }
848
- }
849
- `
850
903
  })
851
- })] });
904
+ ] });
852
905
  }
853
906
  });
854
907
  //#endregion
855
908
  //#region kubb-extension.json
856
909
  var compatibility = {
857
- "kubb": ">=5.8.0",
910
+ "kubb": ">=5.8.3",
858
911
  "node": ">=22"
859
912
  };
860
913
  //#endregion
861
914
  //#region package.json
862
- var version = "5.1.0";
915
+ var version = "5.1.2";
863
916
  //#endregion
864
917
  //#region src/resolvers/resolverMcp.ts
865
918
  /**
@@ -895,12 +948,15 @@ const pluginMcpName = "plugin-mcp";
895
948
  * operation becomes a typed MCP tool that AI assistants (Claude Desktop, Claude
896
949
  * Code, MCP-compatible clients) can call directly. Each handler calls a contract
897
950
  * client `<op>` from a registered `@kubb/plugin-axios` or `@kubb/plugin-fetch`.
951
+ * Next to the handlers it writes `server.ts`, a `start.ts` entry that serves the
952
+ * tools over stdio, and a `.mcp.json` that runs `start.ts` with `tsx`.
898
953
  *
899
954
  * @example
900
955
  * ```ts
901
956
  * import { defineConfig } from 'kubb/config'
902
957
  * import { pluginTs } from '@kubb/plugin-ts'
903
958
  * import { pluginZod } from '@kubb/plugin-zod'
959
+ * import { pluginFetch } from '@kubb/plugin-fetch'
904
960
  * import { pluginMcp } from '@kubb/plugin-mcp'
905
961
  *
906
962
  * export default defineConfig({
@@ -909,15 +965,14 @@ const pluginMcpName = "plugin-mcp";
909
965
  * plugins: [
910
966
  * pluginTs(),
911
967
  * pluginZod(),
912
- * pluginMcp({
913
- * output: { path: './mcp' },
914
- * baseURL: 'https://petstore.swagger.io/v2',
915
- * }),
968
+ * pluginFetch({ baseURL: 'https://petstore.swagger.io/v2' }),
969
+ * pluginMcp({ output: { path: 'mcp' } }),
916
970
  * ],
917
971
  * })
918
972
  * ```
919
973
  */
920
- const pluginMcp = (0, kubb_kit.definePlugin)({
974
+ const pluginMcp = (0, kubb_kit.defineExtension)({
975
+ kind: "plugin",
921
976
  meta: {
922
977
  name: pluginMcpName,
923
978
  version,