@saiteja1123/mcp-server 1.1.6 → 1.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saiteja1123/mcp-server",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "description": "Vibesecur MCP security scanner — universal account config, multi-project CRU, folder locking, cross-IDE",
@@ -79,6 +79,24 @@ export function invalidateProjectsListCache() {
79
79
  projectsCache = { at: 0, projects: [] };
80
80
  }
81
81
 
82
+ export function invalidateBindingCache(projectRoot) {
83
+ if (projectRoot) {
84
+ bindingCache.delete(cacheKey(projectRoot));
85
+ return;
86
+ }
87
+ bindingCache.clear();
88
+ }
89
+
90
+ async function isBindingStillValid(entry, apiBase) {
91
+ if (!entry?.installToken || !entry?.lockedRootHash) return false;
92
+ const verify = await verifyInstallBinding({
93
+ installToken: entry.installToken,
94
+ lockedRootHash: entry.lockedRootHash,
95
+ apiBase,
96
+ });
97
+ return !!(verify.ok && verify.json?.success);
98
+ }
99
+
82
100
  async function writeServerLock(projectRoot, { installToken, lockedRootHash, account = 'server' }) {
83
101
  await createLock({
84
102
  rootPath: projectRoot,
@@ -167,7 +185,13 @@ export async function resolveBindingForScanPath({
167
185
  const root = path.resolve(entry.projectRoot);
168
186
  return target.startsWith(root + path.sep) || target === root;
169
187
  });
170
- if (cached) return { ok: true, ...cached, resolvedRoot: target };
188
+ if (cached) {
189
+ if (await isBindingStillValid(cached, apiBase)) {
190
+ return { ok: true, ...cached, resolvedRoot: target };
191
+ }
192
+ bindingCache.delete(cacheKey(cached.projectRoot));
193
+ invalidateProjectsListCache();
194
+ }
171
195
 
172
196
  let projects = [];
173
197
  try {
package/src/server.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  } from './repo-scan.mjs';
17
17
  import { diagnosticLock } from './lock.mjs';
18
18
  import { persistRepoScanLog } from './api-scan.mjs';
19
+ import { ensureProjectBinding } from './project-bindings.mjs';
19
20
  import { createBindingGuard, formatGuardError } from './security/pathGuard.js';
20
21
  import { registerLocalScanTool } from './tools/localScan.js';
21
22
  import { registerScanFileTool } from './tools/scanFile.js';
@@ -80,21 +81,41 @@ function humanRepoSummary(meta, agg) {
80
81
  }
81
82
 
82
83
  async function syncRepoScanToDashboard({ aggregate, findings, projectRoot, guard }) {
83
- const installToken = guard.installToken || INSTALL_TOKEN;
84
- const lockedRootHash = guard.lockedRootHash || guard.lock?.lockedRootHash || guard.lock?.rootHash;
84
+ let installToken = guard.installToken || INSTALL_TOKEN;
85
+ let lockedRootHash = guard.lockedRootHash || guard.lock?.lockedRootHash || guard.lock?.rootHash;
85
86
  if (!installToken || !lockedRootHash) {
86
87
  return { ok: false, reason: 'missing install token or locked root hash' };
87
88
  }
88
89
  try {
89
- const logRes = await persistRepoScanLog({
90
+ let logRes = await persistRepoScanLog({
90
91
  aggregate,
91
92
  findings,
92
93
  projectRoot,
93
94
  installToken,
94
95
  lockedRootHash,
95
96
  });
97
+ const revoked = logRes?.json?.code === 'MCP_INSTALL_LOCK_INVALID'
98
+ || /revoked or invalid/i.test(String(logRes?.json?.error || logRes?.reason || ''));
99
+ if (!logRes?.ok && revoked && AUTH_TOKEN && projectRoot) {
100
+ const rebound = await ensureProjectBinding({
101
+ lockedRootPath: projectRoot,
102
+ authToken: AUTH_TOKEN,
103
+ apiBase: API_BASE,
104
+ });
105
+ if (rebound.ok) {
106
+ installToken = rebound.installToken;
107
+ lockedRootHash = rebound.lockedRootHash;
108
+ logRes = await persistRepoScanLog({
109
+ aggregate,
110
+ findings,
111
+ projectRoot,
112
+ installToken,
113
+ lockedRootHash,
114
+ });
115
+ }
116
+ }
96
117
  if (logRes?.ok && logRes.json?.success) {
97
- return { ok: true, scanId: logRes.json?.data?.scanId || null };
118
+ return { ok: true, scanId: logRes.json?.data?.scanId || null, rebound: revoked && !!installToken };
98
119
  }
99
120
  return {
100
121
  ok: false,
@@ -482,22 +503,39 @@ server.registerTool('buildClaudePrompt', {
482
503
  });
483
504
 
484
505
  async function main() {
485
- if (!INSTALL_TOKEN || !BOUND_ROOT) {
506
+ if (UNIVERSAL_MODE) {
507
+ if (!AUTH_TOKEN) {
508
+ throw new Error(
509
+ 'Universal MCP mode requires VIBESECUR_AUTH_TOKEN. ' +
510
+ 'Generate config from the dashboard (MCP page) or run: vibesecur-mcp init --mode=universal',
511
+ );
512
+ }
513
+ if (!API_BASE) {
514
+ throw new Error(
515
+ 'Universal MCP mode requires VIBESECUR_API_BASE (e.g. http://localhost:4000 or https://vibesecur.onrender.com).',
516
+ );
517
+ }
518
+ } else if (!INSTALL_TOKEN || !BOUND_ROOT) {
486
519
  throw new Error(
487
- 'VIBESECUR_INSTALL_TOKEN and VIBESECUR_BOUND_ROOT are required. ' +
488
- 'Run "vibesecur-mcp bind <folder>" and update your MCP config env.',
520
+ 'Missing MCP binding. Use universal mode (VIBESECUR_AUTH_TOKEN + VIBESECUR_API_BASE) or legacy bind ' +
521
+ '(VIBESECUR_INSTALL_TOKEN + VIBESECUR_BOUND_ROOT). Run "vibesecur-mcp init --mode=universal" for setup.',
489
522
  );
490
523
  }
491
- const startupGuard = await guardPath(BOUND_ROOT);
492
- if (!startupGuard.ok) {
493
- throw new Error(`${startupGuard.code}: ${startupGuard.message}`);
524
+
525
+ if (!UNIVERSAL_MODE) {
526
+ const startupGuard = await guardPath(BOUND_ROOT);
527
+ if (!startupGuard.ok) {
528
+ throw new Error(`${startupGuard.code}: ${startupGuard.message}`);
529
+ }
494
530
  }
531
+
495
532
  const transport = new StdioServerTransport();
496
533
  await server.connect(transport);
497
534
  process.stderr.write(
498
535
  `[vibesecur] MCP server v${mcpPkg.version} started. ` +
499
- `BoundRoot: ${BOUND_ROOT || 'unconfigured'}. ` +
500
- `Lock: ${INSTALL_TOKEN ? 'set' : 'NOT SET'}.\n`,
536
+ `Mode: ${UNIVERSAL_MODE ? 'universal' : 'single-folder'}. ` +
537
+ `BoundRoot: ${BOUND_ROOT || (UNIVERSAL_MODE ? 'account-wide' : 'unconfigured')}. ` +
538
+ `Lock: ${INSTALL_TOKEN || AUTH_TOKEN ? 'set' : 'NOT SET'}.\n`,
501
539
  );
502
540
  }
503
541