Skip to content

feat(mcp): emit external_id in search_notes markdown output - #1103

Merged
phernandez merged 1 commit into
mainfrom
search-markdown-external-id
Jul 18, 2026
Merged

feat(mcp): emit external_id in search_notes markdown output#1103
phernandez merged 1 commit into
mainfrom
search-markdown-external-id

Conversation

@jope-bm

@jope-bm jope-bm commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Why

The hosted Basic Memory Cloud MCP layer decorates search_notes results with web-app deep-links. For all-projects search, the tool fans out one API call per project, then merges/sorts/slices before returning — so links recorded from those per-project API calls don't match the final displayed page (wrong cap, wrong ordering). To decorate from the final result the caller actually sees, the cloud layer needs a stable per-result identifier in that output.

search_notes text output already prints permalink, score, and match, but not external_id. Permalink isn't usable as the key because all-projects search workspace-qualifies it (workspace/project/...), while external_id is globally unique and unchanged by qualification.

What

_format_search_markdown now emits a - external_id: {uuid} line per result that has one — the same pattern recent_activity already uses. Hits without an external_id render no line.

The external_id field itself already exists on SearchResult (added in #1101); this only surfaces it in the text output.

How it was tested

  • tests/mcp/test_tool_search.py::test_format_search_markdown_with_results — extended: one result carries an external_id (asserts the line renders), one does not (asserts exactly one external_id: line, no empty line).
  • uv run pytest tests/mcp/test_tool_search.py -k format_search_markdown → 2 passed. Lint clean.

Companion

Consumed by basic-memory-cloud #1546, which parses these external_ids from the final result to build per-result web-app links that match the displayed page for both single- and multi-project search. That PR pins its basic-memory rev to this commit and must be re-pinned to the merged commit here.

🤖 Generated with Claude Code

search_notes text output printed permalink/score/match but not the note's external_id, so a consumer reading the final (post-merge) markdown could not identify which notes are on the displayed page. This adds a per-result external_id line (like recent_activity), letting the hosted MCP layer deep-link each hit from the result the caller actually sees — the reliable key for all-projects search, where the displayed page is decided after the per-project API calls (#1423).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Joe P <joe@basicmemory.com>
@jope-bm

jope-bm commented Jul 18, 2026

Copy link
Copy Markdown
Contributor Author

@phernandez let me know if you don't want the entity external_id in the search results markdown, and i'll do something else.

@phernandez
phernandez merged commit 2519bbe into main Jul 18, 2026
22 checks passed
@phernandez
phernandez deleted the search-markdown-external-id branch July 18, 2026 17:45
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.

2 participants