@restforgejs/mcp-server 1.2.2 → 1.2.4

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 (80) hide show
  1. package/dist/server.js +71 -2
  2. package/dist/server.js.map +1 -1
  3. package/dist/tools/codegen/create-kafka-consumer.d.ts +2 -0
  4. package/dist/tools/codegen/create-kafka-consumer.js +140 -0
  5. package/dist/tools/codegen/create-kafka-consumer.js.map +1 -0
  6. package/dist/tools/codegen/create-processor.d.ts +2 -0
  7. package/dist/tools/codegen/create-processor.js +157 -0
  8. package/dist/tools/codegen/create-processor.js.map +1 -0
  9. package/dist/tools/codegen/generate-test.d.ts +2 -0
  10. package/dist/tools/codegen/generate-test.js +149 -0
  11. package/dist/tools/codegen/generate-test.js.map +1 -0
  12. package/dist/tools/codegen/index.js +8 -0
  13. package/dist/tools/codegen/index.js.map +1 -1
  14. package/dist/tools/codegen/migrate-payload.d.ts +2 -0
  15. package/dist/tools/codegen/migrate-payload.js +210 -0
  16. package/dist/tools/codegen/migrate-payload.js.map +1 -0
  17. package/dist/tools/data/index.d.ts +2 -0
  18. package/dist/tools/data/index.js +7 -0
  19. package/dist/tools/data/index.js.map +1 -0
  20. package/dist/tools/data/pull.d.ts +2 -0
  21. package/dist/tools/data/pull.js +202 -0
  22. package/dist/tools/data/pull.js.map +1 -0
  23. package/dist/tools/data/push.d.ts +2 -0
  24. package/dist/tools/data/push.js +190 -0
  25. package/dist/tools/data/push.js.map +1 -0
  26. package/dist/tools/designer/generate.js +86 -81
  27. package/dist/tools/designer/generate.js.map +1 -1
  28. package/dist/tools/designer/get-udf-catalog.d.ts +2 -0
  29. package/dist/tools/designer/get-udf-catalog.js +225 -0
  30. package/dist/tools/designer/get-udf-catalog.js.map +1 -0
  31. package/dist/tools/designer/index.js +2 -0
  32. package/dist/tools/designer/index.js.map +1 -1
  33. package/dist/tools/designer/init-project.js +73 -73
  34. package/dist/tools/designer/inspect-plugin.js +70 -65
  35. package/dist/tools/designer/inspect-plugin.js.map +1 -1
  36. package/dist/tools/designer/list-plugins.js +62 -62
  37. package/dist/tools/designer/preview-files.js +72 -67
  38. package/dist/tools/designer/preview-files.js.map +1 -1
  39. package/dist/tools/designer/scaffold-plugin.js +72 -72
  40. package/dist/tools/designer/validate-payload.js +74 -69
  41. package/dist/tools/designer/validate-payload.js.map +1 -1
  42. package/dist/tools/key/generate.d.ts +2 -0
  43. package/dist/tools/key/generate.js +130 -0
  44. package/dist/tools/key/generate.js.map +1 -0
  45. package/dist/tools/key/index.d.ts +2 -0
  46. package/dist/tools/key/index.js +9 -0
  47. package/dist/tools/key/index.js.map +1 -0
  48. package/dist/tools/key/list.d.ts +2 -0
  49. package/dist/tools/key/list.js +126 -0
  50. package/dist/tools/key/list.js.map +1 -0
  51. package/dist/tools/key/revoke.d.ts +2 -0
  52. package/dist/tools/key/revoke.js +117 -0
  53. package/dist/tools/key/revoke.js.map +1 -0
  54. package/dist/tools/project/delete.d.ts +2 -0
  55. package/dist/tools/project/delete.js +116 -0
  56. package/dist/tools/project/delete.js.map +1 -0
  57. package/dist/tools/project/index.d.ts +2 -0
  58. package/dist/tools/project/index.js +7 -0
  59. package/dist/tools/project/index.js.map +1 -0
  60. package/dist/tools/project/list.d.ts +2 -0
  61. package/dist/tools/project/list.js +107 -0
  62. package/dist/tools/project/list.js.map +1 -0
  63. package/dist/tools/runtime/generate-launcher.js +3 -3
  64. package/dist/tools/setup/clear-default-config.d.ts +2 -0
  65. package/dist/tools/setup/clear-default-config.js +104 -0
  66. package/dist/tools/setup/clear-default-config.js.map +1 -0
  67. package/dist/tools/setup/get-default-config.d.ts +2 -0
  68. package/dist/tools/setup/get-default-config.js +104 -0
  69. package/dist/tools/setup/get-default-config.js.map +1 -0
  70. package/dist/tools/setup/index.js +8 -0
  71. package/dist/tools/setup/index.js.map +1 -1
  72. package/dist/tools/setup/init-config.js +3 -5
  73. package/dist/tools/setup/init-config.js.map +1 -1
  74. package/dist/tools/setup/list-configs.d.ts +2 -0
  75. package/dist/tools/setup/list-configs.js +104 -0
  76. package/dist/tools/setup/list-configs.js.map +1 -0
  77. package/dist/tools/setup/set-default-config.d.ts +2 -0
  78. package/dist/tools/setup/set-default-config.js +109 -0
  79. package/dist/tools/setup/set-default-config.js.map +1 -0
  80. package/package.json +1 -1
