@restforgejs/mcp-server 1.2.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 (135) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +149 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +7 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/lib/env-parser.d.ts +30 -0
  7. package/dist/lib/env-parser.js +150 -0
  8. package/dist/lib/env-parser.js.map +1 -0
  9. package/dist/lib/exec.d.ts +29 -0
  10. package/dist/lib/exec.js +38 -0
  11. package/dist/lib/exec.js.map +1 -0
  12. package/dist/server.d.ts +1 -0
  13. package/dist/server.js +220 -0
  14. package/dist/server.js.map +1 -0
  15. package/dist/tools/codegen/create-dashboard.d.ts +2 -0
  16. package/dist/tools/codegen/create-dashboard.js +256 -0
  17. package/dist/tools/codegen/create-dashboard.js.map +1 -0
  18. package/dist/tools/codegen/create-endpoint.d.ts +2 -0
  19. package/dist/tools/codegen/create-endpoint.js +263 -0
  20. package/dist/tools/codegen/create-endpoint.js.map +1 -0
  21. package/dist/tools/codegen/dbschema-generate-ddl.d.ts +2 -0
  22. package/dist/tools/codegen/dbschema-generate-ddl.js +187 -0
  23. package/dist/tools/codegen/dbschema-generate-ddl.js.map +1 -0
  24. package/dist/tools/codegen/dbschema-init.d.ts +2 -0
  25. package/dist/tools/codegen/dbschema-init.js +158 -0
  26. package/dist/tools/codegen/dbschema-init.js.map +1 -0
  27. package/dist/tools/codegen/dbschema-introspect.d.ts +2 -0
  28. package/dist/tools/codegen/dbschema-introspect.js +241 -0
  29. package/dist/tools/codegen/dbschema-introspect.js.map +1 -0
  30. package/dist/tools/codegen/dbschema-migrate.d.ts +2 -0
  31. package/dist/tools/codegen/dbschema-migrate.js +219 -0
  32. package/dist/tools/codegen/dbschema-migrate.js.map +1 -0
  33. package/dist/tools/codegen/dbschema-models.d.ts +2 -0
  34. package/dist/tools/codegen/dbschema-models.js +146 -0
  35. package/dist/tools/codegen/dbschema-models.js.map +1 -0
  36. package/dist/tools/codegen/dbschema-validate.d.ts +2 -0
  37. package/dist/tools/codegen/dbschema-validate.js +153 -0
  38. package/dist/tools/codegen/dbschema-validate.js.map +1 -0
  39. package/dist/tools/codegen/describe-table.d.ts +2 -0
  40. package/dist/tools/codegen/describe-table.js +259 -0
  41. package/dist/tools/codegen/describe-table.js.map +1 -0
  42. package/dist/tools/codegen/diff-payload.d.ts +2 -0
  43. package/dist/tools/codegen/diff-payload.js +165 -0
  44. package/dist/tools/codegen/diff-payload.js.map +1 -0
  45. package/dist/tools/codegen/generate-payload.d.ts +2 -0
  46. package/dist/tools/codegen/generate-payload.js +145 -0
  47. package/dist/tools/codegen/generate-payload.js.map +1 -0
  48. package/dist/tools/codegen/get-dashboard-catalog.d.ts +2 -0
  49. package/dist/tools/codegen/get-dashboard-catalog.js +213 -0
  50. package/dist/tools/codegen/get-dashboard-catalog.js.map +1 -0
  51. package/dist/tools/codegen/get-dbschema-catalog.d.ts +2 -0
  52. package/dist/tools/codegen/get-dbschema-catalog.js +244 -0
  53. package/dist/tools/codegen/get-dbschema-catalog.js.map +1 -0
  54. package/dist/tools/codegen/get-field-validation-catalog.d.ts +2 -0
  55. package/dist/tools/codegen/get-field-validation-catalog.js +186 -0
  56. package/dist/tools/codegen/get-field-validation-catalog.js.map +1 -0
  57. package/dist/tools/codegen/get-query-declarative-catalog.d.ts +2 -0
  58. package/dist/tools/codegen/get-query-declarative-catalog.js +200 -0
  59. package/dist/tools/codegen/get-query-declarative-catalog.js.map +1 -0
  60. package/dist/tools/codegen/index.d.ts +2 -0
  61. package/dist/tools/codegen/index.js +43 -0
  62. package/dist/tools/codegen/index.js.map +1 -0
  63. package/dist/tools/codegen/list-tables.d.ts +2 -0
  64. package/dist/tools/codegen/list-tables.js +220 -0
  65. package/dist/tools/codegen/list-tables.js.map +1 -0
  66. package/dist/tools/codegen/sync-payload.d.ts +2 -0
  67. package/dist/tools/codegen/sync-payload.js +177 -0
  68. package/dist/tools/codegen/sync-payload.js.map +1 -0
  69. package/dist/tools/codegen/validate-dashboard-payload.d.ts +2 -0
  70. package/dist/tools/codegen/validate-dashboard-payload.js +239 -0
  71. package/dist/tools/codegen/validate-dashboard-payload.js.map +1 -0
  72. package/dist/tools/codegen/validate-payload.d.ts +2 -0
  73. package/dist/tools/codegen/validate-payload.js +166 -0
  74. package/dist/tools/codegen/validate-payload.js.map +1 -0
  75. package/dist/tools/codegen/validate-sql.d.ts +2 -0
  76. package/dist/tools/codegen/validate-sql.js +270 -0
  77. package/dist/tools/codegen/validate-sql.js.map +1 -0
  78. package/dist/tools/health/index.d.ts +2 -0
  79. package/dist/tools/health/index.js +5 -0
  80. package/dist/tools/health/index.js.map +1 -0
  81. package/dist/tools/health/ping.d.ts +2 -0
  82. package/dist/tools/health/ping.js +68 -0
  83. package/dist/tools/health/ping.js.map +1 -0
  84. package/dist/tools/runtime/check-launcher-exists.d.ts +2 -0
  85. package/dist/tools/runtime/check-launcher-exists.js +111 -0
  86. package/dist/tools/runtime/check-launcher-exists.js.map +1 -0
  87. package/dist/tools/runtime/check-status.d.ts +2 -0
  88. package/dist/tools/runtime/check-status.js +417 -0
  89. package/dist/tools/runtime/check-status.js.map +1 -0
  90. package/dist/tools/runtime/detect-config.d.ts +2 -0
  91. package/dist/tools/runtime/detect-config.js +130 -0
  92. package/dist/tools/runtime/detect-config.js.map +1 -0
  93. package/dist/tools/runtime/detect-project.d.ts +2 -0
  94. package/dist/tools/runtime/detect-project.js +132 -0
  95. package/dist/tools/runtime/detect-project.js.map +1 -0
  96. package/dist/tools/runtime/generate-launcher.d.ts +2 -0
  97. package/dist/tools/runtime/generate-launcher.js +438 -0
  98. package/dist/tools/runtime/generate-launcher.js.map +1 -0
  99. package/dist/tools/runtime/index.d.ts +2 -0
  100. package/dist/tools/runtime/index.js +15 -0
  101. package/dist/tools/runtime/index.js.map +1 -0
  102. package/dist/tools/runtime/validate-preflight.d.ts +2 -0
  103. package/dist/tools/runtime/validate-preflight.js +209 -0
  104. package/dist/tools/runtime/validate-preflight.js.map +1 -0
  105. package/dist/tools/setup/create-folder.d.ts +2 -0
  106. package/dist/tools/setup/create-folder.js +138 -0
  107. package/dist/tools/setup/create-folder.js.map +1 -0
  108. package/dist/tools/setup/get-config-schema.d.ts +2 -0
  109. package/dist/tools/setup/get-config-schema.js +158 -0
  110. package/dist/tools/setup/get-config-schema.js.map +1 -0
  111. package/dist/tools/setup/get-init-template.d.ts +2 -0
  112. package/dist/tools/setup/get-init-template.js +130 -0
  113. package/dist/tools/setup/get-init-template.js.map +1 -0
  114. package/dist/tools/setup/index.d.ts +2 -0
  115. package/dist/tools/setup/index.js +21 -0
  116. package/dist/tools/setup/index.js.map +1 -0
  117. package/dist/tools/setup/init-config.d.ts +2 -0
  118. package/dist/tools/setup/init-config.js +120 -0
  119. package/dist/tools/setup/init-config.js.map +1 -0
  120. package/dist/tools/setup/install-package.d.ts +2 -0
  121. package/dist/tools/setup/install-package.js +133 -0
  122. package/dist/tools/setup/install-package.js.map +1 -0
  123. package/dist/tools/setup/read-env.d.ts +2 -0
  124. package/dist/tools/setup/read-env.js +138 -0
  125. package/dist/tools/setup/read-env.js.map +1 -0
  126. package/dist/tools/setup/update-env.d.ts +2 -0
  127. package/dist/tools/setup/update-env.js +176 -0
  128. package/dist/tools/setup/update-env.js.map +1 -0
  129. package/dist/tools/setup/validate-config.d.ts +2 -0
  130. package/dist/tools/setup/validate-config.js +138 -0
  131. package/dist/tools/setup/validate-config.js.map +1 -0
  132. package/dist/tools/setup/write-env.d.ts +2 -0
  133. package/dist/tools/setup/write-env.js +168 -0
  134. package/dist/tools/setup/write-env.js.map +1 -0
  135. package/package.json +60 -0
