fix(mcp): validate navigation pagination and fix recent_activity project display by phernandez · Pull Request #915 · basicmachines-co/basic-memory · GitHub
Skip to content

fix(mcp): validate navigation pagination and fix recent_activity project display - #915

Merged
phernandez merged 1 commit into
mainfrom
fix/navigation-pagination
Jun 8, 2026
Merged

fix(mcp): validate navigation pagination and fix recent_activity project display#915
phernandez merged 1 commit into
mainfrom
fix/navigation-pagination

Conversation

@phernandez

Copy link
Copy Markdown
Member

Summary

Fixes three navigation/pagination bugs found by the integration-test bug hunt in the MCP tools search_notes, build_context, and recent_activity. Two of them (#9, #10) make pagination validation consistent across all three navigation tools — previously only recent_activity rejected non-positive page/page_size. The third (#13) stops recent_activity's text header from leaking a raw project UUID.

Bugs fixed

  • feat: import chatgpt conversation data #9search_notes accepted non-positive page_size and returned a misleading has_more=true with zero rows. A page_size=0 returned {results: [], total: 15, has_more: True} — no reachable page could ever fetch those rows. A negative page_size became an uncapped SQLite LIMIT and returned an arbitrary slice. Added the same page < 1 / page_size < 1 guard that recent_activity already uses, so the tool fails fast with a clear ValueError.
  • fix: Re do enhanced read note format #10build_context with page_size<=0 silently dropped the requested primary entity. A valid memory:// lookup returned primary_count=0 because the context service does primary = primary[:limit], and limit=0 truncates the resolved entity to []. Added the same page/page_size validation so a valid direct lookup never silently returns nothing.
  • feat: Incremental sync on watch #13recent_activity text output showed the raw project UUID instead of the project name when routed via project_id. When callers pass only project_id (a UUID), resolved_project is the verbatim UUID. The fix uses active_project.name (the canonical, display-safe name already in scope from get_project_client) for both the log line and the formatted header — matching every other tool's display behavior.

Testing

All regression tests live in test-int/bughunt_fixes/test_navigation_pagination_integration.py and use the real MCP server (FastMCP Client), real DB, and ASGI routing — no mocks. The CLI portion uses the real Typer CliRunner.

Commands and results:

  • uv run pytest test-int/bughunt_fixes/test_navigation_pagination_integration.py -q --no-cov → 4 passed
  • BASIC_MEMORY_TEST_POSTGRES=1 uv run pytest test-int/bughunt_fixes/... -q --no-cov → 4 passed (Postgres)
  • uv run pytest tests/mcp/ -q --no-cov → 697 passed, 8 skipped (includes test_tool_contracts.py + test_tool_telemetry.py)
  • uv run pytest test-int/mcp/test_pagination_integration.py test-int/mcp/test_build_context_validation.py test-int/mcp/test_ui_sdk_integration.py test-int/mcp/test_search_integration.py test-int/mcp/test_output_format_json_integration.py test-int/mcp/test_chatgpt_tools_integration.py test-int/mcp/test_param_aliases_integration.py -q --no-cov → all passed
  • uv run pytest test-int/cli/test_cli_tool_json_integration.py test-int/cli/test_search_notes_meta_integration.py test-int/cli/test_cli_tool_json_failure_integration.py -q --no-cov → all passed
  • uv run pytest tests/cli/ -k "tool or search" -q --no-cov → 48 passed
  • uv run ruff check ... / uv run ruff format ... → clean
  • uv run ty check src tests test-int → All checks passed

Risk

Low. No tool signatures changed. The fix tightens existing pagination validation to match recent_activity's established pattern (raise ValueError for page<1/page_size<1), so callers that previously got silent bad payloads now get an explicit error. The CLI search-notes command already maps ValueError to a non-zero exit with a clear message. Internal search_notes callers (chatgpt_tools, read_note, ui_sdk, ci) all use positive defaults. The #13 change is a display-only fix.

🤖 Generated with Claude Code

…ect display

From the integration-test bug hunt. Regression tests live under test-int/bughunt_fixes/ and exercise the real MCP server, DB, and ASGI routing (no mocks).

Bugs fixed:
- #9  search_notes accepted non-positive page_size and returned a misleading
      has_more=true with zero rows (a negative page_size became an uncapped SQLite
      LIMIT). Added the same page/page_size guard recent_activity uses so all three
      navigation tools reject invalid pagination consistently.
- #10 build_context with page_size<=0 silently dropped the requested primary entity
      (primary_count=0 for a valid memory:// URL) because the context service does
      primary = primary[:limit]. Added the same page/page_size validation.
- #13 recent_activity text output printed the raw project UUID instead of the
      project name when routed via project_id. Use active_project.name (the canonical,
      display-safe name) for both the log line and the formatted header.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: phernandez <paul@basicmachines.co>
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

@phernandez
phernandez merged commit 7c0937f into main Jun 8, 2026
40 of 41 checks passed
@phernandez
phernandez deleted the fix/navigation-pagination branch June 8, 2026 04:03
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