Skip to content

Commit 434705d

Browse files
feat(mcp): make background sync opt-in
1 parent b03ebac commit 434705d

3 files changed

Lines changed: 82 additions & 5 deletions

File tree

packages/mcp/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,22 @@ CODE_CHUNKS_COLLECTION_NAME_OVERRIDE=my_project
197197

198198
The per-codebase `<pathHash>` suffix is preserved even when the override is set, so the same MCP server can still index multiple repos without collapsing them onto one collection. The override value is sanitized to letters, numbers, and underscores, and truncated to keep the full name within Milvus's 255-char limit. If you unset the variable later, Claude Context switches back to the plain `code_chunks_<pathHash>` naming.
199199

200+
#### Background Sync Configuration (Optional)
201+
202+
By default, the MCP server does **not** run background sync. This avoids duplicated rescans when multiple local MCP sessions are open at the same time.
203+
204+
If you want automatic reindexing, enable it explicitly:
205+
206+
```bash
207+
# Opt in to startup + periodic background sync
208+
CLAUDE_CONTEXT_BACKGROUND_SYNC=true
209+
210+
# Optional: control how often sync runs (default: 300000 = 5 minutes)
211+
CLAUDE_CONTEXT_SYNC_INTERVAL_MS=60000
212+
```
213+
214+
This is most useful when you run Claude Context as a single long-lived MCP server. For per-session local stdio setups, leaving background sync disabled usually avoids unnecessary CPU churn.
215+
200216
## Usage with MCP Clients
201217

202218
<details>

packages/mcp/src/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ Environment Variables:
226226
The per-codebase pathHash is preserved so multiple
227227
codebases stay distinct under the same override.
228228
229+
MCP Sync Configuration:
230+
CLAUDE_CONTEXT_BACKGROUND_SYNC Enable background sync for indexed codebases (default: false)
231+
CLAUDE_CONTEXT_SYNC_INTERVAL_MS Background sync interval in milliseconds when enabled (default: 300000)
232+
229233
Examples:
230234
# Start MCP server with OpenAI (default) and explicit Milvus address
231235
OPENAI_API_KEY=sk-xxx MILVUS_ADDRESS=localhost:19530 npx @zilliz/claude-context-mcp@latest
@@ -247,5 +251,8 @@ Examples:
247251
248252
# Start MCP server with a human-readable collection name override
249253
OPENAI_API_KEY=sk-xxx MILVUS_TOKEN=your-token CODE_CHUNKS_COLLECTION_NAME_OVERRIDE=my_project npx @zilliz/claude-context-mcp@latest
254+
255+
# Start MCP server with background sync enabled every minute
256+
OPENAI_API_KEY=sk-xxx MILVUS_TOKEN=your-token CLAUDE_CONTEXT_BACKGROUND_SYNC=true CLAUDE_CONTEXT_SYNC_INTERVAL_MS=60000 npx @zilliz/claude-context-mcp@latest
250257
`);
251258
}

packages/mcp/src/sync.ts

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,59 @@
11
import * as fs from "fs";
22
import * as os from "os";
33
import * as path from "path";
4-
import { Context, FileSynchronizer } from "@zilliz/claude-context-core";
4+
import { Context, FileSynchronizer, envManager } from "@zilliz/claude-context-core";
55
import { SnapshotManager } from "./snapshot.js";
66

7+
const DEFAULT_INITIAL_SYNC_DELAY_MS = 5_000;
8+
const DEFAULT_SYNC_INTERVAL_MS = 5 * 60 * 1000;
9+
const MIN_SYNC_INTERVAL_MS = 1_000;
710
const DEFAULT_SYNC_LOCK_STALE_MS = 10 * 60 * 1000;
811
const SYNC_LOCK_STALE_ENV = "CLAUDE_CONTEXT_SYNC_LOCK_STALE_MS";
912

13+
function isBackgroundSyncEnabled(): boolean {
14+
const value = envManager.get("CLAUDE_CONTEXT_BACKGROUND_SYNC");
15+
if (!value) {
16+
return false;
17+
}
18+
19+
switch (value.trim().toLowerCase()) {
20+
case "1":
21+
case "true":
22+
case "yes":
23+
case "on":
24+
return true;
25+
case "0":
26+
case "false":
27+
case "no":
28+
case "off":
29+
return false;
30+
default:
31+
console.warn(
32+
`[SYNC-DEBUG] Invalid CLAUDE_CONTEXT_BACKGROUND_SYNC value '${value}'. ` +
33+
"Expected true/false. Background sync will remain disabled."
34+
);
35+
return false;
36+
}
37+
}
38+
39+
function getBackgroundSyncIntervalMs(): number {
40+
const value = envManager.get("CLAUDE_CONTEXT_SYNC_INTERVAL_MS");
41+
if (!value) {
42+
return DEFAULT_SYNC_INTERVAL_MS;
43+
}
44+
45+
const intervalMs = Number.parseInt(value, 10);
46+
if (!Number.isFinite(intervalMs) || intervalMs < MIN_SYNC_INTERVAL_MS) {
47+
console.warn(
48+
`[SYNC-DEBUG] Invalid CLAUDE_CONTEXT_SYNC_INTERVAL_MS value '${value}'. ` +
49+
`Falling back to ${DEFAULT_SYNC_INTERVAL_MS}ms.`
50+
);
51+
return DEFAULT_SYNC_INTERVAL_MS;
52+
}
53+
54+
return intervalMs;
55+
}
56+
1057
export class SyncManager {
1158
private context: Context;
1259
private snapshotManager: SnapshotManager;
@@ -212,8 +259,15 @@ export class SyncManager {
212259
public startBackgroundSync(): void {
213260
console.log('[SYNC-DEBUG] startBackgroundSync() called');
214261

262+
if (!isBackgroundSyncEnabled()) {
263+
console.log('[SYNC-DEBUG] Background sync is disabled. Set CLAUDE_CONTEXT_BACKGROUND_SYNC=true to enable it.');
264+
return;
265+
}
266+
267+
const syncIntervalMs = getBackgroundSyncIntervalMs();
268+
215269
// Execute initial sync immediately after a short delay to let server initialize
216-
console.log('[SYNC-DEBUG] Scheduling initial sync in 5 seconds...');
270+
console.log(`[SYNC-DEBUG] Scheduling initial sync in ${DEFAULT_INITIAL_SYNC_DELAY_MS}ms...`);
217271
setTimeout(async () => {
218272
console.log('[SYNC-DEBUG] Executing initial sync after server startup');
219273
try {
@@ -227,14 +281,14 @@ export class SyncManager {
227281
// Do not re-throw here: this callback runs via setTimeout with no caller to propagate to.
228282
}
229283
}
230-
}, 5000); // Initial sync after 5 seconds
284+
}, DEFAULT_INITIAL_SYNC_DELAY_MS);
231285

232286
// Periodically check for file changes and update the index
233-
console.log('[SYNC-DEBUG] Setting up periodic sync every 5 minutes (300000ms)');
287+
console.log(`[SYNC-DEBUG] Setting up periodic sync every ${syncIntervalMs}ms`);
234288
const syncInterval = setInterval(() => {
235289
console.log('[SYNC-DEBUG] Executing scheduled periodic sync');
236290
this.handleSyncIndex();
237-
}, 5 * 60 * 1000); // every 5 minutes
291+
}, syncIntervalMs);
238292

239293
console.log('[SYNC-DEBUG] Background sync setup complete. Interval ID:', syncInterval);
240294
}

0 commit comments

Comments
 (0)