@es-plus/mcp-server 1.0.0

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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +345 -0
  3. package/build/core/code-generator.d.ts +9 -0
  4. package/build/core/code-generator.d.ts.map +1 -0
  5. package/build/core/code-generator.js +87 -0
  6. package/build/core/code-generator.js.map +1 -0
  7. package/build/core/constants.d.ts +61 -0
  8. package/build/core/constants.d.ts.map +1 -0
  9. package/build/core/constants.js +51 -0
  10. package/build/core/constants.js.map +1 -0
  11. package/build/core/crud-engine.d.ts +12 -0
  12. package/build/core/crud-engine.d.ts.map +1 -0
  13. package/build/core/crud-engine.js +405 -0
  14. package/build/core/crud-engine.js.map +1 -0
  15. package/build/core/schema-validator.d.ts +9 -0
  16. package/build/core/schema-validator.d.ts.map +1 -0
  17. package/build/core/schema-validator.js +57 -0
  18. package/build/core/schema-validator.js.map +1 -0
  19. package/build/index.d.ts +3 -0
  20. package/build/index.d.ts.map +1 -0
  21. package/build/index.js +18 -0
  22. package/build/index.js.map +1 -0
  23. package/build/prompts/crud-page.d.ts +3 -0
  24. package/build/prompts/crud-page.d.ts.map +1 -0
  25. package/build/prompts/crud-page.js +49 -0
  26. package/build/prompts/crud-page.js.map +1 -0
  27. package/build/prompts/form-config.d.ts +3 -0
  28. package/build/prompts/form-config.d.ts.map +1 -0
  29. package/build/prompts/form-config.js +42 -0
  30. package/build/prompts/form-config.js.map +1 -0
  31. package/build/prompts/index.d.ts +3 -0
  32. package/build/prompts/index.d.ts.map +1 -0
  33. package/build/prompts/index.js +7 -0
  34. package/build/prompts/index.js.map +1 -0
  35. package/build/resources/examples.d.ts +3 -0
  36. package/build/resources/examples.d.ts.map +1 -0
  37. package/build/resources/examples.js +36 -0
  38. package/build/resources/examples.js.map +1 -0
  39. package/build/resources/index.d.ts +3 -0
  40. package/build/resources/index.d.ts.map +1 -0
  41. package/build/resources/index.js +9 -0
  42. package/build/resources/index.js.map +1 -0
  43. package/build/resources/schemas.d.ts +3 -0
  44. package/build/resources/schemas.d.ts.map +1 -0
  45. package/build/resources/schemas.js +46 -0
  46. package/build/resources/schemas.js.map +1 -0
  47. package/build/resources/types.d.ts +3 -0
  48. package/build/resources/types.d.ts.map +1 -0
  49. package/build/resources/types.js +159 -0
  50. package/build/resources/types.js.map +1 -0
  51. package/build/tools/generate-crud-page.d.ts +3 -0
  52. package/build/tools/generate-crud-page.d.ts.map +1 -0
  53. package/build/tools/generate-crud-page.js +33 -0
  54. package/build/tools/generate-crud-page.js.map +1 -0
  55. package/build/tools/get-component-api.d.ts +3 -0
  56. package/build/tools/get-component-api.d.ts.map +1 -0
  57. package/build/tools/get-component-api.js +191 -0
  58. package/build/tools/get-component-api.js.map +1 -0
  59. package/build/tools/index.d.ts +3 -0
  60. package/build/tools/index.d.ts.map +1 -0
  61. package/build/tools/index.js +13 -0
  62. package/build/tools/index.js.map +1 -0
  63. package/build/tools/list-form-types.d.ts +3 -0
  64. package/build/tools/list-form-types.d.ts.map +1 -0
  65. package/build/tools/list-form-types.js +21 -0
  66. package/build/tools/list-form-types.js.map +1 -0
  67. package/build/tools/scaffold-page.d.ts +3 -0
  68. package/build/tools/scaffold-page.d.ts.map +1 -0
  69. package/build/tools/scaffold-page.js +38 -0
  70. package/build/tools/scaffold-page.js.map +1 -0
  71. package/build/tools/validate-config.d.ts +3 -0
  72. package/build/tools/validate-config.d.ts.map +1 -0
  73. package/build/tools/validate-config.js +60 -0
  74. package/build/tools/validate-config.js.map +1 -0
  75. package/package.json +57 -0
  76. package/schemas/README.md +75 -0
  77. package/schemas/api-params.schema.json +36 -0
  78. package/schemas/btn-config.schema.json +77 -0
  79. package/schemas/dialog-options.schema.json +149 -0
  80. package/schemas/form-item.schema.json +142 -0
  81. package/schemas/index.schema.json +71 -0
  82. package/schemas/table-column.schema.json +111 -0
  83. package/schemas/table-options.schema.json +141 -0
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ const SYSTEM_PROMPT = `You are an expert at generating es-plus-ui form configurations. Generate only the form configuration JSON, not the full Vue component.
3
+
4
+ FormItemOption interface:
5
+ - prop: string (field key)
6
+ - label: string (display label)
7
+ - formtype: 'Input' | 'Select' | 'datePicker' | 'timePicker' | 'Slider' | 'ColorPicker' | 'Transfer' | 'Cascader' | 'Radio' | 'Checkbox' | 'Switch' | 'Rate' | 'Upload'
8
+ - span: number (grid width, 1-24)
9
+ - attrs: object (pass-through props to Element Plus component)
10
+ - dataOptions: Array<{ label: string, value: any }> (for Select/Radio/Checkbox)
11
+ - rules: array (Element Plus validation rules)
12
+ - isHidden: function (dynamic visibility)
13
+
14
+ Common patterns:
15
+ - Text input: { prop: 'name', label: '姓名', formtype: 'Input', span: 12 }
16
+ - Select with options: { prop: 'status', label: '状态', formtype: 'Select', dataOptions: [...], span: 12 }
17
+ - Date range: { prop: 'dateRange', label: '日期', formtype: 'datePicker', attrs: { type: 'daterange', valueFormat: 'YYYY-MM-DD' }, span: 12 }
18
+ - Textarea: { prop: 'remark', label: '备注', formtype: 'Input', attrs: { type: 'textarea', rows: 3 }, span: 24 }
19
+ - Switch: { prop: 'enabled', label: '启用', formtype: 'Switch', span: 12 }
20
+
21
+ Output format: JSON array of FormItemOption objects.
22
+ `;
23
+ export function registerFormConfigPrompt(server) {
24
+ server.prompt("form-config", "Generate es-plus-ui form configuration JSON from a description", {
25
+ description: z
26
+ .string()
27
+ .describe("Description of the form fields needed"),
28
+ }, async ({ description }) => {
29
+ return {
30
+ messages: [
31
+ {
32
+ role: "user",
33
+ content: {
34
+ type: "text",
35
+ text: `${SYSTEM_PROMPT}\n\nGenerate the formItemList JSON configuration for this form:\n\n${description}\n\nReturn only the JSON array, properly formatted.`,
36
+ },
37
+ },
38
+ ],
39
+ };
40
+ });
41
+ }
42
+ //# sourceMappingURL=form-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form-config.js","sourceRoot":"","sources":["../../src/prompts/form-config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;CAoBrB,CAAC;AAEF,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,CAAC,MAAM,CACX,aAAa,EACb,gEAAgE,EAChE;QACE,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,CAAC,uCAAuC,CAAC;KACrD,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;QACxB,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,GAAG,aAAa,sEAAsE,WAAW,qDAAqD;qBAC7J;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerPrompts(server: McpServer): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,QAGhD"}
@@ -0,0 +1,7 @@
1
+ import { registerCrudPagePrompt } from "./crud-page.js";
2
+ import { registerFormConfigPrompt } from "./form-config.js";
3
+ export function registerPrompts(server) {
4
+ registerCrudPagePrompt(server);
5
+ registerFormConfigPrompt(server);
6
+ }
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAE5D,MAAM,UAAU,eAAe,CAAC,MAAiB;IAC/C,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,wBAAwB,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerExamplesResource(server: McpServer): void;
3
+ //# sourceMappingURL=examples.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"examples.d.ts","sourceRoot":"","sources":["../../src/resources/examples.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,QAuCzD"}
@@ -0,0 +1,36 @@
1
+ import { PRESET_EXAMPLES } from "../core/constants.js";
2
+ import { generateCrudPage } from "../core/code-generator.js";
3
+ export function registerExamplesResource(server) {
4
+ server.resource("examples", "esplus://examples", {
5
+ description: "Pre-built CRUD page examples with prompts and generated code",
6
+ mimeType: "text/plain",
7
+ }, async () => {
8
+ const sections = PRESET_EXAMPLES.map((ex) => {
9
+ const result = generateCrudPage(ex.prompt);
10
+ return [
11
+ `## ${ex.label}`,
12
+ `**Prompt:** ${ex.prompt}`,
13
+ "",
14
+ "```vue",
15
+ result.code,
16
+ "```",
17
+ "",
18
+ ].join("\n");
19
+ });
20
+ const content = [
21
+ "# es-plus-ui CRUD Page Examples\n",
22
+ "These examples are generated from natural language descriptions using the es-plus CRUD engine.\n",
23
+ ...sections,
24
+ ].join("\n");
25
+ return {
26
+ contents: [
27
+ {
28
+ uri: "esplus://examples",
29
+ mimeType: "text/plain",
30
+ text: content,
31
+ },
32
+ ],
33
+ };
34
+ });
35
+ }
36
+ //# sourceMappingURL=examples.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"examples.js","sourceRoot":"","sources":["../../src/resources/examples.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,CAAC,QAAQ,CACb,UAAU,EACV,mBAAmB,EACnB;QACE,WAAW,EAAE,8DAA8D;QAC3E,QAAQ,EAAE,YAAY;KACvB,EACD,KAAK,IAAI,EAAE;QACT,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;YAC1C,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;YAC3C,OAAO;gBACL,MAAM,EAAE,CAAC,KAAK,EAAE;gBAChB,eAAe,EAAE,CAAC,MAAM,EAAE;gBAC1B,EAAE;gBACF,QAAQ;gBACR,MAAM,CAAC,IAAI;gBACX,KAAK;gBACL,EAAE;aACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG;YACd,mCAAmC;YACnC,kGAAkG;YAClG,GAAG,QAAQ;SACZ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,mBAAmB;oBACxB,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,OAAO;iBACd;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerResources(server: McpServer): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,QAIlD"}
@@ -0,0 +1,9 @@
1
+ import { registerSchemaResources } from "./schemas.js";
2
+ import { registerTypesResource } from "./types.js";
3
+ import { registerExamplesResource } from "./examples.js";
4
+ export function registerResources(server) {
5
+ registerSchemaResources(server);
6
+ registerTypesResource(server);
7
+ registerExamplesResource(server);
8
+ }
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAEzD,MAAM,UAAU,iBAAiB,CAAC,MAAiB;IACjD,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,wBAAwB,CAAC,MAAM,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerSchemaResources(server: McpServer): void;
3
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/resources/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiBzE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,QAoCxD"}
@@ -0,0 +1,46 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { join, dirname } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ const SCHEMAS_DIR = join(__dirname, "../../schemas");
6
+ const SCHEMA_FILES = [
7
+ { name: "form-item", description: "FormItemOption configuration schema" },
8
+ { name: "table-column", description: "TableColumn configuration schema" },
9
+ { name: "table-options", description: "TableOptions configuration schema" },
10
+ { name: "dialog-options", description: "DialogOptions configuration schema" },
11
+ { name: "btn-config", description: "BtnConfig button configuration schema" },
12
+ { name: "api-params", description: "ApiParams remote data loading schema" },
13
+ ];
14
+ export function registerSchemaResources(server) {
15
+ for (const schema of SCHEMA_FILES) {
16
+ const uri = `esplus://schemas/${schema.name}`;
17
+ server.resource(schema.name, uri, {
18
+ description: schema.description,
19
+ mimeType: "application/json",
20
+ }, async () => {
21
+ const filePath = join(SCHEMAS_DIR, `${schema.name}.schema.json`);
22
+ if (!existsSync(filePath)) {
23
+ return {
24
+ contents: [
25
+ {
26
+ uri,
27
+ mimeType: "text/plain",
28
+ text: `Schema file not found: ${schema.name}.schema.json`,
29
+ },
30
+ ],
31
+ };
32
+ }
33
+ const content = readFileSync(filePath, "utf-8");
34
+ return {
35
+ contents: [
36
+ {
37
+ uri,
38
+ mimeType: "application/json",
39
+ text: content,
40
+ },
41
+ ],
42
+ };
43
+ });
44
+ }
45
+ }
46
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/resources/schemas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;AAErD,MAAM,YAAY,GAAG;IACnB,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,qCAAqC,EAAE;IACzE,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,kCAAkC,EAAE;IACzE,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,mCAAmC,EAAE;IAC3E,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,oCAAoC,EAAE;IAC7E,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,uCAAuC,EAAE;IAC5E,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,sCAAsC,EAAE;CAC5E,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,oBAAoB,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9C,MAAM,CAAC,QAAQ,CACb,MAAM,CAAC,IAAI,EACX,GAAG,EACH;YACE,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,QAAQ,EAAE,kBAAkB;SAC7B,EACD,KAAK,IAAI,EAAE;YACT,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,IAAI,cAAc,CAAC,CAAC;YACjE,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,OAAO;oBACL,QAAQ,EAAE;wBACR;4BACE,GAAG;4BACH,QAAQ,EAAE,YAAY;4BACtB,IAAI,EAAE,0BAA0B,MAAM,CAAC,IAAI,cAAc;yBAC1D;qBACF;iBACF,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChD,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG;wBACH,QAAQ,EAAE,kBAAkB;wBAC5B,IAAI,EAAE,OAAO;qBACd;iBACF;aACF,CAAC;QACJ,CAAC,CACF,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerTypesResource(server: McpServer): void;
3
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/resources/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiJzE,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,QAoBtD"}
@@ -0,0 +1,159 @@
1
+ const TYPES_CONTENT = `// es-plus-ui TypeScript Type Definitions
2
+
3
+ import type { VNode, RenderFunction } from 'vue'
4
+ import type { FormItemProps, FormProps, ButtonProps } from 'element-plus'
5
+
6
+ export type FormType = 'Input' | 'Select' | 'datePicker' | 'timePicker' | 'Slider' | 'ColorPicker' | 'Transfer' | 'Cascader' | 'Radio' | 'Checkbox' | 'Switch' | 'Rate' | 'Upload'
7
+
8
+ export interface FormItemOption {
9
+ prop: string
10
+ label: string
11
+ formtype?: FormType
12
+ span?: number
13
+ attrs?: Record<string, unknown>
14
+ on?: Record<string, unknown>
15
+ dataOptions?: Array<{ label: string; value: unknown }>
16
+ isHidden?: (model: Record<string, unknown>, item: FormItemOption, formProps: FormProps) => boolean
17
+ render?: (h: RenderFunction, model: Record<string, unknown>, ctx: { row: FormItemOption; index: number }) => VNode | string
18
+ apiParams?: ApiParams
19
+ isInitRun?: boolean
20
+ callOptionListFormat?: (data: unknown[]) => unknown[]
21
+ httpRequest?: (params: Record<string, unknown>) => Promise<unknown>
22
+ listenToCallBack?: Record<string, (params: unknown) => unknown>
23
+ width?: number | string
24
+ [key: string]: unknown
25
+ }
26
+
27
+ export interface ApiParams {
28
+ url: string
29
+ method?: string
30
+ headers?: Record<string, string>
31
+ model?: Record<string, unknown>
32
+ options?: Record<string, unknown>
33
+ }
34
+
35
+ export interface BtnConfig {
36
+ name: string
37
+ key?: string
38
+ type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
39
+ size?: 'large' | 'default' | 'small'
40
+ icon?: string
41
+ direction?: 'left' | 'right'
42
+ loading?: boolean
43
+ disabled?: boolean | (() => boolean)
44
+ triggerEvent?: boolean
45
+ click?: (model: Record<string, unknown>, formRef: unknown, httpRequestInstance?: unknown) => void
46
+ [key: string]: unknown
47
+ }
48
+
49
+ export interface LayoutFormProps {
50
+ rowLayProps?: Record<string, unknown>
51
+ fromLayProps?: {
52
+ isBtnHidden?: boolean
53
+ minFoldRows?: number
54
+ btnColSpan?: number
55
+ labelBtnWidth?: string | number
56
+ }
57
+ setOptions?: boolean
58
+ }
59
+
60
+ export interface TableColumn {
61
+ prop?: string
62
+ key?: string
63
+ label?: string
64
+ width?: number | string
65
+ minWidth?: number | string
66
+ align?: string
67
+ fixed?: boolean | string
68
+ formatter?: (row: Record<string, unknown>) => string
69
+ render?: (h: RenderFunction, ctx: { row: Record<string, unknown>; value: unknown; index: number }) => VNode | string
70
+ scopedSlots?: { customRender?: string }
71
+ groups?: TableColumn[]
72
+ ellipsis?: boolean
73
+ hidCol?: boolean
74
+ btns?: Array<{ name: string; type?: string; clickEvent?: (row: Record<string, unknown>) => void }>
75
+ [key: string]: unknown
76
+ }
77
+
78
+ export interface TableOptions {
79
+ multiSelect?: boolean
80
+ expand?: boolean
81
+ snIndex?: boolean
82
+ loading?: boolean
83
+ border?: boolean
84
+ stripe?: boolean
85
+ size?: 'large' | 'default' | 'small'
86
+ headerCellStyle?: Record<string, unknown>
87
+ highlightCurrentRow?: boolean
88
+ cachePageSelection?: boolean
89
+ heightType?: 'auto' | 'height'
90
+ tabHeight?: number | string
91
+ isInitRun?: boolean
92
+ actionUrl?: string
93
+ apiParams?: ApiParams
94
+ httpRequest?: (params: Record<string, unknown>) => Promise<unknown>
95
+ listenToCallBack?: Record<string, (params: unknown) => unknown>
96
+ configTableOut?: Record<string, string>
97
+ entryQuery?: Record<string, unknown>
98
+ rowkey?: string
99
+ [key: string]: unknown
100
+ }
101
+
102
+ export interface PaginationConfig {
103
+ pageSize?: number
104
+ current?: number
105
+ total?: number
106
+ pageSizes?: number[]
107
+ size?: 'large' | 'default' | 'small'
108
+ isSmall?: boolean
109
+ }
110
+
111
+ export interface DialogOptions {
112
+ title?: string
113
+ width?: string | number
114
+ render?: (h: RenderFunction, instance: unknown, components: Record<string, unknown>) => VNode
115
+ renderHeader?: (h: RenderFunction, instance: unknown) => VNode
116
+ renderFooter?: (h: RenderFunction, instance: unknown) => VNode
117
+ configBtn?: BtnConfig[]
118
+ onSubmit?: (close: () => void) => void
119
+ onClosed?: () => void
120
+ isDraggable?: boolean
121
+ hiddenFullBtn?: boolean
122
+ isHiddenFooter?: boolean
123
+ maxHeight?: string | number
124
+ appendTo?: string | HTMLElement
125
+ fullscreen?: boolean
126
+ [key: string]: unknown
127
+ }
128
+
129
+ export interface EsFormInstance {
130
+ validate: () => Promise<boolean>
131
+ resetFields: () => void
132
+ clearValidate: () => void
133
+ }
134
+
135
+ export interface EsTableInstance {
136
+ httpRequestInstance: (model?: Record<string, unknown>) => Promise<unknown>
137
+ clearSelection: () => void
138
+ toggleRowSelection: (row: Record<string, unknown>, selected?: boolean) => void
139
+ clearAllSelection: () => void
140
+ refresh: () => void
141
+ }
142
+ `;
143
+ export function registerTypesResource(server) {
144
+ server.resource("types", "esplus://types", {
145
+ description: "Complete TypeScript type definitions for all es-plus-ui components",
146
+ mimeType: "text/plain",
147
+ }, async () => {
148
+ return {
149
+ contents: [
150
+ {
151
+ uri: "esplus://types",
152
+ mimeType: "text/plain",
153
+ text: TYPES_CONTENT,
154
+ },
155
+ ],
156
+ };
157
+ });
158
+ }
159
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/resources/types.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6IrB,CAAC;AAEF,MAAM,UAAU,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,QAAQ,CACb,OAAO,EACP,gBAAgB,EAChB;QACE,WAAW,EAAE,oEAAoE;QACjF,QAAQ,EAAE,YAAY;KACvB,EACD,KAAK,IAAI,EAAE;QACT,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,gBAAgB;oBACrB,QAAQ,EAAE,YAAY;oBACtB,IAAI,EAAE,aAAa;iBACpB;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerGenerateCrudPage(server: McpServer): void;
3
+ //# sourceMappingURL=generate-crud-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-crud-page.d.ts","sourceRoot":"","sources":["../../src/tools/generate-crud-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIzE,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,QAmCzD"}
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ import { generateCrudPage } from "../core/code-generator.js";
3
+ export function registerGenerateCrudPage(server) {
4
+ server.tool("generate_crud_page", "Generate a complete Vue 3 CRUD page (.vue SFC) from a natural language description. Supports Chinese and English input. Produces query form, table columns, action buttons, and dialog forms.", {
5
+ description: z
6
+ .string()
7
+ .describe("Natural language description of the CRUD page to generate. Example: '用户管理页面,查询条件有姓名、手机号、状态,表格显示姓名、手机号、邮箱、状态、创建时间,支持新增编辑删除'"),
8
+ }, async ({ description }) => {
9
+ try {
10
+ const result = generateCrudPage(description);
11
+ return {
12
+ content: [
13
+ {
14
+ type: "text",
15
+ text: `${result.summary}\n\n---\n\n${result.code}`,
16
+ },
17
+ ],
18
+ };
19
+ }
20
+ catch (error) {
21
+ return {
22
+ content: [
23
+ {
24
+ type: "text",
25
+ text: `Error generating CRUD page: ${error.message}`,
26
+ },
27
+ ],
28
+ isError: true,
29
+ };
30
+ }
31
+ });
32
+ }
33
+ //# sourceMappingURL=generate-crud-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-crud-page.js","sourceRoot":"","sources":["../../src/tools/generate-crud-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAE7D,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB,+LAA+L,EAC/L;QACE,WAAW,EAAE,CAAC;aACX,MAAM,EAAE;aACR,QAAQ,CACP,4HAA4H,CAC7H;KACJ,EACD,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE;QACxB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;YAC7C,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,cAAc,MAAM,CAAC,IAAI,EAAE;qBACnD;iBACF;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,+BAA+B,KAAK,CAAC,OAAO,EAAE;qBACrD;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerGetComponentApi(server: McpServer): void;
3
+ //# sourceMappingURL=get-component-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-component-api.d.ts","sourceRoot":"","sources":["../../src/tools/get-component-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4KzE,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,QA2BxD"}
@@ -0,0 +1,191 @@
1
+ import { z } from "zod";
2
+ import { COMPONENT_LIST } from "../core/constants.js";
3
+ const COMPONENT_DOCS = {
4
+ EsForm: `# EsForm API
5
+
6
+ ## Props
7
+ | Prop | Type | Description |
8
+ |------|------|-------------|
9
+ | model | \`Record<string, unknown>\` | Form data model (reactive object) |
10
+ | formItemList | \`FormItemOption[]\` | Array of form field configurations |
11
+ | configBtn | \`BtnConfig[]\` | Button configurations (query, reset, etc.) |
12
+ | layoutFormProps | \`LayoutFormProps\` | Layout settings (row/col grid, fold) |
13
+
14
+ ## FormItemOption Interface
15
+ \`\`\`typescript
16
+ interface FormItemOption {
17
+ prop: string // Field key in model
18
+ label: string // Display label
19
+ formtype?: FormType // Input/Select/datePicker/Switch/Rate/Upload/...
20
+ span?: number // Grid span (1-24, default 6)
21
+ attrs?: Record<string, unknown> // Pass-through to Element Plus component
22
+ dataOptions?: Array<{ label: string; value: unknown }> // Options for Select/Radio/Checkbox
23
+ isHidden?: (model, item, formProps) => boolean // Dynamic visibility
24
+ render?: (h, model, ctx) => VNode // Custom render function
25
+ apiParams?: ApiParams // Remote data loading config
26
+ isInitRun?: boolean // Auto-load API data on mount (default true)
27
+ }
28
+ \`\`\`
29
+
30
+ ## BtnConfig Interface
31
+ \`\`\`typescript
32
+ interface BtnConfig {
33
+ name: string // Button text
34
+ key?: string // Identifier (query/reset/add/...)
35
+ type?: 'primary' | 'success' | 'warning' | 'danger' | 'info'
36
+ icon?: string // Element Plus icon name
37
+ triggerEvent?: boolean // If true, triggers table refresh via provide/inject
38
+ click?: (model, formRef, httpRequestInstance?) => void
39
+ }
40
+ \`\`\`
41
+
42
+ ## Instance Methods (via ref)
43
+ - \`validate()\` — Trigger form validation
44
+ - \`resetFields()\` — Reset to initial values
45
+ - \`clearValidate()\` — Clear validation messages
46
+
47
+ ## Key Features
48
+ - Config-driven: define form entirely via JSON
49
+ - Auto grid layout with \`span\` property
50
+ - Fold/expand for query forms
51
+ - Built-in provide/inject linking with EsTable (\`triggerEvent: true\`)
52
+ `,
53
+ EsTable: `# EsTable API
54
+
55
+ ## Props
56
+ | Prop | Type | Description |
57
+ |------|------|-------------|
58
+ | columns | \`TableColumn[]\` | Column definitions |
59
+ | options | \`TableOptions\` | Table behavior configuration |
60
+ | dataSource (v-model) | \`any[]\` | Table data array |
61
+ | pagination (v-model) | \`PaginationConfig\` | Pagination state |
62
+
63
+ ## TableColumn Interface
64
+ \`\`\`typescript
65
+ interface TableColumn {
66
+ prop?: string // Data field key
67
+ label?: string // Column header
68
+ width?: number | string
69
+ minWidth?: number | string
70
+ align?: string // left/center/right (default: center)
71
+ fixed?: boolean | 'left' | 'right'
72
+ groups?: TableColumn[] // Nested group columns
73
+ render?: (h, ctx) => VNode // Custom cell render
74
+ scopedSlots?: { customRender?: string } // Named slot
75
+ btns?: Array<{ name: string; type?: string; clickEvent?: (row) => void }>
76
+ ellipsis?: boolean // Show tooltip on overflow
77
+ hidCol?: boolean // Hide column
78
+ }
79
+ \`\`\`
80
+
81
+ ## TableOptions Interface
82
+ \`\`\`typescript
83
+ interface TableOptions {
84
+ border?: boolean
85
+ stripe?: boolean
86
+ multiSelect?: boolean // Show checkbox column
87
+ snIndex?: boolean // Show row index column
88
+ expand?: boolean // Show expand column
89
+ httpRequest?: (params) => Promise<any> // Data fetching function
90
+ configTableOut?: Record<string, string> // Response field mapping
91
+ rowkey?: string // Row unique key
92
+ isInitRun?: boolean // Auto-fetch on mount (default true)
93
+ heightType?: 'auto' | 'height' // Height mode
94
+ }
95
+ \`\`\`
96
+
97
+ ## Instance Methods (via ref)
98
+ - \`httpRequestInstance(model?)\` — Trigger data fetch
99
+ - \`clearSelection()\` — Clear row selection
100
+ - \`toggleRowSelection(row, selected?)\` — Toggle row checkbox
101
+ - \`refresh()\` — Reload current page
102
+
103
+ ## Key Features
104
+ - Built-in pagination with auto-refresh
105
+ - httpRequest with configTableOut for response mapping
106
+ - Grouped columns via \`groups\` property
107
+ - Operation column via \`btns\` array
108
+ - Auto-linked with EsForm via provide/inject
109
+ `,
110
+ useDialog: `# useDialog API
111
+
112
+ ## Usage
113
+ \`\`\`typescript
114
+ import { useDialog } from 'es-plus-ui'
115
+
116
+ const dialog = useDialog()
117
+
118
+ dialog({
119
+ title: '新增用户',
120
+ width: '500px',
121
+ render: (h, { registerRef }) => (
122
+ <EsForm ref={el => registerRef('form', el)} model={formData} formItemList={items} />
123
+ ),
124
+ configBtn: [
125
+ { name: '取消', click: (_, { close }) => close() },
126
+ { name: '确定', type: 'primary', click: async (_, { close, getRefs }) => {
127
+ await getRefs('form')?.validate()
128
+ // save logic
129
+ close()
130
+ }}
131
+ ]
132
+ })
133
+ \`\`\`
134
+
135
+ ## DialogOptions Interface
136
+ \`\`\`typescript
137
+ interface DialogOptions {
138
+ title?: string
139
+ width?: string | number
140
+ render?: (h, instance, components) => VNode // Dialog body content
141
+ renderHeader?: (h, instance) => VNode // Custom header
142
+ renderFooter?: (h, instance) => VNode // Custom footer
143
+ configBtn?: BtnConfig[] // Footer buttons (auto-generated if not using renderFooter)
144
+ onSubmit?: (close) => void
145
+ onClosed?: () => void
146
+ isDraggable?: boolean // Draggable dialog
147
+ hiddenFullBtn?: boolean // Hide fullscreen toggle
148
+ isHiddenFooter?: boolean // Hide footer entirely
149
+ maxHeight?: string | number
150
+ fullscreen?: boolean
151
+ }
152
+ \`\`\`
153
+
154
+ ## Dialog Instance (available in render/configBtn callbacks)
155
+ - \`close()\` — Close dialog
156
+ - \`registerRef(name, ref)\` — Register a component ref
157
+ - \`getRefs(name)\` — Get registered ref by name
158
+ - \`setLoading(bool)\` — Toggle button loading state
159
+
160
+ ## Key Features
161
+ - Imperative API: call function instead of managing v-model
162
+ - JSX render for dialog body
163
+ - Ref registration for form validation in confirm handler
164
+ - Auto fullscreen button
165
+ - Draggable support
166
+ `,
167
+ };
168
+ export function registerGetComponentApi(server) {
169
+ server.tool("get_component_api", "Get the full API documentation for an es-plus-ui component, including TypeScript interfaces, props, methods, and usage examples.", {
170
+ component: z
171
+ .enum(COMPONENT_LIST)
172
+ .describe("Component name: EsForm, EsTable, or useDialog"),
173
+ }, async ({ component }) => {
174
+ const doc = COMPONENT_DOCS[component];
175
+ if (!doc) {
176
+ return {
177
+ content: [
178
+ {
179
+ type: "text",
180
+ text: `Component "${component}" not found. Available: ${COMPONENT_LIST.join(", ")}`,
181
+ },
182
+ ],
183
+ isError: true,
184
+ };
185
+ }
186
+ return {
187
+ content: [{ type: "text", text: doc }],
188
+ };
189
+ });
190
+ }
191
+ //# sourceMappingURL=get-component-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-component-api.js","sourceRoot":"","sources":["../../src/tools/get-component-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAsB,MAAM,sBAAsB,CAAC;AAE1E,MAAM,cAAc,GAAkC;IACpD,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDT;IAEC,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDV;IAEC,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwDZ;CACA,CAAC;AAEF,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,IAAI,CACT,mBAAmB,EACnB,kIAAkI,EAClI;QACE,SAAS,EAAE,CAAC;aACT,IAAI,CAAC,cAAc,CAAC;aACpB,QAAQ,CAAC,+CAA+C,CAAC;KAC7D,EACD,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QACtB,MAAM,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,cAAc,SAAS,2BAA2B,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;qBACpF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;SACvC,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerTools(server: McpServer): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,QAM9C"}
@@ -0,0 +1,13 @@
1
+ import { registerGenerateCrudPage } from "./generate-crud-page.js";
2
+ import { registerValidateConfig } from "./validate-config.js";
3
+ import { registerListFormTypes } from "./list-form-types.js";
4
+ import { registerGetComponentApi } from "./get-component-api.js";
5
+ import { registerScaffoldPage } from "./scaffold-page.js";
6
+ export function registerTools(server) {
7
+ registerGenerateCrudPage(server);
8
+ registerValidateConfig(server);
9
+ registerListFormTypes(server);
10
+ registerGetComponentApi(server);
11
+ registerScaffoldPage(server);
12
+ }
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,MAAM,UAAU,aAAa,CAAC,MAAiB;IAC7C,wBAAwB,CAAC,MAAM,CAAC,CAAC;IACjC,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAC/B,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAC9B,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAChC,oBAAoB,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}