@viberaven/mcp 1.0.7 → 1.1.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 (3) hide show
  1. package/README.md +63 -40
  2. package/bin/server.js +297 -74
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -10,57 +10,80 @@ This package exposes VibeRaven CLI actions as MCP tools for Codex, Claude Code,
10
10
 
11
11
  The MCP server wraps the stable CLI package: `npx -y viberaven`.
12
12
 
13
- ## Run
14
-
15
- ```bash
16
- npx -y @viberaven/mcp
17
- ```
13
+ ## Run
14
+
15
+ ```bash
16
+ npx -y @viberaven/mcp
17
+ ```
18
+
19
+ MCP config:
20
+
21
+ ```json
22
+ { "viberaven": { "command": "npx", "args": ["-y", "@viberaven/mcp"] } }
23
+ ```
24
+
25
+ ## Tools
26
+
27
+ - `viberaven_check_readiness` -> `npx -y viberaven --agent-mode`
28
+ - `viberaven_verify` -> `npx -y viberaven --verify`
29
+ - `viberaven_audit` -> `npx -y viberaven audit --vercel-supabase`
30
+ - `viberaven_init_rules` -> `npx -y viberaven init`
31
+ - `viberaven_clean_plan` -> `npx -y viberaven clean --plan`
32
+ - `viberaven_strict_gate` -> `npx -y viberaven --agent-mode --strict --json`
33
+ - `viberaven_gate_result` -> `npx -y viberaven --agent-mode --json`
34
+ - `viberaven_context_map` -> `npx -y viberaven --condense`
35
+ - `viberaven_prp_current` -> read `.viberaven/prp.json`
36
+ - `viberaven_prp_findings` -> list PRP findings
37
+ - `viberaven_prp_next_action` -> return the first PRP next action
38
+ - `viberaven_verify_url` -> URL-specific verification fallback; currently unsupported and not live URL proof
39
+ - `viberaven_mark_manual_evidence` -> append manual PRP evidence; manual evidence is not live provider proof
40
+ - `viberaven_heal_plan` -> `npx -y viberaven --heal --plan`
41
+ - `viberaven_heal_prompt` -> `npx -y viberaven --heal --prompt`
42
+ - `viberaven_heal_apply` -> `npx -y viberaven --heal --apply`
43
+ - `viberaven_validate_npm_package` -> check npm package names before install
44
+
45
+ `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`.
18
46
 
19
- You can also start the MCP server from the main CLI package:
47
+ After one fix, call `viberaven_verify`. Before deploy or CI pass, call `viberaven_strict_gate` or run:
20
48
 
21
49
  ```bash
22
- npx -y viberaven mcp
23
- ```
24
-
25
- ## Tools
26
-
27
- - `viberaven_check_readiness` -> `npx -y viberaven --agent-mode`
28
- - `viberaven_verify` -> `npx -y viberaven --verify`
29
- - `viberaven_audit` -> `npx -y viberaven audit --vercel-supabase`
30
- - `viberaven_init_rules` -> `npx -y viberaven init`
31
- - `viberaven_clean_plan` -> `npx -y viberaven clean --plan`
32
- - `viberaven_strict_gate` -> `npx -y viberaven --agent-mode --strict --json`
33
- - `viberaven_gate_result` -> `npx -y viberaven --agent-mode --json`
34
- - `viberaven_context_map` -> `npx -y viberaven --condense`
35
- - `viberaven_heal_plan` -> `npx -y viberaven --heal --plan`
36
- - `viberaven_heal_prompt` -> `npx -y viberaven --heal --prompt`
37
- - `viberaven_heal_apply` -> `npx -y viberaven --heal --apply`
38
-
39
- `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`, `.viberaven/context-map.json`, and Launch Autopilot artifacts.
50
+ npx -y viberaven --strict
51
+ ```
52
+
53
+ ## VibeRaven Production Protocol
54
+
55
+ VibeRaven 1.1.0 introduces the Production Protocol for AI-built apps.
40
56
 
41
- Launch Autopilot keeps the canonical agent command:
57
+ Run the canonical agent command:
42
58
 
43
59
  ```bash
