@viberaven/mcp 0.1.0-beta.1 → 1.0.1
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.
- package/README.md +43 -7
- package/bin/server.js +214 -69
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -4,20 +4,56 @@ Thin MCP wrapper for VibeRaven.
|
|
|
4
4
|
|
|
5
5
|
This package exposes VibeRaven CLI actions as MCP tools for Codex, Claude Code, Cursor, and other agent runtimes. It does not contain VibeRaven backend logic and does not bypass VibeRaven login or scan quotas.
|
|
6
6
|
|
|
7
|
+
The MCP server wraps the stable CLI package: `npx -y viberaven`.
|
|
8
|
+
|
|
7
9
|
## Run
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
|
-
npx -y @viberaven/mcp
|
|
12
|
+
npx -y @viberaven/mcp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
You can also start the MCP server from the main CLI package:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx -y viberaven mcp
|
|
11
19
|
```
|
|
12
20
|
|
|
13
21
|
## Tools
|
|
14
22
|
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
17
|
-
- `
|
|
18
|
-
- `
|
|
19
|
-
- `
|
|
23
|
+
- `viberaven_check_readiness` -> `npx -y viberaven --agent-mode`
|
|
24
|
+
- `viberaven_verify` -> `npx -y viberaven --verify`
|
|
25
|
+
- `viberaven_audit` -> `npx -y viberaven audit --vercel-supabase`
|
|
26
|
+
- `viberaven_init_rules` -> `npx -y viberaven init`
|
|
27
|
+
- `viberaven_clean_plan` -> `npx -y viberaven clean --plan`
|
|
28
|
+
- `viberaven_strict_gate` -> `npx -y viberaven --agent-mode --strict --json`
|
|
29
|
+
- `viberaven_gate_result` -> `npx -y viberaven --agent-mode --json`
|
|
30
|
+
- `viberaven_context_map` -> `npx -y viberaven --condense`
|
|
31
|
+
- `viberaven_heal_plan` -> `npx -y viberaven --heal --plan`
|
|
32
|
+
- `viberaven_heal_prompt` -> `npx -y viberaven --heal --prompt`
|
|
33
|
+
- `viberaven_heal_apply` -> `npx -y viberaven --heal --apply`
|
|
34
|
+
|
|
35
|
+
`viberaven_check_readiness` is the canonical entrypoint. It runs VibeRaven as the Agent Context + Production Gate and writes `.viberaven/agent-tasklist.md`, `.viberaven/gate-result.json`, and `.viberaven/context-map.json`.
|
|
36
|
+
|
|
37
|
+
After one fix, call `viberaven_verify`. Before deploy or CI pass, call `viberaven_strict_gate` or run:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx -y viberaven --strict
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Machine Artifact Contract
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
docs/contracts/artifacts.md
|
|
47
|
+
https://viberaven.dev/schemas/gate-result.schema.json
|
|
48
|
+
https://viberaven.dev/schemas/context-map.schema.json
|
|
49
|
+
https://viberaven.dev/schemas/gap.schema.json
|
|
50
|
+
https://viberaven.dev/schemas/heal-result.schema.json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Login
|
|
54
|
+
|
|
55
|
+
If VibeRaven prints `LOGIN_URL_READY`, open that exact URL for the user, keep the MCP call alive, and do not ask for passwords, tokens, cookies, or other secrets.
|
|
20
56
|
|
|
21
57
|
## Security
|
|
22
58
|
|
|
23
|
-
The MCP package is public integration glue only.
|
|
59
|
+
The MCP package is public integration glue only. It returns CLI stdout/stderr and structured JSON content when available. It does not mutate provider dashboards and does not bypass VibeRaven login, managed API checks, or quota enforcement. Do not claim provider dashboard checks are fixed by repo-code edits.
|
package/bin/server.js
CHANGED
|
@@ -1,84 +1,116 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
const { spawn } = require('node:child_process');
|
|
3
|
+
let spawnChild = spawn;
|
|
3
4
|
|
|
4
|
-
const SERVER_INFO = { name: 'viberaven-mcp', version: '
|
|
5
|
+
const SERVER_INFO = { name: 'viberaven-mcp', version: '1.0.0' };
|
|
6
|
+
const CLI_PACKAGE = '@viberaven/cli';
|
|
7
|
+
|
|
8
|
+
const cwdSchema = {
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
cwd: { type: 'string', description: 'Project root. Defaults to the MCP server working directory.' }
|
|
12
|
+
},
|
|
13
|
+
additionalProperties: false
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const healSchema = {
|
|
17
|
+
type: 'object',
|
|
18
|
+
properties: {
|
|
19
|
+
cwd: { type: 'string' },
|
|
20
|
+
target: { type: 'string' },
|
|
21
|
+
gap: { type: 'string' },
|
|
22
|
+
yes: { type: 'boolean' }
|
|
23
|
+
},
|
|
24
|
+
additionalProperties: false
|
|
25
|
+
};
|
|
5
26
|
|
|
6
27
|
const TOOLS = [
|
|
7
28
|
{
|
|
8
|
-
name: '
|
|
9
|
-
description: 'Run VibeRaven
|
|
10
|
-
inputSchema:
|
|
11
|
-
type: 'object',
|
|
12
|
-
properties: {
|
|
13
|
-
cwd: { type: 'string', description: 'Project root to scan. Defaults to the MCP server working directory.' },
|
|
14
|
-
path: { type: 'string', description: 'Optional path argument passed to viberaven scan.' },
|
|
15
|
-
open: { type: 'boolean', description: 'Open the generated report after scan.' }
|
|
16
|
-
},
|
|
17
|
-
additionalProperties: false
|
|
18
|
-
}
|
|
29
|
+
name: 'viberaven_check_readiness',
|
|
30
|
+
description: 'Run the VibeRaven agent-mode production-readiness check and write .viberaven artifacts.',
|
|
31
|
+
inputSchema: cwdSchema
|
|
19
32
|
},
|
|
20
33
|
{
|
|
21
|
-
name: '
|
|
22
|
-
description: '
|
|
23
|
-
inputSchema:
|
|
24
|
-
type: 'object',
|
|
25
|
-
properties: {
|
|
26
|
-
cwd: { type: 'string', description: 'Project root. Defaults to the MCP server working directory.' },
|
|
27
|
-
json: { type: 'boolean', description: 'Return machine-readable status JSON.' }
|
|
28
|
-
},
|
|
29
|
-
additionalProperties: false
|
|
30
|
-
}
|
|
34
|
+
name: 'viberaven_verify',
|
|
35
|
+
description: 'Rescan and refresh VibeRaven production-readiness artifacts after a fix.',
|
|
36
|
+
inputSchema: cwdSchema
|
|
31
37
|
},
|
|
32
38
|
{
|
|
33
|
-
name: '
|
|
34
|
-
description: '
|
|
39
|
+
name: 'viberaven_audit',
|
|
40
|
+
description: 'Run local Vercel/Supabase production checks for RLS, service-role boundaries, and Vercel pooler usage.',
|
|
35
41
|
inputSchema: {
|
|
36
42
|
type: 'object',
|
|
37
43
|
properties: {
|
|
38
|
-
cwd: { type: 'string', description: 'Project root. Defaults to
|
|
44
|
+
cwd: { type: 'string', description: 'Project root. Defaults to current working directory.' },
|
|
45
|
+
json: { type: 'boolean', description: 'Return JSON output.' }
|
|
39
46
|
},
|
|
40
47
|
additionalProperties: false
|
|
41
48
|
}
|
|
42
49
|
},
|
|
43
50
|
{
|
|
44
|
-
name: '
|
|
45
|
-
description: '
|
|
51
|
+
name: 'viberaven_init_rules',
|
|
52
|
+
description: 'Install bounded VibeRaven rules into native AI instruction files.',
|
|
46
53
|
inputSchema: {
|
|
47
54
|
type: 'object',
|
|
48
55
|
properties: {
|
|
49
|
-
cwd: { type: 'string', description: 'Project root. Defaults to
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
provider: { type: 'string', description: 'Optional provider key.' }
|
|
56
|
+
cwd: { type: 'string', description: 'Project root. Defaults to current working directory.' },
|
|
57
|
+
agents: { type: 'string', description: 'Comma-separated agent targets, or all.' },
|
|
58
|
+
dryRun: { type: 'boolean', description: 'Preview changes without writing files.' }
|
|
53
59
|
},
|
|
54
60
|
additionalProperties: false
|
|
55
61
|
}
|
|
56
62
|
},
|
|
57
63
|
{
|
|
58
|
-
name: '
|
|
59
|
-
description: '
|
|
60
|
-
inputSchema:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
name: 'viberaven_clean_plan',
|
|
65
|
+
description: 'Write a non-destructive context cleanup plan for generated artifacts and logs.',
|
|
66
|
+
inputSchema: cwdSchema
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'viberaven_strict_gate',
|
|
70
|
+
description: 'Run VibeRaven agent-mode strict gate and return the machine verdict.',
|
|
71
|
+
inputSchema: cwdSchema
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'viberaven_gate_result',
|
|
75
|
+
description: 'Run VibeRaven agent-mode JSON output and return gate-result.json content.',
|
|
76
|
+
inputSchema: cwdSchema
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'viberaven_context_map',
|
|
80
|
+
description: 'Refresh .viberaven/context-map.json from the last scan.',
|
|
81
|
+
inputSchema: cwdSchema
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'viberaven_heal_plan',
|
|
85
|
+
description: 'Write a non-destructive VibeRaven heal plan for a target file or gap.',
|
|
86
|
+
inputSchema: healSchema
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'viberaven_heal_prompt',
|
|
90
|
+
description: 'Write an agent-ready VibeRaven heal prompt for a target file or gap.',
|
|
91
|
+
inputSchema: healSchema
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'viberaven_heal_apply',
|
|
95
|
+
description: 'Apply a guarded VibeRaven repo-code heal recipe when supported.',
|
|
96
|
+
inputSchema: healSchema
|
|
67
97
|
}
|
|
68
98
|
];
|
|
69
99
|
|
|
70
|
-
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
71
|
-
console.log(`${SERVER_INFO.name} ${SERVER_INFO.version}`);
|
|
72
|
-
console.log('MCP stdio server wrapping npx -y @viberaven/cli@beta.');
|
|
73
|
-
process.exit(0);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
100
|
let buffer = Buffer.alloc(0);
|
|
77
101
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
});
|
|
102
|
+
function main() {
|
|
103
|
+
if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
104
|
+
console.log(`${SERVER_INFO.name} ${SERVER_INFO.version}`);
|
|
105
|
+
console.log(`MCP stdio server wrapping npx -y ${CLI_PACKAGE}.`);
|
|
106
|
+
process.exit(0);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
process.stdin.on('data', (chunk) => {
|
|
110
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
111
|
+
drainMessages();
|
|
112
|
+
});
|
|
113
|
+
}
|
|
82
114
|
|
|
83
115
|
function drainMessages() {
|
|
84
116
|
while (true) {
|
|
@@ -146,41 +178,125 @@ async function handleRequest(method, params) {
|
|
|
146
178
|
const name = params.name;
|
|
147
179
|
const args = params.arguments || {};
|
|
148
180
|
const text = await callTool(name, args);
|
|
149
|
-
|
|
181
|
+
const parsed = parseJsonObjectFromToolText(text);
|
|
182
|
+
return {
|
|
183
|
+
content: [{ type: 'text', text }],
|
|
184
|
+
...(parsed ? { structuredContent: parsed } : {})
|
|
185
|
+
};
|
|
150
186
|
}
|
|
151
187
|
|
|
152
188
|
throw new Error(`Unsupported MCP method: ${method}`);
|
|
153
189
|
}
|
|
154
190
|
|
|
155
191
|
async function callTool(name, args) {
|
|
156
|
-
|
|
157
|
-
|
|
192
|
+
return runVibeRaven(['-y', CLI_PACKAGE, ...buildToolArgs(name, args || {})], args && args.cwd);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function buildToolArgs(name, args) {
|
|
196
|
+
if (name === 'viberaven_check_readiness') {
|
|
197
|
+
return ['--agent-mode'];
|
|
198
|
+
}
|
|
199
|
+
if (name === 'viberaven_verify') {
|
|
200
|
+
return ['--verify'];
|
|
201
|
+
}
|
|
202
|
+
if (name === 'viberaven_audit') {
|
|
203
|
+
return ['audit', '--vercel-supabase', ...(args.json ? ['--json'] : [])];
|
|
204
|
+
}
|
|
205
|
+
if (name === 'viberaven_init_rules') {
|
|
206
|
+
const cliArgs = ['init'];
|
|
207
|
+
if (args.agents) cliArgs.push('--agents', safeStringArg(args.agents, 'agents'));
|
|
208
|
+
if (args.dryRun) cliArgs.push('--dry-run');
|
|
209
|
+
return cliArgs;
|
|
210
|
+
}
|
|
211
|
+
if (name === 'viberaven_clean_plan') {
|
|
212
|
+
return ['clean', '--plan'];
|
|
158
213
|
}
|
|
159
|
-
if (name === '
|
|
160
|
-
return
|
|
214
|
+
if (name === 'viberaven_strict_gate') {
|
|
215
|
+
return ['--agent-mode', '--strict', '--json'];
|
|
161
216
|
}
|
|
162
|
-
if (name === '
|
|
163
|
-
return
|
|
217
|
+
if (name === 'viberaven_gate_result') {
|
|
218
|
+
return ['--agent-mode', '--json'];
|
|
164
219
|
}
|
|
165
|
-
if (name === '
|
|
166
|
-
|
|
167
|
-
if (args.gap) cliArgs.push('--gap', String(args.gap));
|
|
168
|
-
if (args.area) cliArgs.push('--area', String(args.area));
|
|
169
|
-
if (args.provider) cliArgs.push('--provider', String(args.provider));
|
|
170
|
-
return runVibeRaven(cliArgs, args.cwd);
|
|
220
|
+
if (name === 'viberaven_context_map') {
|
|
221
|
+
return ['--condense'];
|
|
171
222
|
}
|
|
172
|
-
if (name === '
|
|
173
|
-
return
|
|
223
|
+
if (name === 'viberaven_heal_plan') {
|
|
224
|
+
return buildHealArgs(['--heal', '--plan'], args);
|
|
225
|
+
}
|
|
226
|
+
if (name === 'viberaven_heal_prompt') {
|
|
227
|
+
return buildHealArgs(['--heal', '--prompt'], args);
|
|
228
|
+
}
|
|
229
|
+
if (name === 'viberaven_heal_apply') {
|
|
230
|
+
const cliArgs = buildHealArgs(['--heal', '--apply'], args);
|
|
231
|
+
if (args.yes === true) cliArgs.push('--yes');
|
|
232
|
+
return cliArgs;
|
|
174
233
|
}
|
|
175
234
|
throw new Error(`Unknown VibeRaven tool: ${name}`);
|
|
176
235
|
}
|
|
177
236
|
|
|
237
|
+
function buildHealArgs(prefix, args) {
|
|
238
|
+
const cliArgs = [...prefix];
|
|
239
|
+
if (args.target) cliArgs.push('--target', safeStringArg(args.target, 'target'));
|
|
240
|
+
if (args.gap) cliArgs.push('--gap', safeStringArg(args.gap, 'gap'));
|
|
241
|
+
return cliArgs;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function safeStringArg(value, label) {
|
|
245
|
+
if (typeof value !== 'string') {
|
|
246
|
+
throw new Error(`Invalid ${label}: expected string`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (!value.trim()) {
|
|
250
|
+
throw new Error(`Invalid ${label}: expected non-empty string`);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (/[&|<>^%!"\r\n]/.test(value)) {
|
|
254
|
+
throw new Error(`Unsafe characters in ${label}`);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return value;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
function resolveCwd(cwd) {
|
|
261
|
+
if (cwd === undefined || cwd === null) {
|
|
262
|
+
return process.cwd();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (typeof cwd !== 'string') {
|
|
266
|
+
throw new Error('Invalid cwd: expected string');
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (!cwd.trim()) {
|
|
270
|
+
throw new Error('Invalid cwd: expected non-empty string');
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return cwd;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function buildNpxCommand(args) {
|
|
277
|
+
if (process.platform === 'win32') {
|
|
278
|
+
return {
|
|
279
|
+
command: 'cmd.exe',
|
|
280
|
+
args: ['/d', '/s', '/c', 'npx', ...args],
|
|
281
|
+
options: { shell: false }
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
return {
|
|
286
|
+
command: 'npx',
|
|
287
|
+
args,
|
|
288
|
+
options: { shell: false }
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
178
292
|
function runVibeRaven(args, cwd) {
|
|
179
293
|
return new Promise((resolve) => {
|
|
180
|
-
const
|
|
181
|
-
|
|
294
|
+
const built = buildNpxCommand(args);
|
|
295
|
+
const child = spawnChild(built.command, built.args, {
|
|
296
|
+
cwd: resolveCwd(cwd),
|
|
182
297
|
env: process.env,
|
|
183
|
-
shell:
|
|
298
|
+
shell: built.options.shell,
|
|
299
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
184
300
|
});
|
|
185
301
|
let stdout = '';
|
|
186
302
|
let stderr = '';
|
|
@@ -195,12 +311,41 @@ function runVibeRaven(args, cwd) {
|
|
|
195
311
|
});
|
|
196
312
|
child.on('close', (code) => {
|
|
197
313
|
const combined = `${stdout}${stderr}`.trim();
|
|
198
|
-
resolve(`exit ${code ?? 1}
|
|
314
|
+
resolve(`exit ${code ?? 1}${combined ? `\n${combined}` : ''}`);
|
|
199
315
|
});
|
|
200
316
|
});
|
|
201
317
|
}
|
|
202
318
|
|
|
319
|
+
function parseJsonObjectFromToolText(text) {
|
|
320
|
+
const jsonStart = text.indexOf('{');
|
|
321
|
+
if (jsonStart === -1) return undefined;
|
|
322
|
+
try {
|
|
323
|
+
return JSON.parse(text.slice(jsonStart));
|
|
324
|
+
} catch {
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
203
329
|
function send(message) {
|
|
204
330
|
const body = JSON.stringify(message);
|
|
205
331
|
process.stdout.write(`Content-Length: ${Buffer.byteLength(body, 'utf8')}\r\n\r\n${body}`);
|
|
206
332
|
}
|
|
333
|
+
|
|
334
|
+
if (require.main === module) {
|
|
335
|
+
main();
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
module.exports = {
|
|
339
|
+
TOOLS,
|
|
340
|
+
buildNpxCommand,
|
|
341
|
+
callTool,
|
|
342
|
+
handleRequest,
|
|
343
|
+
parseJsonObjectFromToolText,
|
|
344
|
+
safeStringArg,
|
|
345
|
+
__setSpawnForTest(spawnForTest) {
|
|
346
|
+
spawnChild = spawnForTest;
|
|
347
|
+
},
|
|
348
|
+
__resetSpawnForTest() {
|
|
349
|
+
spawnChild = spawn;
|
|
350
|
+
}
|
|
351
|
+
};
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viberaven/mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Thin MCP wrapper around the VibeRaven CLI for agent launch-readiness workflows.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"author": "VibeRaven",
|
|
7
|
+
"mcpName": "io.github.ohad6k/viberaven",
|
|
7
8
|
"homepage": "https://viberaven.dev/mcp.md",
|
|
8
9
|
"repository": {
|
|
9
10
|
"type": "git",
|
|
@@ -24,7 +25,7 @@
|
|
|
24
25
|
],
|
|
25
26
|
"publishConfig": {
|
|
26
27
|
"access": "public",
|
|
27
|
-
"tag": "
|
|
28
|
+
"tag": "latest"
|
|
28
29
|
},
|
|
29
30
|
"bin": {
|
|
30
31
|
"viberaven-mcp": "bin/server.js"
|
|
@@ -37,6 +38,7 @@
|
|
|
37
38
|
"node": ">=20"
|
|
38
39
|
},
|
|
39
40
|
"scripts": {
|
|
40
|
-
"smoke": "node scripts/smoke.mjs"
|
|
41
|
+
"smoke": "node scripts/smoke.mjs",
|
|
42
|
+
"test": "vitest run"
|
|
41
43
|
}
|
|
42
44
|
}
|