Skip to content

fix(mcp): report never-indexed projects instead of a silent empty search - #1535

Open
wangzhengzhuo05 wants to merge 1 commit into
basicmachines-co:mainfrom
wangzhengzhuo05:fix/1534-mcp-never-indexed-says-so
Open

fix(mcp): report never-indexed projects instead of a silent empty search#1535
wangzhengzhuo05 wants to merge 1 commit into
basicmachines-co:mainfrom
wangzhengzhuo05:fix/1534-mcp-never-indexed-says-so

Conversation

@wangzhengzhuo05

Copy link
Copy Markdown

What

On a project that has never been indexed (project.last_indexed_at IS NULL), the MCP tools reported an ordinary empty result that is indistinguishable from an honest "no match" on an indexed project:

  • search_notes returned results: [] plus No results found for '<q>' in project '<p>'. Try broader or different terms, ...
  • recent_activity (project-scoped) was empty and said nothing about the index.

Both are vacuous negatives: files exist on disk, but nothing was ever searched. This defeats the "search before creating" convention agents rely on, and it is the state of every fresh install before the first index pass.

Why

The signal already exists — ProjectIndexPhase.NEVER_INDEXED and ProjectIndexReadiness.describe() — and the CLI already uses it (bm status, bm project add). Nothing under src/basic_memory/mcp/ read last_indexed_at, so the MCP surface — the one agents actually read through — never asked.

How

  • src/basic_memory/mcp/tools/search.py: on the zero-result path only, read readiness through the existing typed client (ProjectClient.get_status). When the phase is NEVER_INDEXED, _format_search_markdown returns an honest sentence that reuses ProjectIndexReadiness.describe(...) (so it cannot drift from bm status). The structured path carries index_phase in the returned payload.
  • src/basic_memory/mcp/tools/recent_activity.py: the same guard for the project-scoped empty page, replacing the "you have no notes yet" onboarding (which would misread "never looked" as "no notes") with the never-indexed state.
  • If readiness cannot be read, both paths fall back to today's copy — this is a reporting courtesy, not a hard failure.
  • No schema, router, client, or CLI changes; no new dependencies. An indexed project pays nothing (the readiness read happens only on the empty path).

Tests

Added 3 tests (tests/mcp/test_tool_search.py, tests/mcp/test_tool_recent_activity.py) that set up a project whose last_indexed_at is None with a note on disk:

  • search_notes text output names the never-indexed state and the bm project index remedy
  • search_notes(output_format="json") carries index_phase == "never_indexed"
  • recent_activity text reports the never-indexed state

Results:

uv run pytest tests/mcp/test_tool_search.py tests/mcp/test_tool_recent_activity.py -q --no-cov
88 passed, 2 failed

Both failures (test_search_with_date_filter, test_recent_activity_format_relative_time_and_truncate_helpers) are pre-existing on clean main — confirmed by stashing this change and re-running them (same 2 failures), and they are unrelated to the touched code.

uv run ruff check and uv run ruff format --check pass on all changed files.

Mutation check

Disabling the readiness read (index_readiness = None) makes all 3 new tests fail, and restoring it makes them pass — the tests genuinely guard the fix.

Notes

  • Commits carry a DCO Signed-off-by line.
  • This is my first PR here, so the license/cla check will need my one-time CLA acceptance from the GitHub bot link; the DCO check should pass on its own.

Fixes #1534

On a project whose last_indexed_at is NULL, search_notes and recent_activity
returned an ordinary empty result, indistinguishable from an honest miss on an
indexed project. Readiness already exists (ProjectIndexPhase/describe, used by
bm status) but nothing under mcp/ read it.

On the zero-result path only, read readiness via ProjectClient.get_status and,
when the phase is NEVER_INDEXED, reuse ProjectIndexReadiness.describe so the
wording cannot drift from bm status. search_notes JSON output carries
index_phase; an unreadable readiness falls back to today's copy.

Fixes basicmachines-co#1534

Signed-off-by: wangzhengzhuo05 <[email protected]>
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

@CLAassistant

CLAassistant commented Sep 11, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

search_notes returns an empty result set on a never-indexed project, indistinguishable from "no such note"

2 participants