44
60
  npx -y viberaven --agent-mode
45
61
  ```
46
62
 
47
- MCP clients may pass `launchMode` to `viberaven_check_readiness`:
63
+ Then have the AI coding agent read:
48
64
 
49
- - `manual`: show links and commands only
50
- - `ask`: default, ask before provider actions
51
- - `safe`: read-only provider checks and safe repo fixes
52
- - `full`: approved session mode; production deploy still needs final confirmation
65
+ - `.viberaven/prp.json`
66
+ - `.viberaven/mission-map.md`
67
+ - `.viberaven/context-map.json`
53
68
 
54
- After one fix, call `viberaven_verify`. Before deploy or CI pass, call `viberaven_strict_gate` or run:
55
-
56
- ```bash
57
- npx -y viberaven --strict
58
- ```
59
-
60
- ## Machine Artifact Contract
61
-
62
- ```text
63
- docs/contracts/artifacts.md
69
+ The agent should fix `nextActions` in order and must not claim production-ready while `decision.status` is `blocked`.
70
+
71
+ ## Production Protocol Resources
72
+
73
+ The MCP server exposes VibeRaven Production Protocol artifacts directly:
74
+
75
+ - `prp://current`
76
+ - `prp://findings`
77
+ - `prp://next-actions`
78
+ - `prp://mission-map`
79
+ - `prp://context-map`
80
+
81
+ Use `viberaven_check_readiness` to generate the artifacts, then use `viberaven_prp_current`, `viberaven_prp_findings`, or `viberaven_prp_next_action` so agents can act without scraping terminal prose.
82
+
83
+ ## Machine Artifact Contract
84
+
85
+ ```text
86
+ docs/contracts/artifacts.md
64
87
  https://viberaven.dev/schemas/gate-result.schema.json
65
88
  https://viberaven.dev/schemas/context-map.schema.json
66
89
  https://viberaven.dev/schemas/gap.schema.json
package/bin/server.js CHANGED
@@ -1,24 +1,23 @@
1
- #!/usr/bin/env node
2
- const { spawn } = require('node:child_process');
3
- let spawnChild = spawn;
4
-
5
- const SERVER_INFO = { name: 'viberaven-mcp', version: '1.0.7' };
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
- launchMode: {
13
- type: 'string',
14
- enum: ['manual', 'ask', 'safe', 'full'],
15
- description: 'Launch Autopilot permission mode. Defaults to ask.'
16
- }
17
- },
18
- additionalProperties: false
19
- };
1
+ #!/usr/bin/env node
2
+ const { spawn } = require('node:child_process');
3
+ const { readFile, writeFile } = require('node:fs/promises');
4
+ const { join } = require('node:path');
5
+ let spawnChild = spawn;
6
+
7
+ const SERVER_INFO = { name: 'viberaven-mcp', version: '1.1.0' };
8
+ const CLI_PACKAGE = '@viberaven/cli';
9
+ const PRP_MISSING_MESSAGE = '.viberaven/prp.json not found. Run npx -y viberaven --agent-mode first.';
10
+ const PRP_INVALID_JSON_MESSAGE = '.viberaven/prp.json is invalid JSON. Re-run npx -y viberaven --agent-mode.';
11
+
12
+ const cwdSchema = {
13
+ type: 'object',
14
+ properties: {
15
+ cwd: { type: 'string', description: 'Project root. Defaults to the MCP server working directory.' }
16
+ },
17
+ additionalProperties: false
18
+ };
20
19
 
21
- const healSchema = {
20
+ const healSchema = {
22
21
  type: 'object',
23
22
  properties: {
24
23
  cwd: { type: 'string' },
@@ -26,16 +25,55 @@ const healSchema = {
26
25
  gap: { type: 'string' },
27
26
  yes: { type: 'boolean' }
28
27
  },
29
- additionalProperties: false
30
- };
31
-
32
- const TOOLS = [
28
+ additionalProperties: false
29
+ };
30
+
31
+ const manualEvidenceSchema = {
32
+ type: 'object',
33
+ properties: {
34
+ cwd: { type: 'string' },
35
+ id: { type: 'string' },
36
+ summary: { type: 'string' },
37
+ source: { type: 'string' }
38
+ },
39
+ required: ['id', 'summary'],
40
+ additionalProperties: false
41
+ };
42
+
43
+ const RESOURCES = [
33
44
  {
34
- name: 'viberaven_check_readiness',
35
- description:
36
- 'Run VibeRaven agent-mode production-readiness and Launch Autopilot; writes .viberaven artifacts and one next launch action.',
37
- inputSchema: cwdSchema
45
+ uri: 'prp://current',
46
+ name: 'Current VibeRaven Production Protocol',
47
+ mimeType: 'application/json'
48
+ },
49
+ {
50
+ uri: 'prp://findings',
51
+ name: 'VibeRaven PRP Findings',
52
+ mimeType: 'application/json'
53
+ },
54
+ {
55
+ uri: 'prp://next-actions',
56
+ name: 'VibeRaven PRP Next Actions',
57
+ mimeType: 'application/json'
58
+ },
59
+ {
60
+ uri: 'prp://mission-map',
61
+ name: 'VibeRaven Mission Map',
62
+ mimeType: 'text/markdown'
38
63
  },
64
+ {
65
+ uri: 'prp://context-map',
66
+ name: 'VibeRaven Context Map',
67
+ mimeType: 'application/json'
68
+ }
69
+ ];
70
+
71
+ const TOOLS = [
72
+ {
73
+ name: 'viberaven_check_readiness',
74
+ description: 'Run the VibeRaven agent-mode production-readiness check and write .viberaven artifacts.',
75
+ inputSchema: cwdSchema
76
+ },
39
77
  {
40
78
  name: 'viberaven_verify',
41
79
  description: 'Rescan and refresh VibeRaven production-readiness artifacts after a fix.',
@@ -81,14 +119,47 @@ const TOOLS = [
81
119
  description: 'Run VibeRaven agent-mode JSON output and return gate-result.json content.',
82
120
  inputSchema: cwdSchema
83
121
  },
84
- {
85
- name: 'viberaven_context_map',
86
- description: 'Refresh .viberaven/context-map.json from the last scan.',
87
- inputSchema: cwdSchema
88
- },
89
- {
90
- name: 'viberaven_heal_plan',
91
- description: 'Write a non-destructive VibeRaven heal plan for a target file or gap.',
122
+ {
123
+ name: 'viberaven_context_map',
124
+ description: 'Refresh .viberaven/context-map.json from the last scan.',
125
+ inputSchema: cwdSchema
126
+ },
127
+ {
128
+ name: 'viberaven_prp_current',
129
+ description: 'Read .viberaven/prp.json, the VibeRaven Production Protocol truth object.',
130
+ inputSchema: cwdSchema
131
+ },
132
+ {
133
+ name: 'viberaven_prp_findings',
134
+ description: 'List PRP findings from .viberaven/prp.json.',
135
+ inputSchema: cwdSchema
136
+ },
137
+ {
138
+ name: 'viberaven_prp_next_action',
139
+ description: 'Return the first PRP next action from .viberaven/prp.json.',
140
+ inputSchema: cwdSchema
141
+ },
142
+ {
143
+ name: 'viberaven_verify_url',
144
+ description:
145
+ 'Run VibeRaven verify for the current workspace. URL-specific verification is reported when supported by the CLI.',
146
+ inputSchema: {
147
+ type: 'object',
148
+ properties: {
149
+ cwd: { type: 'string' },
150
+ url: { type: 'string' }
151
+ },
152
+ additionalProperties: false
153
+ }
154
+ },
155
+ {
156
+ name: 'viberaven_mark_manual_evidence',
157
+ description: 'Append manual evidence to PRP. Manual evidence is not live provider proof.',
158
+ inputSchema: manualEvidenceSchema
159
+ },
160
+ {
161
+ name: 'viberaven_heal_plan',
162
+ description: 'Write a non-destructive VibeRaven heal plan for a target file or gap.',
92
163
  inputSchema: healSchema
93
164
  },
94
165
  {
@@ -187,17 +258,17 @@ async function handleRawMessage(raw) {
187
258
  async function handleRequest(method, params) {
188
259
  if (method === 'initialize') {
189
260
  return {
190
- protocolVersion: params.protocolVersion || '2024-11-05',
191
- capabilities: { tools: {} },
192
- serverInfo: SERVER_INFO
193
- };
194
- }
261
+ protocolVersion: params.protocolVersion || '2024-11-05',
262
+ capabilities: { tools: {}, resources: {} },
263
+ serverInfo: SERVER_INFO
264
+ };
265
+ }
195
266
 
196
267
  if (method === 'tools/list') {
197
268
  return { tools: TOOLS };
198
269
  }
199
270
 
200
- if (method === 'tools/call') {
271
+ if (method === 'tools/call') {
201
272
  const name = params.name;
202
273
  const args = params.arguments || {};
203
274
  const text = await callTool(name, args);
@@ -205,25 +276,62 @@ async function handleRequest(method, params) {
205
276
  return {
206
277
  content: [{ type: 'text', text }],
207
278
  ...(parsed ? { structuredContent: parsed } : {})
208
- };
209
- }
210
-
211
- throw new Error(`Unsupported MCP method: ${method}`);
212
- }
213
-
214
- async function callTool(name, args) {
215
- return runVibeRaven(['-y', CLI_PACKAGE, ...buildToolArgs(name, args || {})], args && args.cwd);
216
- }
217
-
218
- function buildToolArgs(name, args) {
219
- if (name === 'viberaven_check_readiness') {
220
- return ['--agent-mode', ...launchModeArgs(args)];
279
+ };
280
+ }
281
+
282
+ if (method === 'resources/list') {
283
+ return { resources: RESOURCES };
284
+ }
285
+
286
+ if (method === 'resources/read') {
287
+ const uri = params.uri;
288
+ const text = await readResourceText(uri, params.cwd);
289
+ return { contents: [{ uri, text }] };
290
+ }
291
+
292
+ throw new Error(`Unsupported MCP method: ${method}`);
293
+ }
294
+
295
+ async function callTool(name, args) {
296
+ if (name === 'viberaven_prp_current') {
297
+ return readPrpText(args && args.cwd);
298
+ }
299
+ if (name === 'viberaven_prp_findings') {
300
+ return readPrpFindingsText(args && args.cwd);
301
+ }
302
+ if (name === 'viberaven_prp_next_action') {
303
+ return readPrpNextActionText(args && args.cwd);
221
304
  }
222
- if (name === 'viberaven_verify') {
223
- return ['--verify'];
305
+ if (name === 'viberaven_verify_url' && Object.prototype.hasOwnProperty.call(args || {}, 'url')) {
306
+ return JSON.stringify(
307
+ {
308
+ ok: false,
309
+ unsupported: 'url-verification',
310
+ message: 'URL-specific verification is not supported yet; run viberaven_verify for workspace verification.',
311
+ fallbackTool: 'viberaven_verify'
312
+ },
313
+ null,
314
+ 2
315
+ );
316
+ }
317
+ if (name === 'viberaven_mark_manual_evidence') {
318
+ return markManualEvidence(args || {});
319
+ }
320
+ return runVibeRaven(['-y', CLI_PACKAGE, ...buildToolArgs(name, args || {})], args && args.cwd);
321
+ }
322
+
323
+ function buildToolArgs(name, args) {
324
+ if (name === 'viberaven_check_readiness') {
325
+ return ['--agent-mode'];
224
326
  }
225
- if (name === 'viberaven_audit') {
226
- return ['audit', '--vercel-supabase', ...(args.json ? ['--json'] : [])];
327
+ if (name === 'viberaven_verify') {
328
+ return ['--verify'];
329
+ }
330
+ if (name === 'viberaven_verify_url') {
331
+ return ['--verify'];
332
+ }
333
+ if (name === 'viberaven_audit') {
334
+ return ['audit', '--vercel-supabase', ...(args.json ? ['--json'] : [])];
227
335
  }
228
336
  if (name === 'viberaven_init_rules') {
229
337
  const cliArgs = ['init'];
@@ -270,16 +378,7 @@ function buildToolArgs(name, args) {
270
378
  return ['validate-npm-package', '--json', ...names];
271
379
  }
272
380
  throw new Error(`Unknown VibeRaven tool: ${name}`);
273
- }
274
-
275
- function launchModeArgs(args) {
276
- if (!args.launchMode) return [];
277
- const allowed = new Set(['manual', 'ask', 'safe', 'full']);
278
- if (!allowed.has(args.launchMode)) {
279
- throw new Error('Invalid launchMode');
280
- }
281
- return ['--launch-mode', args.launchMode];
282
- }
381
+ }
283
382
 
284
383
  function buildHealArgs(prefix, args) {
285
384
  const cliArgs = [...prefix];
@@ -304,7 +403,7 @@ function safeStringArg(value, label) {
304
403
  return value;
305
404
  }
306
405
 
307
- function resolveCwd(cwd) {
406
+ function resolveCwd(cwd) {
308
407
  if (cwd === undefined || cwd === null) {
309
408
  return process.cwd();
310
409
  }
@@ -317,10 +416,134 @@ function resolveCwd(cwd) {
317
416
  throw new Error('Invalid cwd: expected non-empty string');
318
417
  }
319
418
 
320
- return cwd;
321
- }
322
-
323
- function buildNpxCommand(args) {
419
+ return cwd;
420
+ }
421
+
422
+ function prpPath(cwd) {
423
+ return join(resolveCwd(cwd), '.viberaven', 'prp.json');
424
+ }
425
+
426
+ async function readPrpText(cwd) {
427
+ try {
428
+ return await readFile(prpPath(cwd), 'utf8');
429
+ } catch (error) {
430
+ if (error && error.code === 'ENOENT') {
431
+ return `ERROR: ${PRP_MISSING_MESSAGE}`;
432
+ }
433
+ throw error;
434
+ }
435
+ }
436
+
437
+ async function readExistingPrpJson(cwd) {
438
+ let text;
439
+ try {
440
+ text = await readFile(prpPath(cwd), 'utf8');
441
+ } catch (error) {
442
+ if (error && error.code === 'ENOENT') {
443
+ throw new Error(PRP_MISSING_MESSAGE);
444
+ }
445
+ throw error;
446
+ }
447
+
448
+ try {
449
+ return JSON.parse(text);
450
+ } catch {
451
+ throw new Error(PRP_INVALID_JSON_MESSAGE);
452
+ }
453
+ }
454
+
455
+ async function readPrpFindingsText(cwd) {
456
+ try {
457
+ const prp = await readExistingPrpJson(cwd);
458
+ return JSON.stringify({ findings: prp.findings || [] }, null, 2);
459
+ } catch (error) {
460
+ return JSON.stringify({ error: errorMessage(error), findings: [] }, null, 2);
461
+ }
462
+ }
463
+
464
+ async function readPrpNextActionText(cwd) {
465
+ try {
466
+ const prp = await readExistingPrpJson(cwd);
467
+ return JSON.stringify({ nextAction: (prp.nextActions || [])[0] || null }, null, 2);
468
+ } catch (error) {
469
+ return JSON.stringify({ error: errorMessage(error), nextAction: null }, null, 2);
470
+ }
471
+ }
472
+
473
+ async function readPrpNextActionsText(cwd) {
474
+ try {
475
+ const prp = await readExistingPrpJson(cwd);
476
+ return JSON.stringify({ nextActions: prp.nextActions || [] }, null, 2);
477
+ } catch (error) {
478
+ return JSON.stringify({ error: errorMessage(error), nextActions: [] }, null, 2);
479
+ }
480
+ }
481
+
482
+ async function markManualEvidence(args) {
483
+ if (typeof args.id !== 'string' || !args.id.trim()) {
484
+ throw new Error('Invalid id: expected non-empty string');
485
+ }
486
+ if (typeof args.summary !== 'string' || !args.summary.trim()) {
487
+ throw new Error('Invalid summary: expected non-empty string');
488
+ }
489
+
490
+ const prp = await readExistingPrpJson(args.cwd);
491
+ const evidence = Array.isArray(prp.evidence) ? prp.evidence : [];
492
+ evidence.push({
493
+ id: args.id,
494
+ kind: 'manual',
495
+ status: 'present',
496
+ source: typeof args.source === 'string' && args.source.trim() ? args.source : 'manual',
497
+ summary: `${args.summary} Manual confirmation is not live provider proof.`
498
+ });
499
+ prp.evidence = evidence;
500
+ await writeFile(prpPath(args.cwd), `${JSON.stringify(prp, null, 2)}\n`);
501
+ return JSON.stringify({ ok: true, evidenceId: args.id, kind: 'manual' }, null, 2);
502
+ }
503
+
504
+ async function readResourceText(uri, cwd) {
505
+ if (typeof uri !== 'string') {
506
+ throw new Error('Invalid resource uri: expected string');
507
+ }
508
+
509
+ if (uri === 'prp://current') {
510
+ return readPrpText(cwd);
511
+ }
512
+ if (uri === 'prp://findings') {
513
+ return readPrpFindingsText(cwd);
514
+ }
515
+ if (uri === 'prp://next-actions') {
516
+ return readPrpNextActionsText(cwd);
517
+ }
518
+ if (uri === 'prp://mission-map') {
519
+ try {
520
+ return await readFile(join(resolveCwd(cwd), '.viberaven', 'mission-map.md'), 'utf8');
521
+ } catch (error) {
522
+ if (error && error.code === 'ENOENT') {
523
+ return 'ERROR: .viberaven/mission-map.md not found. Run npx -y viberaven --agent-mode first.';
524
+ }
525
+ throw error;
526
+ }
527
+ }
528
+ if (uri === 'prp://context-map') {
529
+ try {
530
+ return await readFile(join(resolveCwd(cwd), '.viberaven', 'context-map.json'), 'utf8');
531
+ } catch (error) {
532
+ if (error && error.code === 'ENOENT') {
533
+ return 'ERROR: .viberaven/context-map.json not found. Run npx -y viberaven --agent-mode first.';
534
+ }
535
+ throw error;
536
+ }
537
+ }
538
+
539
+ throw new Error(`Unknown resource uri: ${uri}`);
540
+ }
541
+
542
+ function errorMessage(error) {
543
+ return error instanceof Error ? error.message : String(error);
544
+ }
545
+
546
+ function buildNpxCommand(args) {
324
547
  if (process.platform === 'win32') {
325
548
  return {
326
549
  command: 'cmd.exe',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viberaven/mcp",
3
- "version": "1.0.7",
3
+ "version": "1.1.0",
4
4
  "description": "MCP server for VibeRaven production-readiness: check_readiness, verify, heal, audit, and strict gate tools for Cursor, Claude Code, and Codex.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "VibeRaven",