@@ -0,0 +1,130 @@
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 registerKeyGenerate(server) {
6
+ server.registerTool('key_generate', {
7
+ title: 'Generate API Key',
8
+ description: `Generate a new API key and write it into an .env file, by wrapping restforge key generate.
9
+
10
+ USE WHEN:
11
+ - The user wants to create/generate a new API key for a RESTForge project, e.g. "buat api key", "generate api key", "bikin key baru"
12
+ - The user is setting up authentication and needs a key written to .env
13
+
14
+ DO NOT USE FOR:
15
+ - Listing existing keys -> use 'key_list'
16
+ - Revoking a key -> use 'key_revoke'
17
+ - Writing arbitrary env values -> use 'setup_write_env'
18
+
19
+ This tool runs: npx restforge key generate [--output] [--force] in the given cwd.
20
+
21
+ NON-INTERACTIVE NOTE: if a key already exists in the output file and 'force' is not set, the CLI asks for overwrite confirmation. In this non-interactive context that prompt cannot be answered and the call may stall until timeout — set 'force' to regenerate over an existing key. Generating into a file with no existing key works without 'force'.
22
+
23
+ SECURITY NOTE: the generated key value is sensitive and will appear in this tool's output. Do not echo it back to the user in plain text unless they ask; the key is written to the .env file.
24
+
25
+ Preconditions:
26
+ - The project must have @restforgejs/platform installed in node_modules.
27
+
28
+ PRESENTATION GUIDANCE:
29
+ - Match the user's language. Never mention internal tool names; describe the action (e.g. "generate the API key").
30
+ - Confirm the key was written to the target file; do not paste the raw key unless the user explicitly asks for it.
31
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
32
+ inputSchema: {
33
+ cwd: z
34
+ .string()
35
+ .min(1)
36
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform)'),
37
+ output: z
38
+ .string()
39
+ .min(1)
40
+ .optional()
41
+ .describe('Output .env file to write the key into (relative to cwd; must be INSIDE the project directory — the CLI rejects paths outside cwd). When omitted, the CLI uses its default (.env).'),
42
+ force: z
43
+ .boolean()
44
+ .optional()
45
+ .describe('Overwrite an existing key without confirmation. Set this to regenerate over an existing key (otherwise the CLI may prompt and stall).'),
46
+ },
47
+ annotations: {
48
+ title: 'Generate API Key',
49
+ readOnlyHint: false,
50
+ idempotentHint: false,
51
+ destructiveHint: false,
52
+ },
53
+ }, async ({ cwd, output, force }) => {
54
+ const projectCwd = resolve(cwd);
55
+ try {
56
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
57
+ }
58
+ catch {
59
+ return {
60
+ content: [
61
+ {
62
+ type: 'text',
63
+ text: `Precondition not met: the RESTForge package is not installed in this project.
64
+
65
+ Project path: ${projectCwd}
66
+ Expected location: node_modules/@restforgejs/platform
67
+
68
+ For the assistant:
69
+ - The user needs to install the RESTForge package before an API key can be generated. Suggest installing it first, then retry. Do not mention internal tool names.`,
70
+ },
71
+ ],
72
+ isError: false,
73
+ };
74
+ }
75
+ const args = ['restforge', 'key', 'generate'];
76
+ if (output)
77
+ args.push(`--output=${output}`);
78
+ if (force)
79
+ args.push('--force');
80
+ const result = await execProcess('npx', args, { cwd: projectCwd, timeout: 60_000 });
81
+ if (!result.success) {
82
+ return {
83
+ content: [
84
+ {
85
+ type: 'text',
86
+ text: `Failed to generate the API key.
87
+
88
+ Project path: ${projectCwd}
89
+ Output: ${output ?? 'default (.env)'}
90
+ Command: ${result.command}
91
+ Exit code: ${result.exitCode}
92
+
93
+ --- CLI output ---
94
+ stdout:
95
+ ${result.stdout}
96
+
97
+ stderr:
98
+ ${result.stderr}
99
+ --- end CLI output ---
100
+
101
+ For the assistant:
102
+ - Tell the user the API key was not generated. A common cause is that a key already exists and overwrite was not allowed (the operation may have stalled waiting for confirmation) — suggest retrying with overwrite enabled. Do not paste raw output unless asked. Do not mention internal tool names.`,
103
+ },
104
+ ],
105
+ isError: true,
106
+ };
107
+ }
108
+ return {
109
+ content: [
110
+ {
111
+ type: 'text',
112
+ text: `API key generated.
113
+
114
+ Project path: ${projectCwd}
115
+ Output: ${output ?? 'default (.env)'}
116
+ Command: ${result.command}
117
+
118
+ --- CLI output ---
119
+ ${result.stdout}
120
+ --- end CLI output ---
121
+
122
+ For the assistant:
123
+ - Confirm the key was written to the target .env file. Treat the key value as a secret: do not repeat it back in plain text unless the user explicitly asks.
124
+ - Keep the reply concise. Do not mention internal tool names.`,
125
+ },
126
+ ],
127
+ };
128
+ });
129
+ }
130
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/tools/key/generate.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,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,YAAY,CACjB,cAAc,EACd;QACE,KAAK,EAAE,kBAAkB;QACzB,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;;;;uGAuBoF;QACjG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,uFAAuF,CAAC;YACpG,MAAM,EAAE,CAAC;iBACN,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,EAAE;iBACV,QAAQ,CAAC,oLAAoL,CAAC;YACjM,KAAK,EAAE,CAAC;iBACL,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,uIAAuI,CAAC;SACrJ;QACD,WAAW,EAAE;YACX,KAAK,EAAE,kBAAkB;YACzB,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,KAAK;YACrB,eAAe,EAAE,KAAK;SACvB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE;QAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,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;;;;mKAIyI;qBACtJ;iBACF;gBACD,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;QAC9C,IAAI,MAAM;YAAE,IAAI,CAAC,IAAI,CAAC,YAAY,MAAM,EAAE,CAAC,CAAC;QAC5C,IAAI,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEpF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;UAChB,MAAM,IAAI,gBAAgB;WACzB,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;wSAIyR;qBAC3R;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;UAChB,MAAM,IAAI,gBAAgB;WACzB,MAAM,CAAC,OAAO;;;EAGvB,MAAM,CAAC,MAAM;;;;;8DAK+C;iBACnD;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 registerKeyTools(server: McpServer): void;
@@ -0,0 +1,9 @@
1
+ import { registerKeyGenerate } from './generate.js';
2
+ import { registerKeyList } from './list.js';
3
+ import { registerKeyRevoke } from './revoke.js';
4
+ export function registerKeyTools(server) {
5
+ registerKeyGenerate(server);
6
+ registerKeyList(server);
7
+ registerKeyRevoke(server);
8
+ }
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/key/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,eAAe,CAAC,MAAM,CAAC,CAAC;IACxB,iBAAiB,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerKeyList(server: McpServer): void;
@@ -0,0 +1,126 @@
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 registerKeyList(server) {
6
+ server.registerTool('key_list', {
7
+ title: 'List API Keys',
8
+ description: `List the registered API keys found in .env files (masked by default), by wrapping restforge key list.
9
+
10
+ USE WHEN:
11
+ - The user wants to see which API keys exist, e.g. "lihat api key", "daftar key", "list api keys", "key apa saja yang terdaftar"
12
+
13
+ DO NOT USE FOR:
14
+ - Generating a new key -> use 'key_generate'
15
+ - Revoking a key -> use 'key_revoke'
16
+
17
+ This tool runs: npx restforge key list [--show-full] [--dir] in the given cwd.
18
+
19
+ SECURITY NOTE: by default keys are shown MASKED. 'showFull' reveals the full secret key values in this tool's output — only enable it when the user explicitly asks, and avoid repeating full keys back to the user.
20
+
21
+ Preconditions:
22
+ - The project must have @restforgejs/platform installed in node_modules.
23
+
24
+ PRESENTATION GUIDANCE:
25
+ - Match the user's language. Never mention internal tool names; describe the action (e.g. "list the API keys").
26
+ - Summarise how many keys are present and where; keep masked values masked. Do not paste full key values unless the user explicitly asked and 'showFull' was used.
27
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
28
+ inputSchema: {
29
+ cwd: z
30
+ .string()
31
+ .min(1)
32
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform)'),
33
+ showFull: z
34
+ .boolean()
35
+ .optional()
36
+ .describe('Reveal full (unmasked) key values. SECURITY: only when the user explicitly asks. When omitted, keys are masked.'),
37
+ dir: z
38
+ .string()
39
+ .min(1)
40
+ .optional()
41
+ .describe('Directory to search for .env files. When omitted, the CLI uses the current working directory.'),
42
+ },
43
+ annotations: {
44
+ title: 'List API Keys',
45
+ readOnlyHint: true,
46
+ idempotentHint: true,
47
+ },
48
+ }, async ({ cwd, showFull, dir }) => {
49
+ const projectCwd = resolve(cwd);
50
+ try {
51
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
52
+ }
53
+ catch {
54
+ return {
55
+ content: [
56
+ {
57
+ type: 'text',
58
+ text: `Precondition not met: the RESTForge package is not installed in this project.
59
+
60
+ Project path: ${projectCwd}
61
+ Expected location: node_modules/@restforgejs/platform
62
+
63
+ For the assistant:
64
+ - The user needs to install the RESTForge package before API keys can be listed. Suggest installing it first, then retry. Do not mention internal tool names.`,
65
+ },
66
+ ],
67
+ isError: false,
68
+ };
69
+ }
70
+ const args = ['restforge', 'key', 'list'];
71
+ if (showFull)
72
+ args.push('--show-full');
73
+ if (dir)
74
+ args.push(`--dir=${dir}`);
75
+ const result = await execProcess('npx', args, { cwd: projectCwd, timeout: 30_000 });
76
+ if (!result.success) {
77
+ return {
78
+ content: [
79
+ {
80
+ type: 'text',
81
+ text: `Failed to list API keys.
82
+
83
+ Project path: ${projectCwd}
84
+ Dir: ${dir ?? 'cwd'}
85
+ Command: ${result.command}
86
+ Exit code: ${result.exitCode}
87
+
88
+ --- CLI output ---
89
+ stdout:
90
+ ${result.stdout}
91
+
92
+ stderr:
93
+ ${result.stderr}
94
+ --- end CLI output ---
95
+
96
+ For the assistant:
97
+ - Tell the user the keys could not be listed; summarise the likely cause from the output (e.g. the search directory does not exist). Do not paste raw output unless asked. Do not mention internal tool names.`,
98
+ },
99
+ ],
100
+ isError: true,
101
+ };
102
+ }
103
+ return {
104
+ content: [
105
+ {
106
+ type: 'text',
107
+ text: `API keys listed${showFull ? ' (FULL/unmasked)' : ' (masked)'}.
108
+
109
+ Project path: ${projectCwd}
110
+ Dir: ${dir ?? 'cwd'}
111
+ Command: ${result.command}
112
+
113
+ --- CLI output ---
114
+ ${result.stdout}
115
+ --- end CLI output ---
116
+
117
+ For the assistant:
118
+ - Read the output and tell the user how many keys are present and in which file(s).
119
+ - ${showFull ? 'Full key values were requested; still avoid repeating the secrets back unless necessary.' : 'Values are masked; do not attempt to unmask unless the user explicitly asks.'}
120
+ - Keep the reply concise. Do not mention internal tool names.`,
121
+ },
122
+ ],
123
+ };
124
+ });
125
+ }
126
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/tools/key/list.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,eAAe,CAAC,MAAiB;IAC/C,MAAM,CAAC,YAAY,CACjB,UAAU,EACV;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EAAE;;;;;;;;;;;;;;;;;;;uGAmBoF;QACjG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,uFAAuF,CAAC;YACpG,QAAQ,EAAE,CAAC;iBACR,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,iHAAiH,CAAC;YAC9H,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,EAAE;iBACV,QAAQ,CAAC,+FAA+F,CAAC;SAC7G;QACD,WAAW,EAAE;YACX,KAAK,EAAE,eAAe;YACtB,YAAY,EAAE,IAAI;YAClB,cAAc,EAAE,IAAI;SACrB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,EAAE;QAC/B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,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;;;;8JAIoI;qBACjJ;iBACF;gBACD,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC1C,IAAI,QAAQ;YAAE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACvC,IAAI,GAAG;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;QAEnC,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEpF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;OACnB,GAAG,IAAI,KAAK;WACR,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;+MAIgM;qBAClM;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,kBAAkB,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,WAAW;;gBAE/D,UAAU;OACnB,GAAG,IAAI,KAAK;WACR,MAAM,CAAC,OAAO;;;EAGvB,MAAM,CAAC,MAAM;;;;;IAKX,QAAQ,CAAC,CAAC,CAAC,0FAA0F,CAAC,CAAC,CAAC,8EAA8E;8DAC5H;iBACnD;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 registerKeyRevoke(server: McpServer): void;
@@ -0,0 +1,117 @@
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 registerKeyRevoke(server) {
6
+ server.registerTool('key_revoke', {
7
+ title: 'Revoke API Key',
8
+ description: `Revoke (remove) an API key from an .env file, by wrapping restforge key revoke.
9
+
10
+ USE WHEN:
11
+ - The user wants to revoke, remove, or invalidate an API key, e.g. "revoke api key", "cabut key", "hapus api key dari .env"
12
+
13
+ DO NOT USE FOR:
14
+ - Generating a key -> use 'key_generate'
15
+ - Listing keys -> use 'key_list'
16
+
17
+ This tool runs: npx restforge key revoke --file=<file> --yes in the given cwd. The 'file' argument is REQUIRED (without it the CLI would drop into an interactive file picker, which cannot be answered here), and '--yes' is always passed to skip the confirmation prompt — so this tool revokes immediately without further confirmation.
18
+
19
+ IMPORTANT — this is destructive: it removes the key from the named .env file. Confirm the file and intent with the user BEFORE calling this tool, because the revoke happens without an additional in-tool confirmation step.
20
+
21
+ Preconditions:
22
+ - The project must have @restforgejs/platform installed in node_modules.
23
+ - The named .env file must exist and contain a key. This tool does not pre-check it; the failure response surfaces the cause.
24
+
25
+ PRESENTATION GUIDANCE:
26
+ - Match the user's language. Never mention internal tool names; describe the action (e.g. "revoke the API key").
27
+ - Confirm which file the key was revoked from. Keep the reply concise.
28
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
29
+ inputSchema: {
30
+ cwd: z
31
+ .string()
32
+ .min(1)
33
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform)'),
34
+ file: z
35
+ .string()
36
+ .min(1)
37
+ .describe('Path to the .env file containing the key to revoke (relative to cwd; must be INSIDE the project directory — the CLI rejects paths outside cwd). REQUIRED (avoids the interactive file picker).'),
38
+ },
39
+ annotations: {
40
+ title: 'Revoke API Key',
41
+ readOnlyHint: false,
42
+ idempotentHint: false,
43
+ destructiveHint: true,
44
+ },
45
+ }, async ({ cwd, file }) => {
46
+ const projectCwd = resolve(cwd);
47
+ try {
48
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
49
+ }
50
+ catch {
51
+ return {
52
+ content: [
53
+ {
54
+ type: 'text',
55
+ text: `Precondition not met: the RESTForge package is not installed in this project.
56
+
57
+ Project path: ${projectCwd}
58
+ Expected location: node_modules/@restforgejs/platform
59
+
60
+ For the assistant:
61
+ - The user needs to install the RESTForge package before an API key can be revoked. Suggest installing it first, then retry. Do not mention internal tool names.`,
62
+ },
63
+ ],
64
+ isError: false,
65
+ };
66
+ }
67
+ const args = ['restforge', 'key', 'revoke', `--file=${file}`, '--yes'];
68
+ const result = await execProcess('npx', args, { cwd: projectCwd, timeout: 30_000 });
69
+ if (!result.success) {
70
+ return {
71
+ content: [
72
+ {
73
+ type: 'text',
74
+ text: `Failed to revoke the API key.
75
+
76
+ Project path: ${projectCwd}
77
+ File: ${file}
78
+ Command: ${result.command}
79
+ Exit code: ${result.exitCode}
80
+
81
+ --- CLI output ---
82
+ stdout:
83
+ ${result.stdout}
84
+
85
+ stderr:
86
+ ${result.stderr}
87
+ --- end CLI output ---
88
+
89
+ For the assistant:
90
+ - Tell the user the key was not revoked; summarise the likely cause (e.g. the file does not exist or contains no key). Do not paste raw output unless asked. Do not mention internal tool names.`,
91
+ },
92
+ ],
93
+ isError: true,
94
+ };
95
+ }
96
+ return {
97
+ content: [
98
+ {
99
+ type: 'text',
100
+ text: `API key revoked.
101
+
102
+ Project path: ${projectCwd}
103
+ File: ${file}
104
+ Command: ${result.command}
105
+
106
+ --- CLI output ---
107
+ ${result.stdout}
108
+ --- end CLI output ---
109
+
110
+ For the assistant:
111
+ - Confirm the key was revoked from the named file. Keep the reply concise. Do not mention internal tool names.`,
112
+ },
113
+ ],
114
+ };
115
+ });
116
+ }
117
+ //# sourceMappingURL=revoke.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"revoke.js","sourceRoot":"","sources":["../../../src/tools/key/revoke.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,iBAAiB,CAAC,MAAiB;IACjD,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;uGAoBoF;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,CAAC,gMAAgM,CAAC;SAC9M;QACD,WAAW,EAAE;YACX,KAAK,EAAE,gBAAgB;YACvB,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,KAAK;YACrB,eAAe,EAAE,IAAI;SACtB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE;QACtB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,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;;;;iKAIuI;qBACpJ;iBACF;gBACD,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;QAEvE,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEpF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;QAClB,IAAI;WACD,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;iMAIkL;qBACpL;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;QAClB,IAAI;WACD,MAAM,CAAC,OAAO;;;EAGvB,MAAM,CAAC,MAAM;;;;+GAIgG;iBACpG;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 registerProjectDelete(server: McpServer): void;
@@ -0,0 +1,116 @@
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 registerProjectDelete(server) {
6
+ server.registerTool('project_delete', {
7
+ title: 'Delete Project',
8
+ description: `Delete a project from the RESTForge registry, INCLUDING all of its endpoints, processors, dashboards, and consumers, by wrapping restforge project delete.
9
+
10
+ USE WHEN:
11
+ - The user explicitly wants to delete/remove an entire project, e.g. "hapus project", "delete project", "remove project beserta isinya"
12
+
13
+ DO NOT USE FOR:
14
+ - Listing projects -> use 'project_list'
15
+ - Deleting a single endpoint/processor/dashboard -> out of scope (this removes the WHOLE project)
16
+
17
+ This tool runs: npx restforge project delete --project=<project> --yes in the given cwd. '--yes' is always passed to skip the confirmation prompt (the prompt cannot be answered in this non-interactive context), so the deletion happens immediately.
18
+
19
+ IMPORTANT — this is highly destructive and not reversible here: it removes the entire project and every endpoint, processor, dashboard, and consumer inside it. There is NO additional in-tool confirmation. ALWAYS confirm the exact project name and intent with the user BEFORE calling this tool; consider listing projects first to verify the name.
20
+
21
+ Preconditions:
22
+ - The project must have @restforgejs/platform installed in node_modules.
23
+ - The named project must exist in the registry. This tool does not pre-check it; the failure response surfaces the cause.
24
+
25
+ PRESENTATION GUIDANCE:
26
+ - Match the user's language. Never mention internal tool names; describe the action (e.g. "delete the project").
27
+ - Confirm what was deleted. Keep the reply concise.
28
+ - When a precondition is not met, frame it as a question or next-step suggestion rather than an error.`,
29
+ inputSchema: {
30
+ cwd: z
31
+ .string()
32
+ .min(1)
33
+ .describe('Absolute path of the project folder (must contain node_modules/@restforgejs/platform)'),
34
+ project: z
35
+ .string()
36
+ .min(1)
37
+ .describe('Name of the project to delete (and everything inside it). REQUIRED. Verify with the user first.'),
38
+ },
39
+ annotations: {
40
+ title: 'Delete Project',
41
+ readOnlyHint: false,
42
+ idempotentHint: false,
43
+ destructiveHint: true,
44
+ },
45
+ }, async ({ cwd, project }) => {
46
+ const projectCwd = resolve(cwd);
47
+ try {
48
+ await access(join(projectCwd, 'node_modules', '@restforgejs', 'platform'));
49
+ }
50
+ catch {
51
+ return {
52
+ content: [
53
+ {
54
+ type: 'text',
55
+ text: `Precondition not met: the RESTForge package is not installed in this project.
56
+
57
+ Project path: ${projectCwd}
58
+ Expected location: node_modules/@restforgejs/platform
59
+
60
+ For the assistant:
61
+ - The user needs to install the RESTForge package before a project can be deleted. Suggest installing it first, then retry. Do not mention internal tool names.`,
62
+ },
63
+ ],
64
+ isError: false,
65
+ };
66
+ }
67
+ const result = await execProcess('npx', ['restforge', 'project', 'delete', `--project=${project}`, '--yes'], { cwd: projectCwd, timeout: 30_000 });
68
+ if (!result.success) {
69
+ return {
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: `Failed to delete the project.
74
+
75
+ Project path: ${projectCwd}
76
+ Project: ${project}
77
+ Command: ${result.command}
78
+ Exit code: ${result.exitCode}
79
+
80
+ --- CLI output ---
81
+ stdout:
82
+ ${result.stdout}
83
+
84
+ stderr:
85
+ ${result.stderr}
86
+ --- end CLI output ---
87
+
88
+ For the assistant:
89
+ - Tell the user the project was not deleted; summarise the likely cause (e.g. the project name does not exist in the registry). Do not paste raw output unless asked. Do not mention internal tool names.`,
90
+ },
91
+ ],
92
+ isError: true,
93
+ };
94
+ }
95
+ return {
96
+ content: [
97
+ {
98
+ type: 'text',
99
+ text: `Project deleted.
100
+
101
+ Project path: ${projectCwd}
102
+ Project: ${project}
103
+ Command: ${result.command}
104
+
105
+ --- CLI output ---
106
+ ${result.stdout}
107
+ --- end CLI output ---
108
+
109
+ For the assistant:
110
+ - Confirm the project and all its contents (endpoints, processors, dashboards, consumers) were removed. Keep the reply concise. Do not mention internal tool names.`,
111
+ },
112
+ ],
113
+ };
114
+ });
115
+ }
116
+ //# sourceMappingURL=delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.js","sourceRoot":"","sources":["../../../src/tools/project/delete.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,qBAAqB,CAAC,MAAiB;IACrD,MAAM,CAAC,YAAY,CACjB,gBAAgB,EAChB;QACE,KAAK,EAAE,gBAAgB;QACvB,WAAW,EAAE;;;;;;;;;;;;;;;;;;;;uGAoBoF;QACjG,WAAW,EAAE;YACX,GAAG,EAAE,CAAC;iBACH,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,uFAAuF,CAAC;YACpG,OAAO,EAAE,CAAC;iBACP,MAAM,EAAE;iBACR,GAAG,CAAC,CAAC,CAAC;iBACN,QAAQ,CAAC,iGAAiG,CAAC;SAC/G;QACD,WAAW,EAAE;YACX,KAAK,EAAE,gBAAgB;YACvB,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,KAAK;YACrB,eAAe,EAAE,IAAI;SACtB;KACF,EACD,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EAAE;QACzB,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,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;;;;gKAIsI;qBACnJ;iBACF;gBACD,OAAO,EAAE,KAAK;aACf,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,OAAO,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAEnJ,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE;;gBAEJ,UAAU;WACf,OAAO;WACP,MAAM,CAAC,OAAO;aACZ,MAAM,CAAC,QAAQ;;;;EAI1B,MAAM,CAAC,MAAM;;;EAGb,MAAM,CAAC,MAAM;;;;0MAI2L;qBAC7L;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;gBAEF,UAAU;WACf,OAAO;WACP,MAAM,CAAC,OAAO;;;EAGvB,MAAM,CAAC,MAAM;;;;oKAIqJ;iBACzJ;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 registerProjectTools(server: McpServer): void;
@@ -0,0 +1,7 @@
1
+ import { registerProjectList } from './list.js';
2
+ import { registerProjectDelete } from './delete.js';
3
+ export function registerProjectTools(server) {
4
+ registerProjectList(server);
5
+ registerProjectDelete(server);
6
+ }
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/project/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC5B,qBAAqB,CAAC,MAAM,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ export declare function registerProjectList(server: McpServer): void;