Repository navigation
Expose live indexing progress to MCP clients #2031
Copy link
Copy link
Open
Labels
editor/integrationEditor compatibility and CLI integrationEditor compatibility and CLI integrationenhancementNew feature or requestNew feature or requestpriority/normalStandard review queue; useful PR with ordinary maintainer urgency.Standard review queue; useful PR with ordinary maintainer urgency.ux/behaviorDisplay bugs, docs, adoption UXDisplay bugs, docs, adoption UX
Description
What problem does this solve?
index_repository can run for minutes or hours on large repositories, but an MCP client currently receives no quantitative progress until the synchronous tool call completes.
index_status reports the already-published graph (nodes, edges, and ready|empty), not the active indexing attempt. The UI job endpoint similarly exposes only indexing|done|error.
The indexer already emits useful structured events such as:
pipeline.discover files=Npass.start pass=... files=Nparallel.extract.progress done=N total=M
These events are consumed by the one-shot CLI progress sink, but are not exposed through MCP progress notifications or an in-flight status snapshot. This makes a healthy long-running index indistinguishable from a stalled one.
Proposed solution
Expose live per-attempt indexing progress to MCP clients.
- When the client supplies an MCP progress token, publish progress notifications while
index_repositoryis running. - Include a structured snapshot for the active/latest attempt in
index_status, so another client or session can poll it. - At minimum expose:
- attempt/run identifier
- state:
queued,running,completed,failed, orcancelled - current phase/pass
- processed and total units for phases that have real counters
- discovered file count
- started and last-updated timestamps
- Do not invent a single overall percentage unless the pipeline has a well-defined weighted model. Phase-local
processed/totalis enough initially. - Preserve the current final
index_repositoryresponse and existingindex_statusfields for compatibility. - Ensure daemon-supervised jobs propagate progress without mixing it into MCP stdout or JSON-RPC responses.
- Rate-limit or coalesce updates to avoid flooding clients.
Suggested acceptance criteria:
- A long-running MCP
index_repositorycall emits monotonic progress updates for the extraction phase. index_statusshows the same in-flight attempt state and counters.- A client that does not request progress sees unchanged behavior.
- Completion, failure, and cancellation leave a terminal attempt record, and the final notification agrees with the tool result.
- Tests cover daemon transport, multiple subscribers, and compatibility when no progress token is supplied.
Related work:
- feat(cli): add --progress flag for live indexing progress output #108 and commit
dbab4d37implemented the CLI presentation. - feat(index): record and report the latest index attempt #1727 records the latest attempt and freshness; this issue adds quantitative live progress.
- Clean linked-worktree full index stalls silently for workspace-scale projects with persisted stored_hashes >= 267k #1300 is an example where a long-running index can appear stalled.
Alternatives considered
- Rely on daemon logs: they are not available through MCP and require client-specific parsing.
- Return only final node and edge counts: this is too late to distinguish progress from a stall.
- Expose only an overall percentage: it would be misleading because pipeline phases have different costs and not every phase has a meaningful total.
Confirmations
- I searched existing issues and this is not a duplicate.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
editor/integrationEditor compatibility and CLI integrationEditor compatibility and CLI integrationenhancementNew feature or requestNew feature or requestpriority/normalStandard review queue; useful PR with ordinary maintainer urgency.Standard review queue; useful PR with ordinary maintainer urgency.ux/behaviorDisplay bugs, docs, adoption UXDisplay bugs, docs, adoption UX
Activity
astandrik commentedon Sep 13, 2026
Checking before writing code, since CONTRIBUTING asks for that.
On current
mainthe pipeline events this issue mentions reach nothing except the supervisor's quiet-timeout tail: the worker runs inside the daemon and its log stays there. That makes the two halves of this request very different in cost.The
index_statushalf is small and daemon-only: pass a log callback when the daemon starts the worker, keep a per-job snapshot (phase, done/total, timestamps, terminal state), expose it fromindex_statusas an additive field. No wire change.The
notifications/progresshalf needs a new daemon-to-frontend path, since the wire is strictly request/response today. That is a protocol decision I would not make for you.Would you take the
index_statushalf as a standalone PR? Notifications I would leave for a separate issue once you have a preferred wire shape.feat(mcp): opt-in async index_repository with status polling (DeusDat…