Skip to content

feat(mcp): search all projects with one scoped query per database - #1573

Merged
phernandez merged 2 commits into
mainfrom
feat/1558-scoped-search-5-mcp-main
Sep 15, 2026
Merged

phernandez merged 2 commits into
mainfrom
feat/1558-scoped-search-5-mcp-main

Conversation

@phernandez

Copy link
Copy Markdown
Member

Summary

Re-lands #1568 on main. #1568 was merged into its stacked base branch (feat/1558-scoped-search-3b-scoped-route) rather than into main after #1567 landed, so its two commits never reached main. This PR carries those same two commits, cherry-picked onto main unchanged. See #1568 for the description, measurements, and test plan.

  • search_notes(search_all_projects=True) runs one QUERY /v2/search/ per database (the local database, and each cloud workspace) through the new ScopedSearchClient, and attributes every hit from the server's project_external_id.
  • New projects parameter searches a chosen subset by name or external id; an unknown name is an error.
  • list_memory_projects rows carry the internal id; the temporal confirmation check is shared by both search clients; search-notes(3) regenerated.

Refs #1558, #1568

🤖 Generated with Claude Code

https://claude.ai/code/session_019YW9ysxugGGBCNEGzsxtFV

phernandez and others added 2 commits September 15, 2026 18:59
`search_notes(search_all_projects=True)` used to run one project search per
project and merge the pages client-side. It now groups the accessible projects
by the database they live in (the local database, or one cloud workspace each)
and runs one `QUERY /v2/search/` per group through the new `ScopedSearchClient`,
passing the group's internal project ids. The server ranks the union in one
query and attributes each hit with `project_external_id`; the tool qualifies
permalinks and paths from that attribution rather than from which request a
result came back on, so a name collision across workspaces can no longer route
a hit to the wrong project.

A new `projects` parameter searches a chosen subset by name or external id.
It shares the grouping and merge with the all-projects path; an unknown name is
an error before any query runs. Cross-database results are still merged by
score and sliced to the requested page, a failing database is skipped with a
warning and an inexact total, a retryable outage fails the merged page, and a
server too old to attribute its results raises a version-skew error like the
existing valid-time skew check.

`list_memory_projects` now carries the internal `id` in its merged project
rows, which is what the scoped route addresses projects by. The temporal
confirmation check moves to a module function shared by both search clients.

Refs #1558

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_019YW9ysxugGGBCNEGzsxtFV
Signed-off-by: phernandez <[email protected]>
…meter

`tests/test_man_pages.py` compares the rendered SYNOPSIS and PARAMETERS of
search-notes(3) with the tool registry; the new `projects` parameter left the
committed page stale.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_019YW9ysxugGGBCNEGzsxtFV
Signed-off-by: phernandez <[email protected]>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@phernandez
phernandez merged commit ae5520a into main Sep 15, 2026
32 of 33 checks passed
@phernandez
phernandez deleted the feat/1558-scoped-search-5-mcp-main branch September 15, 2026 23:59
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.

1 participant