@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,176 @@
1
+ import { z } from 'zod';
2
+ import { readFile, writeFile, access } from 'node:fs/promises';
3
+ import { resolve, join } from 'node:path';
4
+ import { parseEnvFile, serializeEnvFile, mergeEnvEntries, isSensitiveKey, maskValue, } from '../../lib/env-parser.js';
5
+ export function registerSetupUpdateEnv(server) {
6
+ server.registerTool('setup_update_env', {
7
+ title: 'Update Database Connection Env',
8
+ description: `Apply a partial update to config/db-connection.env. Accepts an arbitrary set of key/value pairs and merges them into the existing file, preserving comments, blank lines, and untouched parameters.
9
+
10
+ USE WHEN:
11
+ - Toggling individual feature flags (e.g. LIVE_SYNC_ENABLED, REDIS_ENABLED, KAFKA_ENABLED)
12
+ - Adjusting one or two values without restating the whole core connection
13
+ - Adding a new optional parameter that is not in the template
14
+
15
+ DO NOT USE FOR:
16
+ - Generating the initial config skeleton -> use 'setup_init_config'
17
+ - Bulk write of license + DB credentials -> use 'setup_write_env'
18
+ - Validating connection -> use 'setup_validate_config'
19
+
20
+ Behavior: read existing file, replace matching keys (preserving inline comments), append non-existing keys at the bottom, write back. Values may be string, number, or boolean (booleans serialize as 'true'/'false'). Values containing spaces, '=' or '#' are auto-quoted.
21
+
22
+ PRESENTATION GUIDANCE:
23
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
24
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "set up the initial config", "fill in the credentials", "validate the connection").
25
+ - Speak in plain language. Summarise the result by counting and naming the changed keys; do not paste the full diff block unless the user explicitly asks.
26
+ - Do not echo sensitive values (license keys, passwords) into chat even when they appear masked in the response. Confirm presence and length only.
27
+ - When a precondition is not met (e.g. config file is missing), frame it as a question or next-step suggestion rather than an error.`,
28
+ inputSchema: {
29
+ cwd: z.string().min(1).describe('Absolute path of the project folder'),
30
+ configFile: z
31
+ .string()
32
+ .default('db-connection.env')
33
+ .describe('Config file name in the config/ folder. Default: db-connection.env'),
34
+ fields: z
35
+ .record(z.string(), z.union([z.string(), z.number(), z.boolean()]))
36
+ .refine((obj) => Object.keys(obj).length > 0, {
37
+ message: 'fields must contain at least one key',
38
+ })
39
+ .describe('Key-value map of parameters to update or add. Example: { "DB_PORT": 5433, "KAFKA_ENABLED": true }'),
40
+ },
41
+ annotations: {
42
+ title: 'Update Env Config',
43
+ readOnlyHint: false,
44
+ idempotentHint: true,
45
+ },
46
+ }, async ({ cwd, configFile, fields }) => {
47
+ const projectCwd = resolve(cwd);
48
+ const envPath = join(projectCwd, 'config', configFile);
49
+ // Precondition check: the config file must exist before it can be updated.
50
+ // Treated as a non-error precondition per the authoring guide §3.4.
51
+ try {
52
+ await access(envPath);
53
+ }
54
+ catch {
55
+ return {
56
+ content: [
57
+ {
58
+ type: 'text',
59
+ text: `Precondition not met: the configuration file does not exist yet.
60
+
61
+ Project path: ${projectCwd}
62
+ Expected file: ${envPath}
63
+
64
+ For the assistant:
65
+ - The user is trying to update a configuration that has not been created yet.
66
+ - Suggest generating the initial RESTForge configuration first, then retry the update.
67
+ - When explaining to the user, say something like "the configuration file isn't there yet — should I set up the initial config first?". Do not mention internal tool names.`,
68
+ },
69
+ ],
70
+ isError: false,
71
+ };
72
+ }
73
+ // Real I/O failure on read: surface as error per §3.4.
74
+ let existingContent;
75
+ try {
76
+ existingContent = await readFile(envPath, 'utf-8');
77
+ }
78
+ catch (error) {
79
+ const msg = error instanceof Error ? error.message : String(error);
80
+ return {
81
+ content: [
82
+ {
83
+ type: 'text',
84
+ text: `Failed to read the configuration file before applying the update.
85
+
86
+ Project path: ${projectCwd}
87
+ File: ${envPath}
88
+ Reason: ${msg}
89
+
90
+ For the assistant:
91
+ - Tell the user that the configuration file exists but could not be read.
92
+ - Summarise the likely cause (permissions, file lock, encoding) in plain language; do not paste the raw error unless the user explicitly asks.
93
+ - Offer to retry once the underlying issue is resolved. Do not mention internal tool names.`,
94
+ },
95
+ ],
96
+ isError: true,
97
+ };
98
+ }
99
+ const existingEntries = parseEnvFile(existingContent);
100
+ const merged = mergeEnvEntries(existingEntries, fields);
101
+ const newContent = serializeEnvFile(merged.entries);
102
+ // Real I/O failure on write: surface as error per §3.4.
103
+ try {
104
+ await writeFile(envPath, newContent, 'utf-8');
105
+ }
106
+ catch (error) {
107
+ const msg = error instanceof Error ? error.message : String(error);
108
+ return {
109
+ content: [
110
+ {
111
+ type: 'text',
112
+ text: `Failed to write the updated configuration to disk.
113
+
114
+ Project path: ${projectCwd}
115
+ File: ${envPath}
116
+ Reason: ${msg}
117
+
118
+ For the assistant:
119
+ - Tell the user that the update could not be persisted.
120
+ - Summarise the likely cause (permissions, disk full, file lock) in plain language; do not paste the raw error unless the user explicitly asks.
121
+ - The original file is unchanged. Offer to retry once the underlying issue is resolved. Do not mention internal tool names.`,
122
+ },
123
+ ],
124
+ isError: true,
125
+ };
126
+ }
127
+ // Success: labeled facts + fenced change summary per §3.5.
128
+ const formatChange = (key, before, after) => {
129
+ if (isSensitiveKey(key)) {
130
+ return ` - ${key}: ${maskValue(before)} -> ${maskValue(after)}`;
131
+ }
132
+ return ` - ${key}: ${before} -> ${after}`;
133
+ };
134
+ const formatAdd = (key, value) => {
135
+ const v = isSensitiveKey(key) ? maskValue(value) : value;
136
+ return ` - ${key}=${v}`;
137
+ };
138
+ const changeBlockLines = [
139
+ `Updated fields (${merged.updated.length}):`,
140
+ ...(merged.updated.length === 0
141
+ ? [' (none)']
142
+ : merged.updated.map((u) => formatChange(u.key, u.before, u.after))),
143
+ '',
144
+ `Added fields (${merged.added.length}):`,
145
+ ...(merged.added.length === 0
146
+ ? [' (none)']
147
+ : merged.added.map((a) => formatAdd(a.key, a.value))),
148
+ '',
149
+ `Unchanged fields (${merged.unchanged.length}): preserved`,
150
+ ];
151
+ const sensitiveTouched = merged.updated.some((u) => isSensitiveKey(u.key)) ||
152
+ merged.added.some((a) => isSensitiveKey(a.key));
153
+ const text = `Configuration updated successfully.
154
+
155
+ Project path: ${projectCwd}
156
+ File: ${envPath}
157
+ Updated keys: ${merged.updated.length}
158
+ Added keys: ${merged.added.length}
159
+ Unchanged keys: ${merged.unchanged.length}
160
+
161
+ --- Changes ---
162
+ ${changeBlockLines.join('\n')}
163
+ --- end Changes ---
164
+
165
+ For the assistant:
166
+ - Confirm to the user that the configuration was updated.
167
+ - Summarise in plain language: how many keys were changed and added, and name the most relevant ones (without listing every single one unless asked).
168
+ - Do not paste the full change block unless the user explicitly asks.
169
+ - ${sensitiveTouched
170
+ ? 'A sensitive value (license or password) was changed or added. Do NOT echo the new value into chat. Confirm only that it was set.'
171
+ : 'No sensitive values were changed in this update.'}
172
+ - Suggest validating the configuration as the next step. Do not mention internal tool names.`;
173
+ return { content: [{ type: 'text', text }] };
174
+ });
175
+ }
176
+ //# sourceMappingURL=update-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-env.js","sourceRoot":"","sources":["../../../src/tools/setup/update-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,SAAS,GAEV,MAAM,yBAAyB,CAAC;AAEjC,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,KAAK,EAAE,gCAAgC;QACvC,WAAW,EAAE;;;;;;;;;;;;;;;;;;;qIAmBkH;QAC/H,WAAW,EAAE;YACX,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;YACtE,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,OAAO,CAAC,mBAAmB,CAAC;iBAC5B,QAAQ,CAAC,oEAAoE,CAAC;YACjF,MAAM,EAAE,CAAC;iBACN,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;iBAClE,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC5C,OAAO,EAAE,sCAAsC;aAChD,CAAC;iBACD,QAAQ,CAAC,mGAAmG,CAAC;SACjH;QACD,WAAW,EAAE;YACX,KAAK,EAAE,mBAAmB;YAC1B,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,IAAI;SACrB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE;QACpC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAEvD,2EAA2E;QAC3E,oEAAoE;QACpE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;iBACT,OAAO;;;;;4KAKoJ;qBAC/J;iBACF;gBACD,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QAED,uDAAuD;QACvD,IAAI,eAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,eAAe,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;QAClB,OAAO;UACL,GAAG;;;;;4FAK+E;qBAC/E;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,eAAe,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,eAAe,CAAC,eAAe,EAAE,MAAuC,CAAC,CAAC;QACzF,MAAM,UAAU,GAAG,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEpD,wDAAwD;QACxD,IAAI,CAAC;YACH,MAAM,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnE,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;QAClB,OAAO;UACL,GAAG;;;;;4HAK+G;qBAC/G;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,2DAA2D;QAC3D,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,MAAc,EAAE,KAAa,EAAU,EAAE;YAC1E,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,OAAO,GAAG,KAAK,SAAS,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACnE,CAAC;YACD,OAAO,OAAO,GAAG,KAAK,MAAM,OAAO,KAAK,EAAE,CAAC;QAC7C,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,KAAa,EAAU,EAAE;YACvD,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YACzD,OAAO,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;QAC3B,CAAC,CAAC;QAEF,MAAM,gBAAgB,GAAa;YACjC,mBAAmB,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI;YAC5C,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;gBAC7B,CAAC,CAAC,CAAC,UAAU,CAAC;gBACd,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,EAAE;YACF,iBAAiB,MAAM,CAAC,KAAK,CAAC,MAAM,IAAI;YACxC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;gBAC3B,CAAC,CAAC,CAAC,UAAU,CAAC;gBACd,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACvD,EAAE;YACF,qBAAqB,MAAM,CAAC,SAAS,CAAC,MAAM,cAAc;SAC3D,CAAC;QAEF,MAAM,gBAAgB,GACpB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACjD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAElD,MAAM,IAAI,GAAG;;gBAEH,UAAU;QAClB,OAAO;gBACC,MAAM,CAAC,OAAO,CAAC,MAAM;cACvB,MAAM,CAAC,KAAK,CAAC,MAAM;kBACf,MAAM,CAAC,SAAS,CAAC,MAAM;;;EAGvC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;IAOzB,gBAAgB;YACV,CAAC,CAAC,kIAAkI;YACpI,CAAC,CAAC,kDAAkD;6FAC+B,CAAC;QAExF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAC/C,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerSetupValidateConfig(server: McpServer): void;
@@ -0,0 +1,138 @@
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 registerSetupValidateConfig(server) {
6
+ server.registerTool('setup_validate_config', {
7
+ title: 'Validate RESTForge Config',
8
+ description: `Validate the RESTForge license and connections to database, redis, and kafka based on the config file.
9
+
10
+ USE WHEN:
11
+ - The db-connection.env file has been filled in (license + DB credentials)
12
+ - After credentials have been written or updated, to verify they actually work
13
+ - Before starting runtime or codegen operations
14
+ - Verifying license and access to external services before deploy
15
+ - Diagnosing configuration issues
16
+ - The user asks things like "test connection", "cek license", "validate config",
17
+ "apakah config sudah benar", "is the database reachable", "tes koneksi",
18
+ "verify the configuration", "cek apakah license valid"
19
+ - Before validating, consider calling 'setup_read_env' to confirm what is
20
+ currently set — especially when the user describes the validation relative
21
+ to a recent change (e.g. "cek apakah license barunya valid"). // per §5.3
22
+ - The user wants to validate CONFIGURATION (license, database connection, kafka, redis), not payload files
23
+
24
+ DO NOT USE FOR:
25
+ - Writing the config file -> use 'setup_write_env'
26
+ - Adjusting individual fields -> use 'setup_update_env'
27
+ - Generating module code -> use codegen_* domain tools
28
+ - Checking if payload JSON files are still in sync with the database schema -> use 'codegen_validate_payload'
29
+
30
+ Often called as the final step after 'setup_write_env' or 'setup_update_env'
31
+ has filled in or changed credentials, to confirm that they actually work. // per §5.2
32
+
33
+ This tool runs: npx restforge validate --config=<configFile> in the given cwd.
34
+ This tool is READ-ONLY and safe to call repeatedly.
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. "fill in the credentials", "update a single value", "set up the initial config").
39
+ - Speak in plain language. Summarise the validation result by component (license, database, optional redis/kafka); do not paste the raw CLI output unless the user explicitly asks.
40
+ - The CLI output may contain license fragments, host names, or user names. Do not echo license keys, passwords, or full connection URIs into chat. Confirm validation status only.
41
+ - When a precondition is not met (e.g. config file is missing), frame it as a question or next-step suggestion rather than an error.`,
42
+ inputSchema: {
43
+ cwd: z.string().min(1).describe('Absolute path of the project folder'),
44
+ configFile: z
45
+ .string()
46
+ .default('db-connection.env')
47
+ .describe('Config file name in the config/ folder. Default: db-connection.env'),
48
+ },
49
+ annotations: {
50
+ title: 'Validate Config',
51
+ readOnlyHint: true,
52
+ idempotentHint: true,
53
+ },
54
+ }, async ({ cwd, configFile }) => {
55
+ const projectCwd = resolve(cwd);
56
+ const configPath = join(projectCwd, 'config', configFile);
57
+ // Precondition check: the config file must exist before it can be validated.
58
+ // Treated as a non-error precondition per the authoring guide §3.4.
59
+ try {
60
+ await access(configPath);
61
+ }
62
+ catch {
63
+ return {
64
+ content: [
65
+ {
66
+ type: 'text',
67
+ text: `Precondition not met: the configuration file does not exist yet.
68
+
69
+ Project path: ${projectCwd}
70
+ Expected file: ${configPath}
71
+
72
+ For the assistant:
73
+ - The user is trying to validate a configuration that has not been created and filled in yet.
74
+ - Suggest generating the initial RESTForge configuration first, then filling in the license and database credentials, and finally retrying the validation.
75
+ - When explaining to the user, say something like "there's no configuration to validate yet — should I set up the initial config first?". Do not mention internal tool names.`,
76
+ },
77
+ ],
78
+ isError: false, // per §3.4
79
+ };
80
+ }
81
+ const result = await execProcess('npx', ['restforge', 'validate', `--config=${configFile}`], { cwd: projectCwd, timeout: 30_000 });
82
+ // Validation failure: real error per §3.4; structured per §3.5.
83
+ if (!result.success) {
84
+ return {
85
+ content: [
86
+ {
87
+ type: 'text',
88
+ text: `Configuration validation did not pass.
89
+
90
+ Project path: ${projectCwd}
91
+ Config file: ${configPath}
92
+ Command: ${result.command}
93
+ Exit code: ${result.exitCode}
94
+
95
+ --- CLI output ---
96
+ stdout:
97
+ ${result.stdout || '(empty)'}
98
+
99
+ stderr:
100
+ ${result.stderr || '(empty)'}
101
+ --- end CLI output ---
102
+
103
+ For the assistant:
104
+ - Tell the user that the validation reported one or more problems.
105
+ - Summarise the likely failing component in plain language (license, database, redis, kafka) based on the CLI output; do not paste the raw stdout/stderr unless the user explicitly asks.
106
+ - Do not echo license keys, passwords, or full connection URIs from the output into chat.
107
+ - Suggest reviewing or updating the relevant credentials and retrying. Do not mention internal tool names.`,
108
+ },
109
+ ],
110
+ isError: true, // per §3.4
111
+ };
112
+ }
113
+ // Success: one-line summary + labeled facts + fenced raw output per §3.5.
114
+ return {
115
+ content: [
116
+ {
117
+ type: 'text',
118
+ text: `Configuration validation passed.
119
+
120
+ Project path: ${projectCwd}
121
+ Config file: ${configPath}
122
+ Command: ${result.command}
123
+ Exit code: ${result.exitCode}
124
+
125
+ --- CLI output ---
126
+ ${result.stdout || '(empty)'}
127
+ --- end CLI output ---
128
+
129
+ For the assistant:
130
+ - Confirm to the user that the license and external connections checked out.
131
+ - Summarise in plain language which components were checked and passed (license, database, optional redis/kafka), based on what appears in the CLI output.
132
+ - Do not paste the raw CLI output unless the user explicitly asks. Do not echo license keys or credentials. Do not mention internal tool names.`,
133
+ },
134
+ ],
135
+ };
136
+ });
137
+ }
138
+ //# sourceMappingURL=validate-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-config.js","sourceRoot":"","sources":["../../../src/tools/setup/validate-config.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,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,2BAA2B;QAClC,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qIAiCkH;QAC/H,WAAW,EAAE;YACX,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,qCAAqC,CAAC;YACtE,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,OAAO,CAAC,mBAAmB,CAAC;iBAC5B,QAAQ,CAAC,oEAAoE,CAAC;SAClF;QACD,WAAW,EAAE;YACX,KAAK,EAAE,iBAAiB;YACxB,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;SACrB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,EAAE;QAC5B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QAE1D,6EAA6E;QAC7E,oEAAoE;QACpE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;iBACT,UAAU;;;;;8KAKmJ;qBACjK;iBACF;gBACD,OAAO,EAAE,KAAK,EAAE,WAAW;aAC5B,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAC9B,KAAK,EACL,CAAC,WAAW,EAAE,UAAU,EAAE,YAAY,UAAU,EAAE,CAAC,EACnD,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CACrC,CAAC;QAEF,gEAAgE;QAChE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;eACX,UAAU;WACd,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM,IAAI,SAAS;;;EAG1B,MAAM,CAAC,MAAM,IAAI,SAAS;;;;;;;2GAO+E;qBAC9F;iBACF;gBACD,OAAO,EAAE,IAAI,EAAE,WAAW;aAC3B,CAAC;QACJ,CAAC;QAED,0EAA0E;QAC1E,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;eACX,UAAU;WACd,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;EAG1B,MAAM,CAAC,MAAM,IAAI,SAAS;;;;;;gJAMoH;iBACrI;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 registerSetupWriteEnv(server: McpServer): void;
@@ -0,0 +1,168 @@
1
+ import { z } from 'zod';
2
+ import { readFile, writeFile, access } from 'node:fs/promises';
3
+ import { resolve, join } from 'node:path';
4
+ import { parseEnvFile, serializeEnvFile, mergeEnvEntries, } from '../../lib/env-parser.js';
5
+ export function registerSetupWriteEnv(server) {
6
+ server.registerTool('setup_write_env', {
7
+ title: 'Write Database Connection Env',
8
+ description: `Write license, server settings, and database credentials into config/db-connection.env using a partial-merge strategy that preserves all other parameters and comments in the file.
9
+
10
+ USE WHEN:
11
+ - The user provides a complete set of license + database credentials in one go
12
+ - The user is doing initial credential setup (first time filling in the empty template)
13
+ - You need to fill in or update ALL core connection fields together (license,
14
+ server, database) — even if some values are already set, this tool will
15
+ overwrite them consistently
16
+ - The user says things like "isi credentials", "setup koneksi database",
17
+ "fill in the connection info", "atur license dan database"
18
+
19
+ DO NOT USE FOR:
20
+ - Generating the initial config skeleton -> use 'setup_init_config'
21
+ - Changing only one or two fields (e.g. just the password, or toggle a flag) -> use 'setup_update_env'
22
+ - Validating license/connection -> use 'setup_validate_config'
23
+
24
+ Behavior: read existing file, update LICENSE/SERVER_*/DB_* entries in place, append any missing keys at the bottom, and write back. Comments, blank lines, and unrelated parameters are preserved verbatim. Output file: <cwd>/config/db-connection.env.
25
+
26
+ PRESENTATION GUIDANCE:
27
+ - Match the user's language. If the user writes in Indonesian, respond in Indonesian.
28
+ - Never mention internal tool names in the reply to the user. Describe actions by what they do (e.g. "set up the initial config", "update a single value", "validate the connection").
29
+ - Speak in plain language. Summarise what was written; do not paste the full field list unless the user explicitly asks.
30
+ - Do not echo sensitive values (license keys, passwords) into chat even when they appear masked in the response. Confirm only that they were set.
31
+ - When a precondition is not met (e.g. config file is missing), frame it as a question or next-step suggestion rather than an error.`,
32
+ inputSchema: {
33
+ cwd: z.string().min(1).describe('Absolute path of the project folder'),
34
+ license: z
35
+ .string()
36
+ .regex(/^[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/, 'Format must be XXXX-XXXX-XXXX-XXXX'),
37
+ serverAddress: z.string().default('127.0.0.1'),
38
+ serverPort: z.number().int().min(1).max(65535).default(3000),
39
+ dbType: z.enum(['postgresql', 'mysql', 'oracle', 'sqlite']),
40
+ dbHost: z.string().min(1),
41
+ dbPort: z.number().int().min(1).max(65535),
42
+ dbUser: z.string().min(1),
43
+ dbPassword: z.string(),
44
+ dbName: z.string().min(1),
45
+ },
46
+ annotations: {
47
+ title: 'Write Env Config',
48
+ readOnlyHint: false,
49
+ idempotentHint: true,
50
+ },
51
+ }, async (args) => {
52
+ const projectCwd = resolve(args.cwd);
53
+ const configDir = join(projectCwd, 'config');
54
+ const envPath = join(configDir, 'db-connection.env');
55
+ // Precondition check: the config file must exist before it can be written.
56
+ // Treated as a non-error precondition per the authoring guide §3.4.
57
+ try {
58
+ await access(envPath);
59
+ }
60
+ catch {
61
+ return {
62
+ content: [
63
+ {
64
+ type: 'text',
65
+ text: `Precondition not met: the configuration file does not exist yet.
66
+
67
+ Project path: ${projectCwd}
68
+ Expected file: ${envPath}
69
+
70
+ For the assistant:
71
+ - The user is trying to write credentials into a configuration that has not been created yet.
72
+ - Suggest generating the initial RESTForge configuration first, then retry filling in the credentials.
73
+ - When explaining to the user, say something like "the configuration file isn't there yet — should I set up the initial config first?". Do not mention internal tool names.`,
74
+ },
75
+ ],
76
+ isError: false,
77
+ };
78
+ }
79
+ // Real I/O failure on read: surface as error per §3.4.
80
+ let existingContent;
81
+ try {
82
+ existingContent = await readFile(envPath, 'utf-8');
83
+ }
84
+ catch (error) {
85
+ const msg = error instanceof Error ? error.message : String(error);
86
+ return {
87
+ content: [
88
+ {
89
+ type: 'text',
90
+ text: `Failed to read the configuration file before applying the credentials.
91
+
92
+ Project path: ${projectCwd}
93
+ File: ${envPath}
94
+ Reason: ${msg}
95
+
96
+ For the assistant:
97
+ - Tell the user that the configuration file exists but could not be read.
98
+ - Summarise the likely cause (permissions, file lock, encoding) in plain language; do not paste the raw error unless the user explicitly asks.
99
+ - Offer to retry once the underlying issue is resolved. Do not mention internal tool names.`,
100
+ },
101
+ ],
102
+ isError: true,
103
+ };
104
+ }
105
+ const fields = {
106
+ LICENSE: args.license,
107
+ SERVER_ADDRESS: args.serverAddress,
108
+ SERVER_PORT: args.serverPort,
109
+ DB_TYPE: args.dbType,
110
+ DB_HOST: args.dbHost,
111
+ DB_PORT: args.dbPort,
112
+ DB_USER: args.dbUser,
113
+ DB_PASSWORD: args.dbPassword,
114
+ DB_NAME: args.dbName,
115
+ };
116
+ const existingEntries = parseEnvFile(existingContent);
117
+ const merged = mergeEnvEntries(existingEntries, fields);
118
+ const newContent = serializeEnvFile(merged.entries);
119
+ // Real I/O failure on write: surface as error per §3.4.
120
+ try {
121
+ await writeFile(envPath, newContent, 'utf-8');
122
+ }
123
+ catch (error) {
124
+ const msg = error instanceof Error ? error.message : String(error);
125
+ return {
126
+ content: [
127
+ {
128
+ type: 'text',
129
+ text: `Failed to write the credentials to the configuration file.
130
+
131
+ Project path: ${projectCwd}
132
+ File: ${envPath}
133
+ Reason: ${msg}
134
+
135
+ For the assistant:
136
+ - Tell the user that the credentials could not be saved.
137
+ - Summarise the likely cause (permissions, disk full, file lock) in plain language; do not paste the raw error unless the user explicitly asks.
138
+ - The original file is unchanged. Offer to retry once the underlying issue is resolved. Do not mention internal tool names.`,
139
+ },
140
+ ],
141
+ isError: true,
142
+ };
143
+ }
144
+ // Success: labeled facts + masked summary per §3.5.
145
+ const updatedKeys = merged.updated.map((u) => u.key);
146
+ const addedKeys = merged.added.map((a) => a.key);
147
+ const unchangedCount = merged.unchanged.length;
148
+ const text = `Credentials and connection settings written successfully.
149
+
150
+ Project path: ${projectCwd}
151
+ File: ${envPath}
152
+ License: ${args.license.slice(0, 4)}-****-****-****
153
+ Server: ${args.serverAddress}:${args.serverPort}
154
+ Database: ${args.dbType}://${args.dbUser}:***@${args.dbHost}:${args.dbPort}/${args.dbName}
155
+
156
+ Updated keys (${updatedKeys.length}): ${updatedKeys.join(', ') || '(none)'}
157
+ Added keys (${addedKeys.length}): ${addedKeys.join(', ') || '(none)'}
158
+ Unchanged keys (${unchangedCount}): preserved (Live Sync, Redis, Kafka, Logging, etc.)
159
+
160
+ For the assistant:
161
+ - Confirm to the user that the license and database credentials were saved.
162
+ - Summarise in plain language: which database is configured (type, host, name) and that the license is set; do not echo the literal license key or password.
163
+ - Do not paste the masked summary block verbatim unless the user explicitly asks for the details.
164
+ - Suggest validating the configuration as the next step (license check + database connectivity). Do not mention internal tool names.`;
165
+ return { content: [{ type: 'text', text }] };
166
+ });
167
+ }
168
+ //# sourceMappingURL=write-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-env.js","sourceRoot":"","sources":["../../../src/tools/setup/write-env.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "@restforgejs/mcp-server",
3
+ "version": "1.2.0",
4
+ "description": "MCP server for RESTForge - enables AI agents to interact with RESTForge via natural language",
5
+ "type": "module",
6
+ "bin": {
7
+ "restforge-mcp": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsx src/index.ts",
13
+ "start": "node dist/index.js",
14
+ "inspect": "npx @modelcontextprotocol/inspector node dist/index.js"
15
+ },
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "restforge",
23
+ "ai-agent",
24
+ "claude",
25
+ "cursor",
26
+ "rest-api",
27
+ "code-generator"
28
+ ],
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "LICENSE.md"
33
+ ],
34
+ "license": "MIT",
35
+ "author": {
36
+ "name": "RESTForge Development Team",
37
+ "url": "https://restforge.dev"
38
+ },
39
+ "repository": {
40
+ "type": "git",
41
+ "url": "git+https://github.com/restforge/restforge-mcp.git"
42
+ },
43
+ "homepage": "https://github.com/restforge/restforge-mcp#readme",
44
+ "bugs": {
45
+ "url": "https://github.com/restforge/restforge-mcp/issues"
46
+ },
47
+ "publishConfig": {
48
+ "access": "public"
49
+ },
50
+ "dependencies": {
51
+ "@modelcontextprotocol/sdk": "^1.29.0",
52
+ "execa": "^9.6.1",
53
+ "zod": "^4.4.2"
54
+ },
55
+ "devDependencies": {
56
+ "@types/node": "^25.6.0",
57
+ "tsx": "^4.21.0",
58
+ "typescript": "^6.0.3"
59
+ }
60
+ }