@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 +1 -1
- package/src/project-bindings.mjs +25 -1
- package/src/server.js +50 -12
package/package.json
CHANGED
package/src/project-bindings.mjs
CHANGED
|
@@ -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)
|
|
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
|
-
|
|
84
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
-
'
|
|
488
|
-
'Run "vibesecur-mcp
|
|
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
|
-
|
|
492
|
-
if (!
|
|
493
|
-
|
|
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
|
-
`
|
|
500
|
-
`
|
|
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
|
|