@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
@@ -0,0 +1,239 @@
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 registerCodegenValidateDashboardPayload(server) {
15
+ server.registerTool('codegen_validate_dashboard_payload', {
16
+ title: 'Validate Dashboard Payload',
17
+ description: `Validate the structural correctness of a dashboard payload spec WITHOUT generating any file, by wrapping restforge dashboard --validate-only=true.
18
+
19
+ Dashboards have a different shape than CRUD endpoints (widgets array, no tableName, no fieldValidation). The CLI's DashboardValidator checks: widgets array shape, allowed/forbidden fields per level, the 'query' vs 'queries' mutual exclusion, params contract (each ':placeholder' used in SQL must be declared in 'params'), 'file:query/<name>.sql' reference resolution, and that no frontend-only fields (widgetType, layout, title, subtitle, color) leak into the payload.
20
+
21
+ This tool is READ-ONLY: it does NOT write any file, does NOT touch the database, does NOT update the project registry. It only reports whether the payload structure is valid. Re-running with the same input gives the same result (idempotent).
22
+
23
+ Workflow positioning: this is the natural pre-flight before 'codegen_create_dashboard'. When the AI authors a dashboard payload (manually via Write), call this tool first to surface validation errors cheaply — before invoking the generator that performs filesystem writes.
24
+
25
+ Gap closed: the general 'codegen_validate_payload' tool silently skips dashboard payloads (it filters on 'tableName' and 'fieldName'). This tool fills that gap for the dashboard shape.
26
+
27
+ USE WHEN:
28
+ - The user asks to validate, check, or verify the structure of a dashboard payload before generating
29
+ - The user has authored a dashboard payload (with 'widgets' array) and wants to confirm it parses correctly before invoking the generator
30
+ - Pertanyaan dalam bentuk: "cek dashboard payload saya valid?", "validate dashboard config", "is this dashboard schema correct?", "apakah payload dashboard ini OK?"
31
+ - Before invoking 'codegen_create_dashboard' — pre-flight to surface validation errors early (cheaper than failing inside the generator stage, which performs filesystem writes)
32
+ - The user reports that 'codegen_create_dashboard' failed with a validation-related error and wants to fix the payload iteratively
33
+ - The user mentions specific dashboard validation rules: forbidden frontend fields (widgetType, layout, title, subtitle, color), 'query' vs 'queries' mutex, params placeholder declaration
34
+ - After the user manually edited a dashboard payload and wants a quick sanity check before re-running the generator
35
+ - The user is unsure whether their payload follows dashboard shape (widgets) or CRUD shape (tableName) and wants verification
36
+
37
+ DO NOT USE FOR:
38
+ - Validating a CRUD payload (with 'tableName' and 'fieldName') against database schema -> use 'codegen_validate_payload'
39
+ - Generating the dashboard module after validation -> use 'codegen_create_dashboard'
40
+ - Inspecting drift between CRUD payload and database -> use 'codegen_validate_payload' (this dashboard validator does NOT touch the database)
41
+ - Generating a payload from scratch -> use 'codegen_generate_payload' for CRUD; for dashboard, the user authors manually
42
+ - Looking up the field validation catalog -> use 'codegen_get_field_validation_catalog' (different scope; dashboard payloads have no fieldValidation)
43
+ - Validating SQL syntax inside a widget query — the validator only checks placeholder declarations and structural shape, not SQL semantics. SQL errors will only surface when the dashboard endpoint is actually called at runtime.
44
+
45
+ Cross-reference: this tool is the read-only sibling of 'codegen_create_dashboard'. Both have nearly identical input schemas, but this tool only validates and does NOT generate any file.
46
+
47
+ Preconditions:
48
+ - The project must have @restforgejs/platform installed in node_modules.
49
+ - The payload file must exist at <cwd>/payload/<payload>.json before calling this tool.
50
+ - The dashboard name MUST start with 'dash-' prefix (CLI requirement). For validate-only mode, this is checked at the argument-parser level even though the value is not used to write any file.
51
+
52
+ PRESENTATION GUIDANCE:
53
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
54
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "validate the dashboard payload", "generate the dashboard module").
55
+ - Speak in plain language. Summarise the result; do not paste raw CLI output unless the user explicitly asks.
56
+ - This tool is read-only: it validates payload structure without writing files or touching the database. Safe to invoke proactively before 'codegen_create_dashboard' to give the user faster feedback on payload errors.
57
+ - If validation passes, briefly confirm the result and offer to proceed with generation. If validation fails, surface the specific error in plain language and offer to help fix it. Do not paste raw CLI output unless the user explicitly asks.
58
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
59
+ inputSchema: {
60
+ cwd: z
61
+ .string()
62
+ .min(1)
63
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform and a payload/ directory with the named payload file)'),
64
+ project: z
65
+ .string()
66
+ .min(1)
67
+ .max(50)
68
+ .regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, 'must start with a letter or number; only letters, numbers, dashes, underscores allowed')
69
+ .describe('Project name. Required by the CLI argument schema even in validate-only mode. Letters/numbers/dash/underscore, max 50 chars.'),
70
+ name: z
71
+ .string()
72
+ .min(6)
73
+ .max(50)
74
+ .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)")
75
+ .describe("Dashboard name. MUST start with 'dash-' prefix (CLI requirement). For validate-only mode, this is checked at the argument-parser level even though the value is not used to write any file. The CLI rejects 'dash-' alone — there must be at least one character after the prefix."),
76
+ payload: z
77
+ .string()
78
+ .min(1)
79
+ .max(50)
80
+ .regex(/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/, 'must start with a letter or number; only letters, numbers, dashes, underscores allowed')
81
+ .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`).'),
82
+ database: z
83
+ .enum(['postgres', 'oracle', 'mysql'])
84
+ .optional()
85
+ .describe('Database type. Default postgres. Database connection is NOT used in validate-only mode (validation is structural, not drift-based), but kept for argument-schema parity with codegen_create_dashboard.'),
86
+ skipSqlValidation: z
87
+ .boolean()
88
+ .optional()
89
+ .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.'),
90
+ },
91
+ annotations: {
92
+ title: 'Validate Dashboard Payload',
93
+ readOnlyHint: true, // pure validation, no filesystem write, no DB write
94
+ idempotentHint: true, // re-running gives same result for same input
95
+ },
96
+ }, async ({ cwd, project, name, payload, database, skipSqlValidation }) => {
97
+ const projectCwd = resolve(cwd);
98
+ const dbType = database ?? 'postgres';
99
+ // Pre-flight 1: @restforgejs/platform must be installed. Treated as a non-error precondition per §3.4.
100
+ try {
101
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
102
+ }
103
+ catch {
104
+ return {
105
+ content: [
106
+ {
107
+ type: 'text',
108
+ text: `Precondition not met: the RESTForge package is not installed in this project.
109
+
110
+ Project path: ${projectCwd}
111
+ Expected location: node_modules/@restforgejs/platform
112
+ Requested project: ${project}
113
+ Requested dashboard: ${name}
114
+ Requested payload: ${payload}
115
+
116
+ For the assistant:
117
+ - The dashboard payload validator can only run once the RESTForge package is installed locally.
118
+ - Suggest installing the package first, then retry validating the dashboard payload.
119
+ - 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.`,
120
+ },
121
+ ],
122
+ isError: false, // per §3.4
123
+ };
124
+ }
125
+ // Pre-flight 2: payload file must exist. Treated as a non-error precondition per §3.4.
126
+ const payloadPath = join(projectCwd, 'payload', `${payload}.json`);
127
+ if (!(await pathExists(payloadPath))) {
128
+ return {
129
+ content: [
130
+ {
131
+ type: 'text',
132
+ text: `Precondition not met: payload file not found.
133
+
134
+ Project path: ${projectCwd}
135
+ Expected payload file: ${payloadPath}
136
+ Requested project: ${project}
137
+ Requested dashboard: ${name}
138
+ Requested payload: ${payload}
139
+
140
+ For the assistant:
141
+ - The dashboard payload validator needs the payload file to exist before it can run.
142
+ - 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.
143
+ - 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.`,
144
+ },
145
+ ],
146
+ isError: false, // per §3.4
147
+ };
148
+ }
149
+ // Build CLI invocation. --validate-only=true is hardcoded: this tool is ONLY for validation.
150
+ // --force is NOT passed (not relevant for validate-only — no overwrite scenario).
151
+ // Validation logic itself is delegated to the CLI's DashboardValidator (single source of
152
+ // truth — see refactor 8C).
153
+ const cliArgs = [
154
+ 'restforge',
155
+ 'dashboard',
156
+ 'create',
157
+ `--project=${project}`,
158
+ `--name=${name}`,
159
+ `--payload=${payload}`,
160
+ `--database=${dbType}`,
161
+ '--validate-only=true',
162
+ ];
163
+ if (skipSqlValidation !== undefined)
164
+ cliArgs.push(`--skip-sql-validation=${skipSqlValidation}`);
165
+ const result = await execProcess('npx', cliArgs, {
166
+ cwd: projectCwd,
167
+ timeout: 30_000, // validation is light: no DB connection, no filesystem write
168
+ env: { NODE_ENV: 'production' }, // suppress legacy banner output
169
+ stripFinalNewline: true,
170
+ });
171
+ // Branch C: CLI failure (validation failed or other) — real error per §3.4; structured per §3.5.
172
+ if (!result.success) {
173
+ return {
174
+ content: [
175
+ {
176
+ type: 'text',
177
+ text: `Dashboard payload validation failed.
178
+
179
+ Project path: ${projectCwd}
180
+ Project: ${project}
181
+ Dashboard: ${name}
182
+ Payload: payload/${payload}.json
183
+ Command: ${result.command}
184
+ Exit code: ${result.exitCode}
185
+
186
+ --- CLI output ---
187
+ stdout:
188
+ ${result.stdout}
189
+
190
+ stderr:
191
+ ${result.stderr}
192
+ --- end CLI output ---
193
+
194
+ For the assistant:
195
+ - Tell the user that the dashboard payload validation did not pass. Surface the error message from the CLI output (typically a single 'Error: ...' line) in plain language.
196
+ - Common validation errors and suggested fixes:
197
+ * 'must not contain tableName' — the payload has CRUD shape; remove 'tableName' or use the CRUD payload validator instead (do not mention internal tool name; describe the action).
198
+ * 'must have widgets array' — payload is missing the 'widgets' field; suggest adding it with at least one entry.
199
+ * 'must declare either query or queries' — a widget is missing both fields; pick one based on whether the widget needs single SQL or multi-SQL.
200
+ * 'undeclared placeholder' — SQL uses ':param_name' that is not declared in 'params'; add it to 'params' or remove the placeholder from SQL.
201
+ * 'forbidden frontend field' (widgetType, layout, title, subtitle, color) — those belong in the frontend code; remove them from the payload.
202
+ * 'invalid type' for params — the param type must be one of: string, number, boolean, date.
203
+ * 'duplicate widget id' — two widgets share the same id; pick distinct ids.
204
+ - Offer to help fix the payload and retry validation.
205
+ - Do not paste the raw stdout/stderr unless the user explicitly asks. Do not mention internal tool names.`,
206
+ },
207
+ ],
208
+ isError: true, // per §3.4
209
+ };
210
+ }
211
+ // Branch B: CLI success (validation passed) — one-line summary + labeled facts + fenced output per §3.5.
212
+ return {
213
+ content: [
214
+ {
215
+ type: 'text',
216
+ text: `Dashboard payload validation passed.
217
+
218
+ Project path: ${projectCwd}
219
+ Project: ${project}
220
+ Dashboard: ${name}
221
+ Payload: payload/${payload}.json
222
+
223
+ --- CLI output ---
224
+ ${result.stdout}
225
+ --- end CLI output ---
226
+
227
+ For the assistant:
228
+ - Confirm to the user in plain language that the dashboard payload structure is valid.
229
+ - This validation does NOT touch the database or write any file. It only checks payload structure (widgets array shape, allowed/forbidden fields, params contract, file:reference resolution, placeholder declaration).
230
+ - If the user requested validation as a precursor to generation, the next step is to generate the dashboard module. Do not mention internal tool names; describe the action ("generate the dashboard module").
231
+ - If the CLI output mentions warnings (lines starting with '! Warning'), surface them to the user — these are non-fatal but worth knowing.
232
+ - Do not paste the full CLI output unless the user explicitly asks; summarise instead.
233
+ - Match the user's language.`,
234
+ },
235
+ ],
236
+ };
237
+ });
238
+ }
239
+ //# sourceMappingURL=validate-dashboard-payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-dashboard-payload.js","sourceRoot":"","sources":["../../../src/tools/codegen/validate-dashboard-payload.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 registerCodegenValidatePayload(server: McpServer): void;
@@ -0,0 +1,166 @@
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
+ export function registerCodegenValidatePayload(server) {
6
+ server.registerTool('codegen_validate_payload', {
7
+ title: 'Validate Payload',
8
+ description: `Validate that existing payload spec files in a project are still in sync with the current database schema, by running restforge payload --validate.
9
+
10
+ USE WHEN:
11
+ - The user asks to validate, check, or verify whether existing payload files are still in sync with the current database schema
12
+ - The user asks things like "cek drift payload", "validate semua payload", "apakah payload masih sinkron", "is the schema in sync", "check schema drift"
13
+ - The user mentions ALTER TABLE in the database and wants to know which payloads are affected
14
+ - Routine drift check after pulling new database migrations
15
+ - Periodic audit of payload files in a project
16
+ - Often called before 'codegen_diff_payload' as a quick overall status pass; if a file shows DRIFT, follow up with 'codegen_diff_payload' to see column-level details.
17
+ - The user wants to validate PAYLOAD FILES against the database schema, not configuration credentials
18
+
19
+ DO NOT USE FOR:
20
+ - Seeing the per-column detail of what changed -> use 'codegen_diff_payload'
21
+ - Generating a payload from scratch for a table that has no payload yet -> use 'codegen_generate_payload'
22
+ - Updating payload files to match the database -> use 'codegen_sync_payload'
23
+ - Checking the database connection, license, or other config credentials -> use 'setup_validate_config'
24
+
25
+ This tool runs: npx restforge payload --validate --config=<config> [--table=<table>] [--output=<output>] in the given cwd.
26
+ The CLI reads existing payload JSON files from the output directory, connects to the database described
27
+ in the config file, and reports per-file status (typically OK / DRIFT / ERROR) without modifying any file.
28
+
29
+ Preconditions:
30
+ - The project must have @restforgejs/platform installed in node_modules.
31
+ - The config file (default 'db-connection.env') must exist in the project and contain valid
32
+ database credentials. This tool does not pre-check that — if the CLI fails, the failure response
33
+ will surface the underlying cause.
34
+
35
+ PRESENTATION GUIDANCE:
36
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
37
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "validate the payload files", "see the column-level differences", "sync the payload files").
38
+ - Speak in plain language. Summarise the result; do not paste raw CLI output unless the user explicitly asks.
39
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
40
+ inputSchema: {
41
+ cwd: z
42
+ .string()
43
+ .min(1)
44
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform and the config file)'),
45
+ config: z
46
+ .string()
47
+ .min(1)
48
+ .default('db-connection.env')
49
+ .describe('Config file name (relative to project) used by the CLI to connect to the database'),
50
+ table: z
51
+ .string()
52
+ .min(1)
53
+ .optional()
54
+ .describe('Specific table name to check (e.g. supplier or core.supplier). When omitted, all payload files in the output directory are checked.'),
55
+ output: z
56
+ .string()
57
+ .min(1)
58
+ .optional()
59
+ .describe('Payload directory relative to project (e.g. payload). When omitted, the CLI uses its default (payload/).'),
60
+ },
61
+ annotations: {
62
+ title: 'Validate Payload',
63
+ readOnlyHint: true,
64
+ idempotentHint: true,
65
+ },
66
+ }, async ({ cwd, config, table, output }) => {
67
+ const projectCwd = resolve(cwd);
68
+ // Precondition check: @restforgejs/platform must be present in node_modules.
69
+ // Treated as a non-error precondition per the authoring guide §3.4.
70
+ try {
71
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
72
+ }
73
+ catch {
74
+ return {
75
+ content: [
76
+ {
77
+ type: 'text',
78
+ text: `Precondition not met: the RESTForge package is not installed in this project.
79
+
80
+ Project path: ${projectCwd}
81
+ Expected location: node_modules/@restforgejs/platform
82
+ Requested table: ${table ?? 'all'}
83
+ Requested config: ${config}
84
+ Requested output: ${output ?? 'default (payload/)'}
85
+
86
+ For the assistant:
87
+ - The user needs to install the RESTForge package before payload files can be validated against the database schema.
88
+ - Use the appropriate package-installation tool to do this, then retry validating the payload.
89
+ - 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.`,
90
+ },
91
+ ],
92
+ isError: false, // per §3.4
93
+ };
94
+ }
95
+ // Forward only the arguments the user supplied. Defaults inside restforge
96
+ // (e.g. payload/ as the default output dir, all files when --table is omitted)
97
+ // should remain in effect when the user does not specify them. per §3.5
98
+ const args = ['restforge', 'payload', 'validate', `--config=${config}`];
99
+ if (table)
100
+ args.push(`--table=${table}`);
101
+ if (output)
102
+ args.push(`--output=${output}`);
103
+ const result = await execProcess('npx', args, { cwd: projectCwd, timeout: 30_000 });
104
+ // CLI failure: real error per §3.4; structured per §3.5.
105
+ if (!result.success) {
106
+ return {
107
+ content: [
108
+ {
109
+ type: 'text',
110
+ text: `Failed to validate payload.
111
+
112
+ Project path: ${projectCwd}
113
+ Config: ${config}
114
+ Table: ${table ?? 'all'}
115
+ Output: ${output ?? 'default (payload/)'}
116
+ Command: ${result.command}
117
+ Exit code: ${result.exitCode}
118
+
119
+ --- CLI output ---
120
+ stdout:
121
+ ${result.stdout}
122
+
123
+ stderr:
124
+ ${result.stderr}
125
+ --- end CLI output ---
126
+
127
+ For the assistant:
128
+ - Tell the user that the payload validation did not complete successfully.
129
+ - Summarise the likely cause from the CLI output in plain language (common causes: the config file is missing or has incomplete credentials, the database is unreachable, the requested table does not exist, or the payload directory is empty). Do not paste the raw stdout/stderr unless the user explicitly asks.
130
+ - Offer to retry once the underlying issue is resolved. Do not mention internal tool names.`,
131
+ },
132
+ ],
133
+ isError: true, // per §3.4
134
+ };
135
+ }
136
+ // Success: one-line summary + labeled facts + fenced raw output per §3.5.
137
+ // The CLI prints a Summary section with counts (OK / DRIFT / ERROR); the
138
+ // model should extract those numbers from stdout when talking to the user.
139
+ return {
140
+ content: [
141
+ {
142
+ type: 'text',
143
+ text: `Payload validation completed.
144
+
145
+ Project path: ${projectCwd}
146
+ Config: ${config}
147
+ Table: ${table ?? 'all'}
148
+ Output: ${output ?? 'default (payload/)'}
149
+ Command: ${result.command}
150
+
151
+ --- CLI output ---
152
+ ${result.stdout}
153
+ --- end CLI output ---
154
+
155
+ For the assistant:
156
+ - Read the Summary section in the CLI output above and tell the user how many payload files are OK, in DRIFT, or in ERROR.
157
+ - If every file is OK, confirm in plain language that the payload files are still in sync with the database.
158
+ - If any file is in DRIFT or ERROR, suggest as the next step that the user can see the column-level differences for the affected file (added, removed, or changed columns). Do not name the internal tool — describe it by what it does.
159
+ - If the user later wants to apply those changes, mention that the next step is to update the payload files automatically (with the previous version archived). Describe this step in plain language; do not name the internal tool.
160
+ - Keep the reply concise. Do not paste the raw CLI output unless the user explicitly asks. Do not mention internal tool names.`,
161
+ },
162
+ ],
163
+ };
164
+ });
165
+ }
166
+ //# sourceMappingURL=validate-payload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-payload.js","sourceRoot":"","sources":["../../../src/tools/codegen/validate-payload.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 registerCodegenValidateSql(server: McpServer): void;