package/dist/server.js ADDED
@@ -0,0 +1,220 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { registerHealthTools } from './tools/health/index.js';
4
+ import { registerSetupTools } from './tools/setup/index.js';
5
+ import { registerCodegenTools } from './tools/codegen/index.js';
6
+ import { registerRuntimeTools } from './tools/runtime/index.js';
7
+ const SERVER_NAME = 'restforge-mcp';
8
+ const SERVER_VERSION = '1.0.0';
9
+ const SERVER_INSTRUCTIONS = `
10
+ This MCP server manages RESTForge backend project configuration.
11
+
12
+ WHEN TO PREFER THESE TOOLS over generic filesystem operations:
13
+ - The user asks about project configuration, settings, env values, or "what's set up"
14
+ - The user asks vague questions like "apa yang sudah di-set", "cek project",
15
+ "tampilkan konfigurasi", "is this configured", "what's the status"
16
+ - The user mentions "parameter", "config", "setup", "konfigurasi" in any form
17
+ - The current working directory contains @restforgejs/platform in node_modules
18
+
19
+ In these cases, prefer using RESTForge tools (setup_read_env, etc.) to inspect
20
+ the actual state, rather than reading files manually with filesystem tools or
21
+ guessing from directory structure.
22
+
23
+ If the configuration file does not exist, that is meaningful information —
24
+ the precondition response will tell you, and you should pass that information
25
+ to the user as a question about whether to set up the initial config.
26
+
27
+ Do not enumerate what "should" be in a backend project (folders like src, routes,
28
+ models, etc.). RESTForge has its own conventions; do not assume generic Express
29
+ or NestJS structure.
30
+
31
+ PROACTIVE USAGE:
32
+ When the user works in a project that contains @restforgejs/platform in node_modules,
33
+ prefer these tools over generic file/bash operations for the following:
34
+ - Reading or writing config/db-connection.env
35
+ - Validating config (license, DB, redis, kafka connections)
36
+ - Generating, validating, diffing, or syncing payload JSON files
37
+ - Looking up the field validation catalog before editing payload constraints
38
+ - Installing or upgrading the @restforgejs/platform package
39
+
40
+ Detection signals for "this is a RESTForge project":
41
+ - Folder contains node_modules/@restforgejs/platform, OR
42
+ - Folder contains config/db-connection.env, OR
43
+ - Folder contains a payload/ directory with .json files, OR
44
+ - The user explicitly mentions "RESTForge", "restforge", "@restforgejs/platform", or
45
+ related keywords (payload, codegen, db-connection, license)
46
+
47
+ When uncertain whether a folder is a RESTForge project, call setup_read_env
48
+ first to inspect the config file content — it's a cheap local file read with
49
+ no network calls. Don't assume from filenames alone. (setup_validate_config
50
+ exists too, but it actively connects to the database and license server, so
51
+ reserve it for explicit validation requests, not initial inspection.)
52
+
53
+ Do not silently fall back to generic file/bash operations for the categories
54
+ above. If a request requires an operation outside these tools' scope (e.g.
55
+ DDL changes — see LAYER BOUNDARY below; running, stopping, or restarting the
56
+ server — see RUNTIME LIFECYCLE BOUNDARY below), state that explicitly to the
57
+ user before proceeding.
58
+
59
+ RUNTIME LIFECYCLE BOUNDARY:
60
+ For any user request involving starting, stopping, or restarting the
61
+ RESTForge runtime server (e.g. "run my app", "jalankan server", "start
62
+ restforge", "stop server", "restart server"), you MUST use the runtime_*
63
+ tools — specifically 'runtime_generate_launcher' to scaffold a launcher
64
+ script. Do NOT use the Bash tool to spawn 'npx restforge', 'pm2 start <app>',
65
+ or equivalent processes. Server processes spawned via Bash become children of
66
+ this AI session and will be killed when the session closes (process tree dies
67
+ with the parent).
68
+
69
+ The correct flow is: detect project (runtime_detect_project) → detect config
70
+ (runtime_detect_config) → validate preflight (runtime_validate_preflight) →
71
+ generate launcher (runtime_generate_launcher) → tell the user to execute the
72
+ generated script themselves. The user's terminal, not the AI session, must
73
+ own the running server process. This applies even when the request looks
74
+ short ("just run it") or when running in the background via Bash seems
75
+ convenient — the lifecycle constraint is absolute.
76
+
77
+ Stopping or restarting an already-running server: tell the user the exact
78
+ command or file to execute (e.g. "run server-stop.bat" or "pm2 restart
79
+ <project>"). Do NOT spawn the stop/restart command via Bash on behalf of the
80
+ user. Read-only inspection — 'runtime_check_status', reading the PID file,
81
+ calling 'pm2 jlist' — is allowed because it does not mutate the server
82
+ lifecycle.
83
+
84
+ If the user explicitly insists on a one-off background run despite the
85
+ warning ("I know it will die, just run it for now"), state plainly that the
86
+ process will terminate when this session ends, then comply only as a last
87
+ resort. Default behaviour: refuse Bash-based start and route through the
88
+ runtime_* tools.
89
+
90
+ LAYER BOUNDARY:
91
+ The codegen and setup tools manage application-layer behavior in payload JSON
92
+ files and generated model code. They do NOT modify database DDL (tables,
93
+ columns, indexes, foreign keys, CHECK constraints, UNIQUE constraints).
94
+
95
+ When the user uses SQL DDL terminology — NOT NULL, UNIQUE, CHECK, REFERENCES,
96
+ ALTER TABLE, CREATE INDEX, DEFAULT (in DDL context) — do not automatically map
97
+ to payload validation. Clarify which layer the user wants:
98
+ (a) Application-layer validation in payload (e.g. required, unique, min,
99
+ maxLength, pattern, enum) — handled by these tools
100
+ (b) Database-level DDL changes — out of scope; suggest direct SQL or a
101
+ migration tool
102
+
103
+ Both layers can co-exist for the same field. They serve different purposes:
104
+ DDL enforces at storage level (rejects with database error); payload validation
105
+ provides structured HTTP 400 responses with custom error messages before the
106
+ request reaches the database. Confirm intent before taking action — don't
107
+ conflate the two layers.
108
+
109
+ PROJECT FILE TAXONOMY:
110
+ The RESTForge ecosystem uses three categories of declarative definition files.
111
+ When the user mentions these abbreviations (case-insensitive), recognise and
112
+ route them as follows:
113
+
114
+ - SDF (Schema Definition File): JavaScript factory function (.js) at
115
+ schema/<table>.js that declares table structure for dbschema-kit. Source
116
+ for 'schema migrate' (apply DDL to database) and produced by
117
+ 'schema introspect' (reverse-engineer database).
118
+ Example: <project>/schema/category.js
119
+
120
+ - RDF (Resource Definition File): JSON file (.json) at
121
+ payload/<resource>.json that declares a backend REST API endpoint (CRUD +
122
+ datatables/view/export queries) for the RESTForge generator.
123
+ Example: <project>/payload/category.json
124
+
125
+ - UDF (UI Definition File): JSON file (.json) at payload/NN-<name>.json in
126
+ the frontend project that declares page/component structure for the UI
127
+ generator.
128
+ Example: <frontend-project>/payload/01-category.json
129
+
130
+ Routing for SDF requests:
131
+ - create / init / scaffold -> codegen_dbschema_init
132
+ - validate -> codegen_dbschema_validate
133
+ - list models / show structural summary -> codegen_dbschema_models
134
+ - generate DDL (preview or to file) -> codegen_dbschema_generate_ddl
135
+ - reverse-engineer from database -> codegen_dbschema_introspect
136
+ - apply to database (DESTRUCTIVE) -> codegen_dbschema_migrate
137
+ - lookup syntax / defineModel API spec -> codegen_get_dbschema_catalog
138
+
139
+ Routing for RDF requests:
140
+ - generate from database table -> codegen_generate_payload
141
+ - validate against current database -> codegen_validate_payload
142
+ - diff against database -> codegen_diff_payload
143
+ - sync (merge changes back to JSON) -> codegen_sync_payload
144
+ - generate endpoint module from RDF -> codegen_create_endpoint
145
+ - lookup field validation spec -> codegen_get_field_validation_catalog
146
+ - lookup query declarative spec -> codegen_get_query_declarative_catalog
147
+
148
+ UDF authoring and generation belongs to the frontend generator toolchain,
149
+ which is a separate workflow from this MCP server. This server currently
150
+ covers the SDF (database) layer and the RDF (backend API) layer; the UDF
151
+ layer is handled by the frontend project's own generator. When the user
152
+ asks about UDF — e.g. "generate UDF for category", "scaffold UI from
153
+ payload", "buatkan UDF untuk halaman X" — recognise UDF as a valid
154
+ first-class concept in the ecosystem and respond constructively:
155
+
156
+ 1. Confirm in plain language that you understood the UDF intent (e.g.
157
+ "you want to generate the frontend UI definition for category").
158
+ 2. Explain helpfully that the UDF generation step lives in the frontend
159
+ project and is run by its dedicated generator, separate from this
160
+ server's surface.
161
+ 3. Suggest concrete next steps in the user's frontend project: locate
162
+ the payload/NN-<name>.json file, run the frontend generator there,
163
+ and verify the generated output.
164
+ 4. Offer continued assistance for the SDF and RDF layers (which this
165
+ server DOES cover) — for example, you can still help draft the
166
+ underlying RDF that the frontend will consume.
167
+
168
+ Tone guidance: frame UDF support as "this stage lives in another part of
169
+ the workflow" rather than "this is unsupported" or "I cannot help". UDF
170
+ is recognised as a legitimate ecosystem concept; the assistant should
171
+ sound informed and forward-looking, not dismissive. Match the user's
172
+ language.
173
+
174
+ The three layers serve different purposes and co-exist in the same ecosystem:
175
+ SDF defines database structure, RDF defines backend API behavior on that
176
+ structure, UDF defines the frontend that consumes the API. They MUST NOT be
177
+ conflated — a request about "schema" can mean SDF (database) or RDF (API
178
+ shape) depending on context. When ambiguous, ask the user which layer they
179
+ mean before invoking any tool.
180
+
181
+ KNOWLEDGE BOUNDARY:
182
+ This MCP server provides structured catalog data for SPECIFIC RESTForge
183
+ features that AI agents commonly need for grounding (currently:
184
+ field-validation, query-declarative). It does NOT provide complete
185
+ documentation coverage for every RESTForge feature.
186
+
187
+ When the user asks about RESTForge behavior, syntax, or configuration
188
+ that is NOT covered by an available catalog tool:
189
+ 1. Do NOT fabricate property names, syntax, or behavior from training
190
+ data. RESTForge has its own conventions that may differ from
191
+ similar frameworks (Express, NestJS, Strapi, Hasura, etc.).
192
+ 2. Do NOT guess based on similar frameworks.
193
+ 3. Either:
194
+ (a) Acknowledge that the specific information is not available via
195
+ this MCP server and suggest consulting the canonical docs at
196
+ https://restforge.dev/docs.
197
+ (b) Ask the user to clarify if the question can be reframed to
198
+ match an available catalog tool.
199
+
200
+ Catalog tools are authoritative for the data they expose. The
201
+ documentationUrl returned by each catalog points to narrative
202
+ documentation which may lag behind the most recent npm release; trust
203
+ the catalog data over the URL for property reference, but use the URL
204
+ for use case examples and decision guides.
205
+ `.trim();
206
+ export async function startServer() {
207
+ const server = new McpServer({
208
+ name: SERVER_NAME,
209
+ version: SERVER_VERSION,
210
+ }, {
211
+ instructions: SERVER_INSTRUCTIONS,
212
+ });
213
+ registerHealthTools(server, SERVER_VERSION);
214
+ registerSetupTools(server);
215
+ registerCodegenTools(server);
216
+ registerRuntimeTools(server);
217
+ const transport = new StdioServerTransport();
218
+ await server.connect(transport);
219
+ }
220
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAEhE,MAAM,WAAW,GAAG,eAAe,CAAC;AACpC,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoM3B,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B;QACE,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE,cAAc;KACxB,EACD;QACE,YAAY,EAAE,mBAAmB;KAClC,CACF,CAAC;IAEF,mBAAmB,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC3B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7B,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerCodegenCreateDashboard(server: McpServer): void;
@@ -0,0 +1,256 @@
1
+ import { z } from 'zod';
2
+ import { access } from 'node:fs/promises';
3
+ import { resolve, join } from 'node:path';
4
+ import { execProcess } from '../../lib/exec.js';
5
+ async function pathExists(p) {
6
+ try {
7
+ await access(p);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ export function registerCodegenCreateDashboard(server) {
15
+ server.registerTool('codegen_create_dashboard', {
16
+ title: 'Create Dashboard Module',
17
+ description: `Generate a multi-widget dashboard endpoint module from a payload spec by wrapping restforge dashboard. URL pattern produced: POST /api/{project}/{name}/dashboard.
18
+
19
+ Dashboards differ structurally from CRUD endpoints: there is no table, no fieldValidation, no CRUD actions. The payload declares a 'widgets' array — each widget owns SQL aggregation queries that are embedded into the generated module file and executed in parallel at request time, returning a JSON envelope keyed by widget id.
20
+
21
+ This tool is DESTRUCTIVE: it spawns the CLI which writes / overwrites files in 'src/modules/<project>.js' and 'src/modules/<project>/<name>.js', plus 'metadata/<project>/<name>.json' and updates '.restforge/projects.json'. Single-call semantics: the tool always executes; there is no preview mode. Internally the tool always passes '--force=true' to the CLI to bypass the CLI's interactive y/N readline prompt (which would deadlock in a no-TTY subprocess).
22
+
23
+ Safety net: when the CLI overwrites an existing dashboard module, it FIRST renames the previous version to '<name>.archive.NNN' (NNN is a sequential generation number starting at 001) inside the same folder. Rollback by restoring the most recent archive is always possible.
24
+
25
+ AI responsibility — IMPORTANT: because this tool always executes and may overwrite generated files, you MUST confirm intent with the user in plain language BEFORE invoking the tool. You do NOT need to detect file conflicts programmatically — the CLI handles that and the archive mechanism keeps the previous version safe. Just confirm intent. Examples of good confirmation phrasing in user-facing chat:
26
+ - "Saya akan generate dashboard <name> di project <project>. Kalau modul lama sudah ada, versi sebelumnya akan disimpan sebagai '.archive.NNN'. Lanjut?"
27
+ - "I will generate <name> under project <project>. Existing files will be archived as .archive.NNN before being overwritten. Proceed?"
28
+
29
+ USE WHEN:
30
+ - The user asks to generate, create, or scaffold a dashboard endpoint, multi-widget aggregator, or analytics endpoint (e.g. "buatkan dashboard X di project Y", "generate dashboard sales", "scaffold dashboard inbound dengan payload Z")
31
+ - The user mentions "dashboard", "widget aggregator", "multi-widget", "POST .../dashboard", or terms like "donut breakdown", "metric card", "sparkline" in the context of generating an endpoint
32
+ - The user has authored a payload file with a 'widgets' array (not a CRUD 'tableName' shape) and wants to materialise it as a runnable endpoint
33
+ - Pertanyaan dalam bentuk: "buatkan dashboard X di project Y", "generate dashboard sales", "scaffold dashboard inbound dengan payload Z"
34
+ - The user mentions the URL pattern POST /api/<project>/<name>/dashboard and wants to register it as runnable code
35
+ - The user explicitly references dashboard concepts: scalar collapse rules, widget id, query versus queries, params contract, file:query/*.sql references inside widgets
36
+ - After 'codegen_validate_payload' confirmed a dashboard-shape payload — this is the natural follow-up that turns it into runnable code
37
+ - The user asks to regenerate an existing dashboard after the payload changed (overwrite + archive flow handled by the CLI)
38
+
39
+ DO NOT USE FOR:
40
+ - Generating a CRUD endpoint (payload has 'tableName', 'fieldName', 'action') -> use 'codegen_create_endpoint'
41
+ - Generating the payload JSON itself from a database table -> use 'codegen_generate_payload' (note: codegen_generate_payload targets CRUD payloads — dashboard payloads are typically authored manually)
42
+ - Validating a payload before generation -> use 'codegen_validate_payload'
43
+ - Inspecting per-column differences between payload and database -> use 'codegen_diff_payload'
44
+ - Syncing payload changes back into existing payload files after schema drift -> use 'codegen_sync_payload'
45
+ - Looking up the field validation catalog (dashboards do not have field validation) -> use 'codegen_get_field_validation_catalog' only if discussing CRUD payload fields
46
+ - Looking up the query declarative catalog (dashboards have their own query structure with widgets[].query and widgets[].queries) -> use 'codegen_get_query_declarative_catalog' only if discussing CRUD payload queries
47
+ - Generating a processor (Kafka consumer, etc.) — out of scope; the CLI has separate 'processor' subcommand not covered by this MCP server yet
48
+ - Deleting a dashboard or project — out of scope; the user must run 'npx restforge drop' manually
49
+ - Changing widget visual presentation (widgetType, layout, color, title, subtitle) — those are frontend concerns and forbidden in the dashboard payload (separation of concerns); they belong in the frontend code, not in this generator
50
+
51
+ Cross-reference: this tool is sibling of 'codegen_create_endpoint'. Both generate runnable code from payload JSON, but they consume different payload shapes (CRUD vs dashboard) and produce different artefacts (full module + model vs single dashboard module with embedded SQL).
52
+
53
+ Preconditions:
54
+ - The project must have @restforgejs/platform installed in node_modules.
55
+ - The payload file must exist at <cwd>/payload/<payload>.json before calling this tool.
56
+ - The payload must follow the dashboard schema: a 'widgets' array (NOT a CRUD payload with 'tableName'). The CLI's DashboardValidator rejects payloads that mix shapes, declare forbidden frontend fields (widgetType, layout, title, subtitle, color), have widgets without 'id', have duplicate widget ids, declare both 'query' AND 'queries' in the same widget, declare neither, or use placeholders not declared in 'params'.
57
+ - The dashboard name MUST start with 'dash-' prefix (e.g. dash-sales, dash-inbound). The prefix is required by the CLI and becomes part of the URL segment.
58
+
59
+ PRESENTATION GUIDANCE:
60
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
61
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "the dashboard generator", "validate the payload first", "draft the payload first").
62
+ - Speak in plain language. Summarise the result; do not paste raw CLI output unless the user explicitly asks.
63
+ - This tool is destructive: it can overwrite an existing dashboard module file. BEFORE invoking this tool, ALWAYS confirm with the user in plain language. Example: "Saya akan generate dashboard <name> di project <project>. Kalau modul lama sudah ada, akan ditimpa (versi sebelumnya disimpan sebagai .archive.NNN). Lanjut?". Do not detect conflicts programmatically; the CLI handles that and creates the archive.
64
+ - After the tool runs, summarise the result. Surface the resulting endpoint URL (POST /api/<project>/<name>/dashboard) so the user knows where to call it. Read the CLI output and identify any archive activity using the '.archive.NNN' filesystem convention; surface to the user when archives exist.
65
+ - If the user is confused about the difference between a dashboard and a CRUD endpoint: dashboards aggregate data from multiple SQL queries (widgets) and return a JSON envelope with widget keys; CRUD endpoints expose actions like /datatables, /read, /create, /update, /delete on a single table. Suggest the right tool based on what the user is actually building.
66
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
67
+ inputSchema: {
68
+ cwd: z
69
+ .string()
70
+ .min(1)
71
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform and a payload/ directory with the named payload file)'),
72
+ project: z
73
+ .string()
74
+ .min(1)
75
+ .max(50)
76
+ .regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, 'must start with a letter or number; only letters, numbers, dashes, underscores allowed')
77
+ .describe('Project name. Letters/numbers/dash/underscore, max 50 chars, cannot start or end with dash or underscore. Auto-lowercased by the CLI. Reserved names rejected by the CLI: src, lib, node_modules, config, utils, models, controllers, middleware, routes.'),
78
+ name: z
79
+ .string()
80
+ .min(6)
81
+ .max(50)
82
+ .regex(/^dash-[a-zA-Z0-9_-]+$/, "must start with 'dash-' prefix and have at least one character after it (e.g. dash-sales, dash-inbound)")
83
+ .describe("Dashboard name. MUST start with 'dash-' prefix. The prefix is required by the CLI and becomes part of the URL segment (POST /api/{project}/{name}/dashboard). The full name is the URL slug, e.g. dash-sales, dash-inbound. The CLI rejects 'dash-' alone — there must be at least one character after the prefix."),
84
+ payload: z
85
+ .string()
86
+ .min(1)
87
+ .max(50)
88
+ .regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, 'must start with a letter or number; only letters, numbers, dashes, underscores allowed')
89
+ .describe('Payload file name without the .json extension. The file must exist at <cwd>/payload/<payload>.json. Payload must follow the dashboard schema (with a `widgets` array; NOT a CRUD payload with `tableName`).'),
90
+ database: z
91
+ .enum(['postgres', 'oracle', 'mysql'])
92
+ .optional()
93
+ .describe('Database type for the generated code. Default postgres.'),
94
+ skipSqlValidation: z
95
+ .boolean()
96
+ .optional()
97
+ .describe('Default false (CLI default). When true, skip SQL keyword validation in payload widget queries. Useful when the SQL fragments are intentional but the validator flags them as suspicious.'),
98
+ },
99
+ annotations: {
100
+ title: 'Create Dashboard Module',
101
+ readOnlyHint: false, // tool spawns CLI that writes module/metadata files and updates the registry
102
+ destructiveHint: true, // can overwrite an existing dashboard module file (CLI archives it as .archive.NNN first)
103
+ idempotentHint: false, // re-running creates new archive files
104
+ },
105
+ }, async ({ cwd, project, name, payload, database, skipSqlValidation }) => {
106
+ const projectCwd = resolve(cwd);
107
+ const dbType = database ?? 'postgres';
108
+ // Pre-flight 1: @restforgejs/platform must be installed. Treated as a non-error precondition per §3.4.
109
+ try {
110
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
111
+ }
112
+ catch {
113
+ return {
114
+ content: [
115
+ {
116
+ type: 'text',
117
+ text: `Precondition not met: the RESTForge package is not installed in this project.
118
+
119
+ Project path: ${projectCwd}
120
+ Expected location: node_modules/@restforgejs/platform
121
+ Requested project: ${project}
122
+ Requested dashboard: ${name}
123
+ Requested payload: ${payload}
124
+ Requested database: ${dbType}
125
+
126
+ For the assistant:
127
+ - The dashboard generator can only run once the RESTForge package is installed locally.
128
+ - Suggest installing the package first, then retry generating the dashboard.
129
+ - When explaining to the user, say something like "the RESTForge package isn't installed yet — should I install it first?". Do not mention internal tool names.`,
130
+ },
131
+ ],
132
+ isError: false, // per §3.4
133
+ };
134
+ }
135
+ // Pre-flight 2: payload file must exist. Treated as a non-error precondition per §3.4.
136
+ const payloadPath = join(projectCwd, 'payload', `${payload}.json`);
137
+ if (!(await pathExists(payloadPath))) {
138
+ return {
139
+ content: [
140
+ {
141
+ type: 'text',
142
+ text: `Precondition not met: payload file not found.
143
+
144
+ Project path: ${projectCwd}
145
+ Expected payload file: ${payloadPath}
146
+ Requested project: ${project}
147
+ Requested dashboard: ${name}
148
+ Requested database: ${dbType}
149
+
150
+ For the assistant:
151
+ - The dashboard generator needs the payload file to exist before it can run.
152
+ - Suggest creating or locating the payload first. Dashboard payloads have a different schema than CRUD payloads (a \`widgets\` array instead of \`tableName\`); see the dashboard documentation if the user is unfamiliar with the format.
153
+ - When explaining to the user, say something like "the payload file '${payload}.json' isn't in the payload/ folder yet — should I help you draft it, or do you have one to put there?". Do not mention internal tool names.`,
154
+ },
155
+ ],
156
+ isError: false, // per §3.4
157
+ };
158
+ }
159
+ // Build CLI invocation. --force=true is hardcoded: it bypasses the interactive readline
160
+ // prompt that would otherwise deadlock the subprocess. Conflict detection and archive
161
+ // creation are delegated to the CLI (single source of truth — see refactor 8C).
162
+ const cliArgs = [
163
+ 'restforge',
164
+ 'dashboard',
165
+ 'create',
166
+ `--project=${project}`,
167
+ `--name=${name}`,
168
+ `--payload=${payload}`,
169
+ `--database=${dbType}`,
170
+ '--force=true',
171
+ ];
172
+ if (skipSqlValidation !== undefined)
173
+ cliArgs.push(`--skip-sql-validation=${skipSqlValidation}`);
174
+ const result = await execProcess('npx', cliArgs, {
175
+ cwd: projectCwd,
176
+ timeout: 60_000,
177
+ env: { NODE_ENV: 'production' }, // suppress legacy banner output
178
+ stripFinalNewline: true,
179
+ });
180
+ // Branch C: CLI failure — real error per §3.4; structured per §3.5.
181
+ if (!result.success) {
182
+ return {
183
+ content: [
184
+ {
185
+ type: 'text',
186
+ text: `Failed to create the dashboard module.
187
+
188
+ Project path: ${projectCwd}
189
+ Project: ${project}
190
+ Dashboard: ${name}
191
+ Payload: payload/${payload}.json
192
+ Database: ${dbType}
193
+ Command: ${result.command}
194
+ Exit code: ${result.exitCode}
195
+
196
+ --- CLI output ---
197
+ stdout:
198
+ ${result.stdout}
199
+
200
+ stderr:
201
+ ${result.stderr}
202
+ --- end CLI output ---
203
+
204
+ For the assistant:
205
+ - Tell the user that creating the dashboard module did not complete successfully.
206
+ - Summarise the most likely cause from the CLI output in plain language. Common causes:
207
+ * Dashboard name did not start with 'dash-' prefix — suggest renaming (e.g. 'sales' becomes 'dash-sales').
208
+ * Payload uses CRUD shape (has 'tableName') instead of dashboard shape (has 'widgets') — suggest reviewing the payload structure or pointing to dashboard documentation.
209
+ * Payload contains forbidden frontend fields (widgetType, layout, title, subtitle, color) — those are frontend concerns and must be removed.
210
+ * Widget without 'id', duplicate widget id, or widget that declares both 'query' AND 'queries' (or neither) — suggest reviewing the widgets array.
211
+ * Widget SQL uses an undeclared placeholder (e.g. ':year' but 'year' missing from 'params') — suggest declaring the missing param or removing the placeholder.
212
+ * Database mismatch with the existing project registry entry — the CLI refuses to switch the database. Suggest sticking with the originally registered database.
213
+ * Reserved project name rejected by the validator — suggest a different project name.
214
+ - Do not paste the raw stdout/stderr unless the user explicitly asks. Do not mention internal tool names.
215
+ - Offer to retry once the underlying issue is resolved.`,
216
+ },
217
+ ],
218
+ isError: true, // per §3.4
219
+ };
220
+ }
221
+ // Branch B: CLI success — one-line summary + labeled facts + fenced output per §3.5.
222
+ return {
223
+ content: [
224
+ {
225
+ type: 'text',
226
+ text: `Dashboard module created successfully.
227
+
228
+ Project path: ${projectCwd}
229
+ Project: ${project}
230
+ Dashboard: ${name}
231
+ Payload: payload/${payload}.json
232
+ Database: ${dbType}
233
+ Endpoint: POST /api/${project}/${name}/dashboard
234
+
235
+ Generated artefacts (commonly produced by the CLI):
236
+ - src/modules/${project}.js (main module — created or refreshed)
237
+ - src/modules/${project}/${name}.js (dashboard handler with embedded SQL)
238
+ - metadata/${project}/${name}.json (dashboard metadata)
239
+ - .restforge/projects.json (registry update)
240
+
241
+ --- CLI output ---
242
+ ${result.stdout}
243
+ --- end CLI output ---
244
+
245
+ For the assistant:
246
+ - Confirm to the user in plain language that the dashboard endpoint was generated. Mention the project, dashboard name, and the resulting URL: POST /api/${project}/${name}/dashboard.
247
+ - Do not paste the entire CLI output unless the user explicitly asks; summarise instead.
248
+ - Read the CLI output to identify any archive activity (the CLI uses the '.archive.NNN' naming convention in the filesystem and reports archive activity in its output, but the exact phrasing may evolve). When archives are created, tell the user that the previous version of the dashboard module is preserved in case rollback is needed.
249
+ - Suggest natural follow-up actions appropriate to context: review the generated module, run the project to test the new dashboard endpoint, draft a frontend caller, etc. Do not mention internal tool names.
250
+ - Match the user's language.`,
251
+ },
252
+ ],
253
+ };
254
+ });
255
+ }
256
+ //# sourceMappingURL=create-dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-dashboard.js","sourceRoot":"","sources":["../../../src/tools/codegen/create-dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerCodegenCreateEndpoint(server: McpServer): void;