vibecheck-mcp-server 3.2.0 → 3.2.6

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/index.js +85 -0
  2. package/package.json +1 -1
  3. package/tier-auth.js +108 -103
package/index.js CHANGED
@@ -33,6 +33,15 @@ import { fileURLToPath } from "url";
33
33
  import { execFile } from "child_process";
34
34
  import { promisify } from "util";
35
35
 
36
+ // Import API client for dashboard integration
37
+ const {
38
+ createScan,
39
+ updateScanProgress,
40
+ submitScanResults,
41
+ reportScanError,
42
+ isApiAvailable
43
+ } = require("./lib/api-client");
44
+
36
45
  const execFileAsync = promisify(execFile);
37
46
 
38
47
  const __filename = fileURLToPath(import.meta.url);
@@ -1360,6 +1369,27 @@ class VibecheckMCP {
1360
1369
  const profile = args?.profile || "quick";
1361
1370
  const only = args?.only;
1362
1371
 
1372
+ // Initialize API integration
1373
+ let apiScan = null;
1374
+ let apiConnected = false;
1375
+
1376
+ // Try to connect to API for dashboard integration
1377
+ try {
1378
+ apiConnected = await isApiAvailable();
1379
+ if (apiConnected) {
1380
+ // Create scan record in dashboard
1381
+ apiScan = await createScan({
1382
+ localPath: projectPath,
1383
+ branch: 'main',
1384
+ enableLLM: false,
1385
+ });
1386
+ console.error(`[MCP] Connected to dashboard (Scan ID: ${apiScan.scanId})`);
1387
+ }
1388
+ } catch (err) {
1389
+ // API connection is optional, continue without it
1390
+ console.error(`[MCP] Dashboard integration unavailable: ${err.message}`);
1391
+ }
1392
+
1363
1393
  let output = "# šŸ” vibecheck Scan\n\n";
1364
1394
  output += `**Profile:** ${profile}\n`;
1365
1395
  output += `**Path:** ${projectPath}\n\n`;
@@ -1375,6 +1405,28 @@ class VibecheckMCP {
1375
1405
  const summary = await this.parseSummaryFromDisk(projectPath);
1376
1406
  if (summary) {
1377
1407
  output += this.formatScanOutput(summary, projectPath);
1408
+
1409
+ // Submit results to dashboard if connected
1410
+ if (apiConnected && apiScan) {
1411
+ try {
1412
+ await submitScanResults(apiScan.scanId, {
1413
+ verdict: summary.verdict || 'UNKNOWN',
1414
+ score: summary.score?.overall || 0,
1415
+ findings: summary.findings || [],
1416
+ filesScanned: summary.stats?.filesScanned || 0,
1417
+ linesScanned: summary.stats?.linesScanned || 0,
1418
+ durationMs: summary.timings?.total || 0,
1419
+ metadata: {
1420
+ profile,
1421
+ source: 'mcp-server',
1422
+ version: CONFIG.VERSION,
1423
+ },
1424
+ });
1425
+ console.error(`[MCP] Results sent to dashboard`);
1426
+ } catch (err) {
1427
+ console.error(`[MCP] Failed to send results to dashboard: ${err.message}`);
1428
+ }
1429
+ }
1378
1430
  }
1379
1431
  output += "\n---\n_Context Enhanced by vibecheck AI_\n";
1380
1432
  return this.success(output);
@@ -1383,10 +1435,43 @@ class VibecheckMCP {
1383
1435
  const summary = await this.parseSummaryFromDisk(projectPath);
1384
1436
  if (summary) {
1385
1437
  output += this.formatScanOutput(summary, projectPath);
1438
+
1439
+ // Submit results to dashboard if connected
1440
+ if (apiConnected && apiScan) {
1441
+ try {
1442
+ await submitScanResults(apiScan.scanId, {
1443
+ verdict: summary.verdict || 'UNKNOWN',
1444
+ score: summary.score?.overall || 0,
1445
+ findings: summary.findings || [],
1446
+ filesScanned: summary.stats?.filesScanned || 0,
1447
+ linesScanned: summary.stats?.linesScanned || 0,
1448
+ durationMs: summary.timings?.total || 0,
1449
+ metadata: {
1450
+ profile,
1451
+ source: 'mcp-server',
1452
+ version: CONFIG.VERSION,
1453
+ error: err.message,
1454
+ },
1455
+ });
1456
+ console.error(`[MCP] Results sent to dashboard (with error)`);
1457
+ } catch (err) {
1458
+ console.error(`[MCP] Failed to send results to dashboard: ${err.message}`);
1459
+ }
1460
+ }
1386
1461
  output += `\nāš ļø Scan completed with findings (exit code ${err.code || 1})\n`;
1387
1462
  return this.success(output);
1388
1463
  }
1389
1464
 
1465
+ // Report error to dashboard if connected
1466
+ if (apiConnected && apiScan) {
1467
+ try {
1468
+ await reportScanError(apiScan.scanId, err);
1469
+ console.error(`[MCP] Error reported to dashboard`);
1470
+ } catch (err) {
1471
+ console.error(`[MCP] Failed to report error to dashboard: ${err.message}`);
1472
+ }
1473
+ }
1474
+
1390
1475
  return this.error(`Scan failed: ${err.message}`, {
1391
1476
  code: "SCAN_ERROR",
1392
1477
  suggestion: "Check that the project path is valid and contains scanable code",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vibecheck-mcp-server",
3
- "version": "3.2.0",
3
+ "version": "3.2.6",
4
4
  "description": "Professional MCP server for vibecheck - Intelligent development environment vibechecks",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/tier-auth.js CHANGED
@@ -1,157 +1,162 @@
1
1
  /**
2
2
  * MCP Server Tier Authentication & Authorization
3
3
  *
4
- * Provides tier checking for MCP tools based on API keys
4
+ * UNIFIED AUTHORITY SYSTEM for MCP tools.
5
+ *
6
+ * Authority Rules:
7
+ * - FREE: May see problems, never resolve certainty. Read-only context tools.
8
+ * - STARTER: May fix, but not prove. Read tools + advisory actions.
9
+ * - PRO: May enforce reality. Full MCP access with proof generation.
10
+ * - ENTERPRISE: All features + compliance tools.
11
+ *
12
+ * Verdict authority is paid. Evidence beats explanations.
5
13
  */
6
14
 
7
15
  import fs from "fs/promises";
8
16
  import path from "path";
9
17
  import os from "os";
10
18
 
11
- // Tier definitions - MUST MATCH CLI entitlements-v2.js
19
+ // ═══════════════════════════════════════════════════════════════════════════════
20
+ // TIER DEFINITIONS - UNIFIED AUTHORITY SYSTEM
21
+ // Synchronized with packages/core/src/tier-config.ts
22
+ //
23
+ // Authority Rules:
24
+ // - FREE: May see problems, never resolve certainty
25
+ // - STARTER: May fix, but not prove (Advisory verdicts only)
26
+ // - PRO: May enforce reality (Full verdict authority)
27
+ // ═══════════════════════════════════════════════════════════════════════════════
12
28
  export const TIERS = {
13
29
  free: {
14
30
  name: 'FREE',
15
31
  price: 0,
16
32
  order: 0,
17
- features: [
18
- // Core commands
19
- 'scan', 'ship', 'ship.static',
20
- // Setup
21
- 'init', 'init.local', 'doctor', 'status', 'install', 'preflight', 'watch', 'watch.local',
22
- // AI Truth
23
- 'ctx', 'guard', 'context', 'mdc', 'contracts',
24
- // Quality
25
- 'verify', 'quality', 'polish', 'checkpoint', 'checkpoint.basic',
26
- // Fix (plan only)
27
- 'fix', 'fix.plan_only',
28
- // Reality (preview)
29
- 'reality', 'reality.preview',
30
- // MCP (help only)
31
- 'mcp.help_only',
32
- // Report (html/md only)
33
- 'report', 'report.html_md',
34
- ],
33
+ // Verdict authority
34
+ verdictAuthority: 'NONE',
35
+ canIssueVerdicts: false,
36
+ canEnforceCI: false,
37
+ canGenerateProof: false,
38
+ // Limits
35
39
  limits: {
36
- scans: 50,
37
- shipChecks: 20,
40
+ scans: -1, // Unlimited scans
38
41
  realityMaxPages: 5,
39
42
  realityMaxClicks: 20,
40
- fixApplyPatches: false,
41
- mcpRateLimit: 10, // requests per minute
43
+ mcpRateLimit: 10,
42
44
  },
43
- // MCP tools allowed on FREE
45
+ // MCP tools allowed on FREE (read-only context only)
44
46
  mcpTools: [
45
47
  'vibecheck.get_truthpack',
46
- 'vibecheck.validate_claim',
47
48
  'vibecheck.compile_context',
48
49
  'vibecheck.search_evidence',
49
50
  ],
50
51
  },
51
52
  starter: {
52
53
  name: 'STARTER',
53
- price: 39, // Updated pricing
54
+ price: 39,
54
55
  order: 1,
55
- features: [
56
- // All FREE features plus...
57
- // Init connect
58
- 'init.connect',
59
- // Scan autofix
60
- 'scan.autofix',
61
- // CI/CD
62
- 'gate', 'pr', 'badge', 'launch', 'dashboard_sync',
63
- // Watch PR
64
- 'watch.pr',
65
- // Report formats
66
- 'report.sarif_csv',
67
- // Reality basic
68
- 'reality.basic',
69
- // MCP read-only
70
- 'mcp', 'mcp.read_only',
71
- // Ship full
72
- 'ship.full',
73
- ],
56
+ // Verdict authority - ADVISORY (verdicts not enforced)
57
+ verdictAuthority: 'ADVISORY',
58
+ canIssueVerdicts: true, // SHIP, WARN only
59
+ canEnforceCI: false, // Cannot block builds
60
+ canGenerateProof: false, // Cannot generate proof
61
+ // Limits
74
62
  limits: {
75
- scans: -1,
76
- shipChecks: -1,
77
- realityMaxPages: 50,
78
- realityMaxClicks: 200,
79
- fixApplyPatches: false,
80
- mcpRateLimit: 60, // requests per minute
63
+ scans: -1, // Unlimited scans
64
+ realityMaxPages: -1, // Unlimited browser testing
65
+ realityMaxClicks: -1,
66
+ mcpRateLimit: 60,
81
67
  },
82
- // MCP tools allowed on STARTER (curated)
68
+ // MCP tools allowed on STARTER (read + advisory actions)
83
69
  mcpTools: [
84
70
  'vibecheck.ctx',
85
71
  'vibecheck.scan',
86
- 'vibecheck.ship',
72
+ 'vibecheck.ship', // Advisory verdicts only
87
73
  'vibecheck.get_truthpack',
88
74
  'vibecheck.validate_claim',
89
75
  'vibecheck.compile_context',
90
76
  'vibecheck.search_evidence',
91
77
  'vibecheck.find_counterexamples',
92
78
  'vibecheck.check_invariants',
79
+ 'vibecheck.fix', // Plan mode only
93
80
  ],
94
81
  },
95
82
  pro: {
96
83
  name: 'PRO',
97
84
  price: 99,
98
85
  order: 2,
99
- features: [
100
- // All STARTER features plus...
101
- // Prove
102
- 'prove',
103
- // Fix apply
104
- 'fix.apply_patches', 'fix.loop',
105
- // Checkpoint advanced
106
- 'checkpoint.hallucination',
107
- // Reality advanced
108
- 'reality.full', 'reality.advanced_auth_boundary',
109
- // Premium
110
- 'replay', 'share', 'ai-test', 'permissions', 'graph',
111
- // MCP full
112
- 'mcp.full',
113
- ],
86
+ // Verdict authority - ENFORCED (verdicts block CI/PRs)
87
+ verdictAuthority: 'ENFORCED',
88
+ canIssueVerdicts: true, // SHIP, WARN, BLOCK
89
+ canEnforceCI: true, // Can block builds
90
+ canGenerateProof: true, // Can generate cryptographic proof
91
+ // Limits
114
92
  limits: {
115
- scans: -1,
116
- shipChecks: -1,
117
- realityMaxPages: -1,
118
- realityMaxClicks: -1,
119
- fixApplyPatches: true,
120
- mcpRateLimit: -1, // unlimited
93
+ scans: -1,
94
+ realityMaxPages: -1,
95
+ realityMaxClicks: -1,
96
+ mcpRateLimit: -1, // Unlimited
121
97
  },
122
- // MCP tools allowed on PRO (curated)
123
- mcpTools: [
124
- 'vibecheck.ctx',
125
- 'vibecheck.scan',
126
- 'vibecheck.ship',
127
- 'vibecheck.get_truthpack',
128
- 'vibecheck.validate_claim',
129
- 'vibecheck.compile_context',
130
- 'vibecheck.search_evidence',
131
- 'vibecheck.find_counterexamples',
132
- 'vibecheck.check_invariants',
133
- ],
98
+ // MCP tools - FULL ACCESS
99
+ mcpTools: ['*'], // All tools unlocked
134
100
  },
135
- compliance: {
136
- name: 'COMPLIANCE',
137
- price: 0, // Enterprise/on-prem
101
+ enterprise: {
102
+ name: 'ENTERPRISE',
103
+ price: 0, // Custom pricing
138
104
  order: 3,
139
- features: [
140
- // All PRO features plus...
141
- 'report.compliance_packs',
142
- ],
105
+ // Verdict authority - ENFORCED + Compliance
106
+ verdictAuthority: 'ENFORCED',
107
+ canIssueVerdicts: true,
108
+ canEnforceCI: true,
109
+ canGenerateProof: true,
110
+ // Limits
143
111
  limits: {
144
- scans: -1,
145
- shipChecks: -1,
146
- realityMaxPages: -1,
147
- realityMaxClicks: -1,
148
- fixApplyPatches: true,
112
+ scans: -1,
113
+ realityMaxPages: -1,
114
+ realityMaxClicks: -1,
149
115
  mcpRateLimit: -1,
150
116
  },
151
- mcpTools: ['*'], // All tools
117
+ // MCP tools - FULL ACCESS + Compliance
118
+ mcpTools: ['*'],
152
119
  }
153
120
  };
154
121
 
122
+ // ═══════════════════════════════════════════════════════════════════════════════
123
+ // MCP TOOL → TIER MAPPING (Unified Authority System)
124
+ // Aligned with packages/core/src/features.ts
125
+ // ═══════════════════════════════════════════════════════════════════════════════
126
+ export const MCP_TOOL_TIERS = {
127
+ // FREE - Read-only context tools ONLY
128
+ // Free users may see problems, never resolve certainty
129
+ 'vibecheck.get_truthpack': 'free',
130
+ 'vibecheck.compile_context': 'free',
131
+ 'vibecheck.search_evidence': 'free',
132
+
133
+ // STARTER - Advisory verdict authority
134
+ // Starter users may fix, but not prove
135
+ 'vibecheck.ctx': 'starter',
136
+ 'vibecheck.scan': 'starter',
137
+ 'vibecheck.ship': 'starter', // SHIP/WARN (advisory, not enforced)
138
+ 'vibecheck.fix': 'starter', // Plan mode only (no apply)
139
+ 'vibecheck.validate_claim': 'starter',
140
+ 'vibecheck.find_counterexamples': 'starter',
141
+ 'vibecheck.check_invariants': 'starter',
142
+ 'vibecheck.gate': 'starter', // Advisory gates
143
+ 'vibecheck.badge': 'starter', // Unverified badges
144
+
145
+ // PRO - Full verdict authority & enforcement
146
+ // Pro users may enforce reality
147
+ 'vibecheck.prove': 'pro', // Cryptographic proof generation
148
+ 'vibecheck.fix.apply': 'pro', // Apply fixes
149
+ 'vibecheck.fix.verify': 'pro', // Verify fixes with proof
150
+ 'vibecheck.reality': 'pro', // Full browser testing
151
+ 'vibecheck.reality.prove': 'pro', // Prove runtime behavior
152
+ 'vibecheck.enforce': 'pro', // Enforce verdicts in CI
153
+ 'vibecheck.ai_test': 'pro', // AI agent testing
154
+ 'vibecheck.autopilot': 'pro', // Autonomous protection
155
+ 'vibecheck.report': 'pro', // Advanced reporting
156
+ 'vibecheck.allowlist': 'pro', // Manage allowlists
157
+ 'vibecheck.status': 'pro', // Advanced status
158
+ };
159
+
155
160
  /**
156
161
  * Load user configuration from ~/.vibecheck/credentials.json
157
162
  */
@@ -175,7 +180,7 @@ async function getTierFromApiKey(apiKey) {
175
180
  // Check API key prefix patterns (matches CLI)
176
181
  if (apiKey.startsWith('gr_starter_')) return 'starter';
177
182
  if (apiKey.startsWith('gr_pro_')) return 'pro';
178
- if (apiKey.startsWith('gr_compliance_') || apiKey.startsWith('gr_ent_')) return 'compliance';
183
+ if (apiKey.startsWith('gr_enterprise_') || apiKey.startsWith('gr_ent_')) return 'enterprise';
179
184
  if (apiKey.startsWith('gr_free_')) return 'free';
180
185
 
181
186
  // Try to validate with API
@@ -199,8 +204,8 @@ async function getTierFromApiKey(apiKey) {
199
204
  return 'starter';
200
205
  case 'pro':
201
206
  return 'pro';
202
- case 'compliance':
203
- return 'compliance';
207
+ case 'enterprise':
208
+ return 'enterprise';
204
209
  default:
205
210
  return 'free';
206
211
  }