get_indexing_status lastUpdated remains stale after incremental sync

Author: dpearson2699Created Jun 13, 2026Updated Jun 13, 2026

Summary

After an incremental sync runs through the trigger/background sync path, get_indexing_status can still report the original full-index lastUpdated time. This makes the index look stale even when the incremental sync path has run.

Observed with @zilliz/[email protected].

Relevant implementation details

From the current MCP implementation:

  • SyncManager.handleSyncIndex() calls Context.reindexByChange(...) and logs added/removed/modified stats.
  • get_indexing_status renders the timestamp from indexedInfo.lastUpdated in the MCP snapshot.
  • The snapshot lastUpdated is set by SnapshotManager.setCodebaseIndexed(...), which is called by full indexing and some recovery paths.
  • The incremental sync path does not appear to update the per-codebase snapshot metadata after reindexByChange(...) completes.

So after trigger/background sync, the vector/Merkle state may be current, but the user-visible MCP status timestamp still reflects the earlier full-index snapshot.

Reproduction outline

  1. Index a codebase with index_codebase.
  2. Call get_indexing_status and note the Last updated value.
  3. Modify files in the codebase.
  4. Trigger incremental sync, for example by touching ~/.context/.sync-trigger with CLAUDE_CONTEXT_TRIGGER_WATCHER=true, or by letting background sync run.
  5. Confirm sync runs from MCP logs, e.g. handleSyncIndex() / reindexByChange(...) logs and added/modified/removed stats.
  6. Call get_indexing_status again.

Expected behavior

get_indexing_status should expose freshness information that reflects the latest successful sync activity.

Possible approaches:

  • update lastUpdated after a successful incremental sync
  • add separate fields such as lastFullIndexAt, lastIncrementalSyncAt, and lastSyncStats
  • make the status message clear that lastUpdated means “last full index” if that is the intended meaning

Actual behavior

The status output can continue to show the original full-index timestamp, which makes agents/users think the index is stale and encourages unnecessary force=true full reindexing.

Why this matters

MCP clients often use get_indexing_status as the freshness gate before search_code. If the status timestamp does not move after incremental refresh, clients cannot distinguish these cases:

  • no refresh has happened since the original full index
  • incremental refresh ran successfully and found no changes
  • incremental refresh ran successfully and updated changed files

That ambiguity is especially painful in multi-instance stdio setups where CLAUDE_CONTEXT_BACKGROUND_SYNC=false and CLAUDE_CONTEXT_TRIGGER_WATCHER=true are used to avoid idle polling.

Source: zilliztech/claude-context