@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,241 @@
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 registerCodegenDbschemaIntrospect(server) {
6
+ server.registerTool('codegen_dbschema_introspect', {
7
+ title: 'Introspect Database into dbschema-kit Files',
8
+ description: `Reverse-engineer an existing database into dbschema-kit definition files (factory function pattern), by wrapping restforge schema introspect. Useful for migrating legacy projects to declarative schema-as-code, or for capturing the current database structure under version control. Mode (single-table, bulk single-schema, bulk multi-schema, all-schemas) is derived from the combination of 'table', 'schema', 'allSchemas', and 'output'.
9
+
10
+ USE WHEN:
11
+ - The user asks to reverse-engineer a database, "buatkan schema dari database existing", "introspect DB ke schema files"
12
+ - Pertanyaan dalam bentuk: "convert legacy DB ke dbschema", "extract schema from production DB", "buat schema-as-code dari DB yang sudah ada"
13
+ - Migration project from a non-declarative DB to schema-as-code
14
+ - Before refactoring an existing database — to capture the current state in version control
15
+ - The user wants a starting point for the dbschema workflow but already has a populated database
16
+ - Single-table snapshot for documentation or comparison
17
+ - Multi-schema database where the user wants per-schema folder layout
18
+ - Dry-run preview before committing to file write
19
+
20
+ DO NOT USE FOR:
21
+ - Listing live database tables (no file write) -> use 'codegen_list_tables'
22
+ - Describing a single live table (no file write) -> use 'codegen_describe_table'
23
+ - Generating a CRUD payload from DB -> use 'codegen_generate_payload'
24
+ - Validating an existing schema file -> use 'codegen_dbschema_validate'
25
+ - Modifying database schema (CREATE/ALTER/DROP) -> use 'codegen_dbschema_migrate'
26
+ - Querying actual row data -> out of scope (returns metadata only)
27
+
28
+ This tool runs: npx restforge schema introspect --config=<file> [--output=<path>] [--table=<name>] [--schema=<name>] [--all-schemas] [--force] [--dry-run] in the given cwd.
29
+ The mode is derived by the CLI from the flag combination. The MCP layer passes flags through and does not validate mutual exclusivity — the CLI is the single source of truth for mode resolution.
30
+
31
+ Preconditions:
32
+ - The project must have @restforgejs/platform installed in node_modules.
33
+ - The config file (default 'db-connection.env') must exist and contain valid database credentials.
34
+ - 'output' is required unless 'dryRun' is true.
35
+
36
+ PRESENTATION GUIDANCE:
37
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
38
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "introspect the database", "validate the schema", "preview before writing").
39
+ - Speak in plain language. Confirm the mode (single-table / bulk / dry-run) and the output target; do not paste raw CLI output unless the user explicitly asks.
40
+ - Mode is derived from the combination of 'table', 'schema', 'allSchemas', and 'output'. Confirm with the user before invoking — different modes produce different file layouts (flat vs subfolder).
41
+ - Without 'force', the tool refuses to overwrite existing files. If the user wants to refresh introspection, confirm before passing force=true.
42
+ - 'dryRun=true' is the safe path for preview. Suggest dry-run first when the user is exploring an unfamiliar database.
43
+ - This is a write operation in non-dry-run mode. Files in the output target may have been created or overwritten.
44
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
45
+ inputSchema: {
46
+ cwd: z
47
+ .string()
48
+ .min(1)
49
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform and the config file)'),
50
+ config: z
51
+ .string()
52
+ .min(1)
53
+ .default('db-connection.env')
54
+ .describe('Config file name relative to the project, used by the CLI to connect to the database'),
55
+ output: z
56
+ .string()
57
+ .min(1)
58
+ .optional()
59
+ .describe('Output target relative to cwd. Required unless dryRun=true. For single-table mode: a .js file path; for bulk modes: a folder path. Multi-schema bulk uses subfolders inside this folder.'),
60
+ table: z
61
+ .string()
62
+ .min(1)
63
+ .optional()
64
+ .describe('Single-table mode. Format: "users" or "inventory.products" (qualified). When omitted, bulk mode is used (combine with schema or allSchemas).'),
65
+ schema: z
66
+ .string()
67
+ .min(1)
68
+ .optional()
69
+ .describe('Bulk mode filter: a single schema name ("inventory") or comma-separated list ("inventory,audit"). Mutually exclusive with allSchemas.'),
70
+ allSchemas: z
71
+ .boolean()
72
+ .optional()
73
+ .describe('Default false. When true, auto-detect all user schemas (skip system schemas). Mutually exclusive with schema and table.'),
74
+ force: z
75
+ .boolean()
76
+ .optional()
77
+ .describe('Default false. When true, overwrite existing output files. Without this, the CLI refuses to overwrite.'),
78
+ dryRun: z
79
+ .boolean()
80
+ .optional()
81
+ .describe('Default false. When true, print the factory function content to stdout and do NOT write any file.'),
82
+ },
83
+ annotations: {
84
+ title: 'Introspect Database into dbschema-kit Files',
85
+ destructiveHint: false, // writes files (and may overwrite with force=true), but no live DB mutation; reversible by deleting outputs
86
+ idempotentHint: false, // first call writes new files; subsequent calls behave differently depending on force
87
+ },
88
+ }, async ({ cwd, config, output, table, schema, allSchemas, force, dryRun }) => {
89
+ const projectCwd = resolve(cwd);
90
+ // Precondition check: @restforgejs/platform must be present in node_modules. per §3.4
91
+ try {
92
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
93
+ }
94
+ catch {
95
+ return {
96
+ content: [
97
+ {
98
+ type: 'text',
99
+ text: `Precondition not met: the RESTForge package is not installed in this project.
100
+
101
+ Project path: ${projectCwd}
102
+ Expected location: node_modules/@restforgejs/platform
103
+ Requested config: ${config}
104
+ Requested output: ${output ?? '(none)'}
105
+ Requested table: ${table ?? '(none)'}
106
+ Requested schema: ${schema ?? '(none)'}
107
+ Requested allSchemas: ${allSchemas ?? false}
108
+ Requested force: ${force ?? false}
109
+ Requested dryRun: ${dryRun ?? false}
110
+
111
+ For the assistant:
112
+ - The user needs to install the RESTForge package before the database can be introspected.
113
+ - Suggest installing the package first, then retry the introspection.
114
+ - 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.`,
115
+ },
116
+ ],
117
+ isError: false, // per §3.4
118
+ };
119
+ }
120
+ // Forward only the arguments the user supplied. The CLI handles mode resolution
121
+ // and mutual-exclusivity rules. per §3.5
122
+ const cliArgs = ['restforge', 'schema', 'introspect', `--config=${config}`];
123
+ if (output !== undefined)
124
+ cliArgs.push(`--output=${output}`);
125
+ if (table !== undefined)
126
+ cliArgs.push(`--table=${table}`);
127
+ if (schema !== undefined)
128
+ cliArgs.push(`--schema=${schema}`);
129
+ if (allSchemas === true)
130
+ cliArgs.push('--all-schemas');
131
+ if (force === true)
132
+ cliArgs.push('--force');
133
+ if (dryRun === true)
134
+ cliArgs.push('--dry-run');
135
+ const result = await execProcess('npx', cliArgs, {
136
+ cwd: projectCwd,
137
+ timeout: 60_000,
138
+ env: { NODE_ENV: 'production' },
139
+ stripFinalNewline: true,
140
+ });
141
+ // The CLI uses exit code 2 to signal "dry-run completed successfully". execProcess
142
+ // treats only exit 0 as success, so we re-route exit 2 back into the success branch.
143
+ const isDryRunSuccess = !result.success && result.exitCode === 2;
144
+ // Branch C: real CLI failure (any non-zero exit other than dry-run sentinel). per §3.4
145
+ if (!result.success && !isDryRunSuccess) {
146
+ return {
147
+ content: [
148
+ {
149
+ type: 'text',
150
+ text: `Failed to introspect the database.
151
+
152
+ Project path: ${projectCwd}
153
+ Config: ${config}
154
+ Output: ${output ?? '(none)'}
155
+ Table: ${table ?? '(none)'}
156
+ Schema: ${schema ?? '(none)'}
157
+ allSchemas: ${allSchemas ?? false}
158
+ Force: ${force ?? false}
159
+ DryRun: ${dryRun ?? false}
160
+ Command: ${result.command}
161
+ Exit code: ${result.exitCode}
162
+
163
+ --- CLI output ---
164
+ stdout:
165
+ ${result.stdout}
166
+
167
+ stderr:
168
+ ${result.stderr}
169
+ --- end CLI output ---
170
+
171
+ For the assistant:
172
+ - Tell the user that introspecting the database did not complete successfully.
173
+ - Summarise the most likely cause from the CLI output in plain language. Common causes:
174
+ * Config file not found — suggest verifying the config path and that the file exists.
175
+ * Database connection failed — suggest verifying credentials, host, and port.
176
+ * Output target missing or invalid (the CLI requires --output unless --dry-run).
177
+ * Output file exists without --force — suggest passing force=true if the user really wants to overwrite, or picking a different output path.
178
+ * Conflicting flags — e.g. table together with allSchemas, or schema together with allSchemas. The CLI rejects these combinations; suggest picking a single mode.
179
+ * Unknown command 'schema introspect' — the installed RESTForge version may be older than this CLI subcommand; suggest upgrading the package.
180
+ - Do not paste the raw stdout/stderr unless the user explicitly asks. Do not mention internal tool names.
181
+ - Offer to retry once the issue is resolved.`,
182
+ },
183
+ ],
184
+ isError: true, // per §3.4
185
+ };
186
+ }
187
+ // Derive a human-readable mode label for the labeled facts. The CLI is the source of
188
+ // truth for actual mode resolution; this label is informational only.
189
+ let modeLabel;
190
+ if (dryRun === true) {
191
+ modeLabel = table !== undefined ? 'dry-run (single-table)' : 'dry-run (bulk)';
192
+ }
193
+ else if (table !== undefined) {
194
+ modeLabel = 'single-table';
195
+ }
196
+ else if (allSchemas === true) {
197
+ modeLabel = 'bulk all-schemas';
198
+ }
199
+ else if (schema !== undefined) {
200
+ modeLabel = schema.includes(',') ? 'bulk multi-schema' : 'bulk single-schema';
201
+ }
202
+ else {
203
+ modeLabel = 'bulk default';
204
+ }
205
+ // Branch B: success (write or dry-run). per §3.5
206
+ const summaryHeading = isDryRunSuccess
207
+ ? 'Database introspection dry-run completed (no files were written).'
208
+ : 'Database introspection completed.';
209
+ const fenceLabel = isDryRunSuccess ? 'Factory function preview' : 'CLI output';
210
+ return {
211
+ content: [
212
+ {
213
+ type: 'text',
214
+ text: `${summaryHeading}
215
+
216
+ Project path: ${projectCwd}
217
+ Config: ${config}
218
+ Mode: ${modeLabel}
219
+ Output target: ${output ?? '(none — dry-run)'}
220
+ Table: ${table ?? '(not specified)'}
221
+ Schema: ${schema ?? '(not specified)'}
222
+ allSchemas: ${allSchemas ?? false}
223
+ Force overwrite: ${force ?? false}
224
+
225
+ --- ${fenceLabel} ---
226
+ ${result.stdout}
227
+ --- end ${fenceLabel} ---
228
+
229
+ For the assistant:
230
+ - Confirm to the user that the introspection ${isDryRunSuccess ? 'preview' : 'run'} completed. Mention the mode and the output target in plain language.
231
+ - ${isDryRunSuccess ? 'This was a preview only. No files were written to disk.' : 'Output files use the factory function pattern, ready to be validated. Suggest validating them as the next step (without naming the internal tool).'}
232
+ - The introspected dialect is auto-detected from the config; database types are mapped to generic types (string, integer, decimal, boolean, date, timestamp, uuid, json) so the schema files are dialect-portable.
233
+ - For multi-schema layouts (multiple schemas in the schema flag, or allSchemas=true), files are organised in subfolders per schema to avoid name collisions.
234
+ - ${isDryRunSuccess ? 'When the user is ready to commit the result to disk, mention that the same call without dry-run will write the files.' : 'This is a write operation. Files in the output target may have been created or overwritten if force=true was used.'}
235
+ - Match the user's language.`,
236
+ },
237
+ ],
238
+ };
239
+ });
240
+ }
241
+ //# sourceMappingURL=dbschema-introspect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dbschema-introspect.js","sourceRoot":"","sources":["../../../src/tools/codegen/dbschema-introspect.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 registerCodegenDbschemaMigrate(server: McpServer): void;
@@ -0,0 +1,219 @@
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 registerCodegenDbschemaMigrate(server) {
6
+ server.registerTool('codegen_dbschema_migrate', {
7
+ title: 'Migrate dbschema-kit Files to Database',
8
+ description: `Apply dbschema-kit definition files to a live database (load -> validate -> generate DDL -> apply via dialect driver), by wrapping restforge schema migrate. This is the only tool in the dbschema-kit family that MUTATES a live database. The DESTRUCTIVE annotation is set deliberately: with drop=true, all data in the affected tables is destroyed before recreation.
9
+
10
+ USE WHEN:
11
+ - The user explicitly asks to apply schema to a database, "deploy schema", "migrate schema ke DB"
12
+ - Pertanyaan dalam bentuk: "create tables di postgres", "apply DDL ke MySQL", "buat schema di production DB"
13
+ - Schema-driven development workflow finalisation
14
+ - After validating schema (codegen_dbschema_validate) and the user confirmed apply
15
+ - Initial DB setup for a new project
16
+ - The user wants dry-run first to preview DDL — pass dryRun=true (safe path)
17
+ - The user wants to drop and recreate tables (DESTRUCTIVE) — pass drop=true with explicit user confirmation
18
+ - After 'codegen_dbschema_introspect' followed by edits, to apply the modified schema
19
+
20
+ DO NOT USE FOR:
21
+ - Generating DDL without applying -> use 'codegen_dbschema_generate_ddl'
22
+ - Validating schema correctness -> use 'codegen_dbschema_validate'
23
+ - Listing live tables -> use 'codegen_list_tables'
24
+ - Querying data -> out of scope
25
+ - Incremental ALTER migration — this tool does full apply only. For incremental migrations, suggest a manual SQL migration script.
26
+ - Production database without explicit user authorisation — DESTRUCTIVE; never proceed without confirmation.
27
+
28
+ This tool runs: npx restforge schema migrate [<path>] --config=<file> [--drop=<bool>] [--dry-run] in the given cwd.
29
+ The CLI auto-detects the dialect from the config file (DB_TYPE=postgresql|mysql|oracle|sqlite). Exit codes: 0 apply success, 1 error, 2 dry-run success.
30
+
31
+ Preconditions:
32
+ - The project must have @restforgejs/platform installed in node_modules.
33
+ - The config file (default 'db-connection.env') must exist and contain valid database credentials.
34
+ - Schema files must exist at the given path (default './schema') and pass validation.
35
+
36
+ PRESENTATION GUIDANCE:
37
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
38
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "apply the schema", "preview the DDL", "drop and recreate the tables").
39
+ - Speak in plain language. Summarise the result; do not paste raw CLI output unless the user explicitly asks.
40
+ - This tool MUTATES a live database. ALWAYS confirm with the user before invoking with dryRun=false. The default safe path is dryRun=true (preview only).
41
+ - When the user uses drop=true, ALL DATA in the affected tables is destroyed. Confirm explicitly that the user understands this — quote the tables that will be dropped if known.
42
+ - Production database operations should be opt-in. If the config points to production (verify by reading DB_HOST or similar), strongly suggest dry-run + manual review first.
43
+ - There is no rollback on failure mid-migration — DDL changes that already executed are NOT automatically reverted. Plan for forward-fix only.
44
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
45
+ inputSchema: {
46
+ cwd: z
47
+ .string()
48
+ .min(1)
49
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform and the config file)'),
50
+ config: z
51
+ .string()
52
+ .min(1)
53
+ .default('db-connection.env')
54
+ .describe('Config file name relative to the project, used by the CLI to connect to the database'),
55
+ path: z
56
+ .string()
57
+ .min(1)
58
+ .optional()
59
+ .describe('Path to schema file or folder relative to cwd. When omitted, the CLI uses its default (./schema).'),
60
+ drop: z
61
+ .boolean()
62
+ .optional()
63
+ .describe('Default false. When true, drop tables before recreating them. DESTRUCTIVE — destroys all data in those tables. Require explicit user confirmation before passing true.'),
64
+ dryRun: z
65
+ .boolean()
66
+ .optional()
67
+ .describe('Default false. When true, generate DDL and preview it without applying. Safe path: prefer this on the first call.'),
68
+ },
69
+ annotations: {
70
+ title: 'Migrate dbschema-kit Files to Database',
71
+ destructiveHint: true, // mutates live DB; with drop=true also destroys data
72
+ idempotentHint: false, // re-running on a fresh DB will fail (tables already exist) unless drop=true
73
+ },
74
+ }, async ({ cwd, config, path, drop, dryRun }) => {
75
+ const projectCwd = resolve(cwd);
76
+ // Precondition check: @restforgejs/platform must be present in node_modules. per §3.4
77
+ try {
78
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
79
+ }
80
+ catch {
81
+ return {
82
+ content: [
83
+ {
84
+ type: 'text',
85
+ text: `Precondition not met: the RESTForge package is not installed in this project.
86
+
87
+ Project path: ${projectCwd}
88
+ Expected location: node_modules/@restforgejs/platform
89
+ Requested config: ${config}
90
+ Requested schema path: ${path ?? 'default (./schema)'}
91
+ Requested drop: ${drop ?? false}
92
+ Requested dryRun: ${dryRun ?? false}
93
+
94
+ For the assistant:
95
+ - The user needs to install the RESTForge package before the schema can be migrated.
96
+ - Suggest installing the package first, then retry the migration.
97
+ - 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.`,
98
+ },
99
+ ],
100
+ isError: false, // per §3.4
101
+ };
102
+ }
103
+ // Forward only the arguments the user supplied. CLI defaults remain in
104
+ // effect when the user does not specify them. per §3.5
105
+ const cliArgs = ['restforge', 'schema', 'migrate'];
106
+ if (path !== undefined)
107
+ cliArgs.push(path);
108
+ cliArgs.push(`--config=${config}`);
109
+ if (drop !== undefined)
110
+ cliArgs.push(`--drop=${drop}`);
111
+ if (dryRun === true)
112
+ cliArgs.push('--dry-run');
113
+ const result = await execProcess('npx', cliArgs, {
114
+ cwd: projectCwd,
115
+ timeout: 120_000, // schema apply on a populated DB can be slow
116
+ env: { NODE_ENV: 'production' },
117
+ stripFinalNewline: true,
118
+ });
119
+ // The CLI uses exit code 2 to signal "dry-run completed successfully". execProcess
120
+ // treats only exit 0 as success, so we re-route exit 2 back into the success branch.
121
+ const isDryRunSuccess = !result.success && result.exitCode === 2;
122
+ // Branch C: real CLI failure (any non-zero exit other than dry-run sentinel). per §3.4
123
+ if (!result.success && !isDryRunSuccess) {
124
+ return {
125
+ content: [
126
+ {
127
+ type: 'text',
128
+ text: `Failed to migrate schema to database.
129
+
130
+ Project path: ${projectCwd}
131
+ Config: ${config}
132
+ Schema path: ${path ?? 'default (./schema)'}
133
+ Drop: ${drop ?? false}
134
+ DryRun: ${dryRun ?? false}
135
+ Command: ${result.command}
136
+ Exit code: ${result.exitCode}
137
+
138
+ --- CLI output ---
139
+ stdout:
140
+ ${result.stdout}
141
+
142
+ stderr:
143
+ ${result.stderr}
144
+ --- end CLI output ---
145
+
146
+ For the assistant:
147
+ - Tell the user that the migration did not complete successfully.
148
+ - Summarise the most likely cause from the CLI output in plain language. Common causes:
149
+ * Config file not found — suggest verifying the config path and that the file exists.
150
+ * Database connection failed — suggest verifying credentials, host, and port.
151
+ * Schema validation error — a schema file has invalid syntax or a broken FK reference. Suggest running the validate action first to surface the specific issue.
152
+ * Schema folder not found — the CLI cannot locate the path. Suggest verifying the folder name (default is './schema').
153
+ * Apply error mid-transaction — DDL changes that already executed before the failure are NOT automatically reverted. The user must inspect the DB state manually and plan a forward-fix.
154
+ * Tables already exist (without drop=true) — the CLI does full apply only. Suggest dry-run + manual review of the existing schema, or pass drop=true with explicit user confirmation.
155
+ * Unknown command 'schema migrate' — the installed RESTForge version may be older than this CLI subcommand; suggest upgrading the package.
156
+ - Do not paste the raw stdout/stderr unless the user explicitly asks. Do not mention internal tool names.
157
+ - For destructive failures (mid-apply error with partial DDL execution), strongly suggest the user reviews the DB state before any retry.`,
158
+ },
159
+ ],
160
+ isError: true, // per §3.4
161
+ };
162
+ }
163
+ if (isDryRunSuccess) {
164
+ // Branch B (dry-run): preview only, no DDL applied. per §3.5
165
+ return {
166
+ content: [
167
+ {
168
+ type: 'text',
169
+ text: `Schema migration dry-run completed (no changes applied).
170
+
171
+ Project path: ${projectCwd}
172
+ Config: ${config}
173
+ Schema path: ${path ?? 'default (./schema)'}
174
+ Mode: dry-run
175
+
176
+ --- DDL preview ---
177
+ ${result.stdout}
178
+ --- end DDL preview ---
179
+
180
+ For the assistant:
181
+ - Confirm to the user that this was a preview only. No DDL was applied to the database.
182
+ - The DDL shown above is what would be applied if the same action is rerun without dry-run.
183
+ - Encourage reviewing the DDL before applying. For destructive operations (drop=true), strongly suggest the user reviews the DROP TABLE list carefully and confirms the data destruction is intended.
184
+ - Match the user's language.`,
185
+ },
186
+ ],
187
+ };
188
+ }
189
+ // Branch B (apply): real apply succeeded. per §3.5
190
+ return {
191
+ content: [
192
+ {
193
+ type: 'text',
194
+ text: `Schema migration applied successfully.
195
+
196
+ Project path: ${projectCwd}
197
+ Config: ${config}
198
+ Schema path: ${path ?? 'default (./schema)'}
199
+ Mode: apply
200
+ Drop tables before recreate: ${drop ?? false}
201
+
202
+ --- CLI output ---
203
+ ${result.stdout}
204
+ --- end CLI output ---
205
+
206
+ For the assistant:
207
+ - Confirm to the user that the migration was applied. Read the CLI output above and mention the database type and the count of tables/indexes/foreign keys created (when present).
208
+ - This is a DESTRUCTIVE operation: tables, indexes, and foreign keys were created in the live database. With drop=true, existing tables and their data were also removed before recreation.
209
+ - The user should verify the database state matches expectation. Suggest listing tables (read-only) for confirmation.
210
+ - For follow-up changes, the user authors updated schema files and reruns the migrate action. Caution: there is no incremental ALTER migration in this version — full apply only. Schema-driven incremental migration is out of scope.
211
+ - There is no rollback on partial failure — if a future migration fails mid-way, DDL that already executed is NOT automatically reverted.
212
+ - Do not paste the raw CLI output unless the user explicitly asks.
213
+ - Match the user's language.`,
214
+ },
215
+ ],
216
+ };
217
+ });
218
+ }
219
+ //# sourceMappingURL=dbschema-migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dbschema-migrate.js","sourceRoot":"","sources":["../../../src/tools/codegen/dbschema-migrate.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 registerCodegenDbschemaModels(server: McpServer): void;
@@ -0,0 +1,146 @@
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 registerCodegenDbschemaModels(server) {
6
+ server.registerTool('codegen_dbschema_models', {
7
+ title: 'List dbschema-kit Models',
8
+ description: `List all schema models from dbschema-kit definition files with a structural summary (schema, table, fields count, primary key kind, indexes, uniques, relations) by wrapping restforge schema models. Output is a tabular text report. Cross-model validation is intentionally skipped so the listing is usable even when FK references are broken.
9
+
10
+ USE WHEN:
11
+ - The user asks to list models, "tampilkan semua model schema", "what tables are defined in dbschema"
12
+ - Pertanyaan dalam bentuk: "berapa banyak model di project ini", "list dbschema models", "show model summary", "ringkasan schema saya"
13
+ - Before invoking 'codegen_dbschema_generate_ddl' — to confirm the scope (which tables will be generated)
14
+ - After 'codegen_dbschema_introspect' — to verify what was generated from the live database
15
+ - The user wants a quick overview of schema-as-code state without a full validation pass
16
+ - The user asks "apa saja table yang akan di-generate ke DDL"
17
+ - Cross-check after editing the schema folder structure
18
+
19
+ DO NOT USE FOR:
20
+ - Listing live database tables -> use 'codegen_list_tables'
21
+ - Detailed inspection of a single model — use 'codegen_dbschema_validate' for correctness, or read the file directly with the Read tool
22
+ - Generating DDL -> use 'codegen_dbschema_generate_ddl'
23
+ - Looking up schema syntax -> use 'codegen_get_dbschema_catalog'
24
+
25
+ This tool runs: npx restforge schema models [<path>] in the given cwd.
26
+
27
+ Preconditions:
28
+ - The project must have @restforgejs/platform installed in node_modules.
29
+ - The schema path (default './schema') must exist. If the CLI fails because the folder is missing, the failure response surfaces the underlying cause.
30
+
31
+ PRESENTATION GUIDANCE:
32
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
33
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "list the schema models", "validate the schema", "generate the DDL").
34
+ - Speak in plain language. Summarise the result (model count, schemas in use); do not paste the tabular output verbatim if many models are listed.
35
+ - Models listing skips cross-model validation. If FK references are broken, listing still works; that is by design — use the validate action for correctness check.
36
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
37
+ inputSchema: {
38
+ cwd: z
39
+ .string()
40
+ .min(1)
41
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform)'),
42
+ path: z
43
+ .string()
44
+ .min(1)
45
+ .optional()
46
+ .describe('Path to schema file or folder relative to cwd. When omitted, the CLI uses its default (./schema).'),
47
+ },
48
+ annotations: {
49
+ title: 'List dbschema-kit Models',
50
+ readOnlyHint: true,
51
+ idempotentHint: true,
52
+ },
53
+ }, async ({ cwd, path }) => {
54
+ const projectCwd = resolve(cwd);
55
+ // Precondition check: @restforgejs/platform must be present in node_modules. per §3.4
56
+ try {
57
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
58
+ }
59
+ catch {
60
+ return {
61
+ content: [
62
+ {
63
+ type: 'text',
64
+ text: `Precondition not met: the RESTForge package is not installed in this project.
65
+
66
+ Project path: ${projectCwd}
67
+ Expected location: node_modules/@restforgejs/platform
68
+ Requested schema path: ${path ?? 'default (./schema)'}
69
+
70
+ For the assistant:
71
+ - The user needs to install the RESTForge package before models can be listed.
72
+ - Suggest installing the package first, then retry listing the models.
73
+ - 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.`,
74
+ },
75
+ ],
76
+ isError: false, // per §3.4
77
+ };
78
+ }
79
+ // Forward only the arguments the user supplied. CLI default './schema' applies otherwise. per §3.5
80
+ const cliArgs = ['restforge', 'schema', 'models'];
81
+ if (path !== undefined)
82
+ cliArgs.push(path);
83
+ const result = await execProcess('npx', cliArgs, {
84
+ cwd: projectCwd,
85
+ timeout: 30_000,
86
+ env: { NODE_ENV: 'production' },
87
+ stripFinalNewline: true,
88
+ });
89
+ // Branch C: CLI failure — real error per §3.4. per §3.5
90
+ if (!result.success) {
91
+ return {
92
+ content: [
93
+ {
94
+ type: 'text',
95
+ text: `Failed to list schema models.
96
+
97
+ Project path: ${projectCwd}
98
+ Schema path: ${path ?? 'default (./schema)'}
99
+ Command: ${result.command}
100
+ Exit code: ${result.exitCode}
101
+
102
+ --- CLI output ---
103
+ stdout:
104
+ ${result.stdout}
105
+
106
+ stderr:
107
+ ${result.stderr}
108
+ --- end CLI output ---
109
+
110
+ For the assistant:
111
+ - Tell the user that listing the schema models did not complete successfully.
112
+ - Summarise the most likely cause from the CLI output in plain language. Common causes:
113
+ * Schema folder not found — the CLI cannot locate the path. Suggest verifying the folder name (default is './schema').
114
+ * Single-model parse error — a file has invalid factory function content. Suggest opening the file and confirming it exports a defineModel call. The validate action surfaces field-level errors more precisely.
115
+ * Unknown command 'schema models' — the installed RESTForge version may be older than this CLI subcommand; suggest upgrading the package.
116
+ - Do not paste the raw stdout/stderr unless the user explicitly asks. Do not mention internal tool names.`,
117
+ },
118
+ ],
119
+ isError: true, // per §3.4
120
+ };
121
+ }
122
+ // Branch B: success — labeled facts + fenced raw output per §3.5.
123
+ return {
124
+ content: [
125
+ {
126
+ type: 'text',
127
+ text: `Schema models listed successfully.
128
+
129
+ Project path: ${projectCwd}
130
+ Schema path: ${path ?? 'default (./schema)'}
131
+
132
+ --- CLI output ---
133
+ ${result.stdout}
134
+ --- end CLI output ---
135
+
136
+ For the assistant:
137
+ - Confirm to the user that the models were listed. Read the tabular output above and summarise in plain language: total model count, distinct schemas in use, any models with relations.
138
+ - Do not paste the entire tabular output if there are many models. Group by schema or list only the models relevant to the user's task.
139
+ - This listing skips cross-model validation. If the user wants to confirm FK target validity, suggest running the validation action next (without naming the internal tool).
140
+ - Match the user's language.`,
141
+ },
142
+ ],
143
+ };
144
+ });
145
+ }
146
+ //# sourceMappingURL=dbschema-models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dbschema-models.js","sourceRoot":"","sources":["../../../src/tools/codegen/dbschema-models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,UAAU,6BAA6B,CAAC,MAAiB;IAC7D,MAAM,CAAC,YAAY,CACjB,yBAAyB,EACzB;QACE,KAAK,EAAE,0BAA0B;QACjC,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;uGA4BoF;QACjG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,uFAAuF,CAAC;YACpG,IAAI,EAAE,CAAC;iBACJ,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,EAAE;iBACV,QAAQ,CAAC,mGAAmG,CAAC;SACjH;QACD,WAAW,EAAE;YACX,KAAK,EAAE,0BAA0B;YACjC,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;SACrB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;QACtB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAEhC,sFAAsF;QACtF,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;;yBAED,IAAI,IAAI,oBAAoB;;;;;gKAK2G;qBACnJ;iBACF;gBACD,OAAO,EAAE,KAAK,EAAE,WAAW;aAC5B,CAAC;QACJ,CAAC;QAED,mGAAmG;QACnG,MAAM,OAAO,GAAG,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAClD,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,KAAK,EACL,OAAO,EACP;YACE,GAAG,EAAE,UAAU;YACf,OAAO,EAAE,MAAM;YACf,GAAG,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE;YAC/B,iBAAiB,EAAE,IAAI;SACxB,CACF,CAAC;QAEF,wDAAwD;QACxD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;eACX,IAAI,IAAI,oBAAoB;WAChC,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;;;;;;0GAS2F;qBAC7F;iBACF;gBACD,OAAO,EAAE,IAAI,EAAE,WAAW;aAC3B,CAAC;QACJ,CAAC;QAED,kEAAkE;QAClE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;eACX,IAAI,IAAI,oBAAoB;;;EAGzC,MAAM,CAAC,MAAM;;;;;;;6BAOc;iBAClB;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerCodegenDbschemaValidate(server: McpServer): void;