Skip to content

fix: honor project scope in smart search - #806

Closed
mturac wants to merge 4 commits into
rohitg00:mainfrom
mturac:fix/issue-787-project-scoped-smart-search
Closed

fix: honor project scope in smart search#806
mturac wants to merge 4 commits into
rohitg00:mainfrom
mturac:fix/issue-787-project-scoped-smart-search

Conversation

@mturac

@mturac mturac commented Jun 3, 2026

Copy link
Copy Markdown

Summary

  • add project filters to the MCP memory_recall and memory_smart_search schemas
  • forward project through MCP server and standalone proxy calls
  • filter smart-search observation and memory hits by project while preserving legacy unscoped results
  • add regression coverage for project-scoped compact, expanded, proxy, and schema paths

Tests

  • git diff --check
  • npm test -- test/smart-search.test.ts test/mcp-standalone-proxy.test.ts test/mcp-surface-default.test.ts
  • npm run build

Closes #787

Summary by CodeRabbit

  • New Features
    • Memory recall and smart search now accept an optional project field to scope results in both proxied and local modes.
    • Smart search’s expanded and compact (hybrid) results now consistently apply project filtering.
  • Documentation
    • MCP tool input schemas were updated to include the optional project field for relevant memory tools.
  • Tests
    • Added/updated tests covering project filtering in smart search (compact/expanded), MCP proxy payloads, and standalone local fallback behavior.

@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown

@mturac is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 3, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 230d5531-8a88-4c77-a680-9d956afcfb67

📥 Commits

Reviewing files that changed from the base of the PR and between 3116627 and fdd73f5.

📒 Files selected for processing (1)
  • test/mcp-standalone-proxy.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/mcp-standalone-proxy.test.ts

📝 Walkthrough

Walkthrough

Adds optional project scoping to MCP memory search tools and applies it through server forwarding, standalone proxy/local handling, and smart-search filtering.

Changes

Project-based scoping for MCP search tools

Layer / File(s) Summary
MCP tool schemas and server forwarding
src/mcp/tools-registry.ts, src/mcp/server.ts, test/mcp-surface-default.test.ts
memory_recall and memory_smart_search input schemas now include an optional project string, and MCP server handlers forward trimmed project values into mem::search and mem::smart-search. Surface tests verify the project field is exposed.
Standalone validation, proxying, and local filtering
src/mcp/standalone.ts, test/mcp-standalone-proxy.test.ts
Standalone validation accepts optional project for save, recall, and smart-search. Proxy mode includes project in outbound POST bodies, and local fallback mode persists and filters memories by matching project. Tests cover proxy payloads and local project scoping.
Smart-search project filtering
src/functions/smart-search.ts, test/smart-search.test.ts
mem::smart-search trims an optional project, filters expanded and hybrid results by project with Memory.project and Session.project fallback, adjusts over-fetch when scoping is active, and preserves project-aware lesson recall. Tests cover compact and expanded project filtering.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • rohitg00/agentmemory#926 — Touches the same MCP project-scoping path in standalone handling and related forwarding/schema changes.

Possibly related PRs

  • rohitg00/agentmemory#654 — Also modifies src/functions/smart-search.ts filtering and over-fetch behavior in the smart-search pipeline.
  • rohitg00/agentmemory#786 — Also changes mem::smart-search flow and result-ID-dependent behavior in the same implementation area.
  • rohitg00/agentmemory#849 — Also overlaps with the same smart-search implementation path and related scoping/filtering logic.

Suggested reviewers: rohitg00

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: honoring project scope in smart search.
Linked Issues check ✅ Passed The PR adds project params to the MCP tools, forwards them, and scopes smart-search reads as requested.
Out of Scope Changes check ✅ Passed The changes stay focused on project-scoped read paths and matching regression tests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/mcp-standalone-proxy.test.ts (1)

56-87: ⚡ Quick win

Add a local-fallback project-scoping regression here too.

These assertions only prove the proxy request bodies carry project. src/mcp/standalone.ts now has separate local filtering logic in handleLocal(), so a fallback regression would still leave this suite green. Please add an ECONNREFUSED case that seeds two projects and verifies memory_recall/memory_smart_search only return the requested one.

Also applies to: 109-127

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/mcp-standalone-proxy.test.ts` around lines 56 - 87, The test currently
only asserts the proxied request body carries project but misses the local
fallback branch in handleLocal; modify the test (both the memory_smart_search
case and the memory_recall case at lines 109-127) to simulate an ECONNREFUSED
upstream (e.g., make installFetch throw or return a connection-refused error) so
the code falls back to handleLocal, seed two memories in two different projects,
then call handleToolCall("memory_smart_search", ...) and
handleToolCall("memory_recall", ...) with project set to one project and assert
the returned results include only items from that project; locate references to
handleToolCall, installFetch, memory_smart_search, memory_recall and handleLocal
to add the error simulation, seeding, and project-scoped assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/functions/smart-search.ts`:
- Around line 315-353: filterExpandedByProject and filterHybridByProject perform
observationMatchesProject serially inside a loop, causing many sequential
kv.get() calls; change them to run the per-item checks in parallel (use
Promise.all over mapped observationMatchesProject promises) and then filter the
original arrays by the resolved boolean results so the functions
(filterExpandedByProject, filterHybridByProject) return the same scoped arrays
but with kv reads performed concurrently to reduce latency.

---

Nitpick comments:
In `@test/mcp-standalone-proxy.test.ts`:
- Around line 56-87: The test currently only asserts the proxied request body
carries project but misses the local fallback branch in handleLocal; modify the
test (both the memory_smart_search case and the memory_recall case at lines
109-127) to simulate an ECONNREFUSED upstream (e.g., make installFetch throw or
return a connection-refused error) so the code falls back to handleLocal, seed
two memories in two different projects, then call
handleToolCall("memory_smart_search", ...) and handleToolCall("memory_recall",
...) with project set to one project and assert the returned results include
only items from that project; locate references to handleToolCall, installFetch,
memory_smart_search, memory_recall and handleLocal to add the error simulation,
seeding, and project-scoped assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 43c4f65c-6811-4896-ba0e-9a7cd104b907

📥 Commits

Reviewing files that changed from the base of the PR and between e5c9dc6 and 5745e89.

📒 Files selected for processing (7)
  • src/functions/smart-search.ts
  • src/mcp/server.ts
  • src/mcp/standalone.ts
  • src/mcp/tools-registry.ts
  • test/mcp-standalone-proxy.test.ts
  • test/mcp-surface-default.test.ts
  • test/smart-search.test.ts

Comment thread src/functions/smart-search.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/mcp-standalone-proxy.test.ts (1)

196-232: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add coverage for unscoped ("legacy") memories under project-scoped queries.

The local fallback filter (src/mcp/standalone.ts, handleLocal) only excludes a memory when it has a non-empty project that mismatches the requested one — memories with no project are intentionally preserved. This test only exercises two project-tagged memories (alpha vs beta) and never asserts that an unscoped memory still surfaces under a project-scoped query, so a regression that started dropping unscoped memories wouldn't be caught.

✅ Suggested additional coverage
     await handleToolCall(
       "memory_save",
       { content: "shared-query beta memory", project: "beta" },
       localKv,
     );
+    await handleToolCall(
+      "memory_save",
+      { content: "shared-query legacy memory" },
+      localKv,
+    );

     const smartSearch = await handleToolCall(
       "memory_smart_search",
       { query: "shared-query", project: "alpha" },
       localKv,
     );
     const smartSearchBody = JSON.parse(smartSearch.content[0].text);
-    expect(smartSearchBody.results.map((m: { content: string }) => m.content)).toEqual([
-      "shared-query alpha memory",
-    ]);
+    expect(
+      smartSearchBody.results.map((m: { content: string }) => m.content),
+    ).toEqual(
+      expect.arrayContaining([
+        "shared-query alpha memory",
+        "shared-query legacy memory",
+      ]),
+    );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/mcp-standalone-proxy.test.ts` around lines 196 - 232, The local fallback
coverage in handleToolCall does not verify that unscoped legacy memories remain
visible when querying with a project. Extend the mcp-standalone-proxy test
alongside the existing memory_save, memory_smart_search, and memory_recall
assertions by adding an unscoped memory (no project field) and confirming it is
still returned for a project-scoped query like alpha. Keep the current scoped
alpha/beta checks, but add assertions that the legacy memory survives the
handleLocal filtering behavior in src/mcp/standalone.ts.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/mcp-standalone-proxy.test.ts`:
- Around line 196-232: The local fallback coverage in handleToolCall does not
verify that unscoped legacy memories remain visible when querying with a
project. Extend the mcp-standalone-proxy test alongside the existing
memory_save, memory_smart_search, and memory_recall assertions by adding an
unscoped memory (no project field) and confirming it is still returned for a
project-scoped query like alpha. Keep the current scoped alpha/beta checks, but
add assertions that the legacy memory survives the handleLocal filtering
behavior in src/mcp/standalone.ts.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b907d274-a57e-4f54-b49b-005a27225c03

📥 Commits

Reviewing files that changed from the base of the PR and between 5745e89 and 3116627.

📒 Files selected for processing (5)
  • src/functions/smart-search.ts
  • src/mcp/server.ts
  • src/mcp/standalone.ts
  • src/mcp/tools-registry.ts
  • test/mcp-standalone-proxy.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/mcp/tools-registry.ts
  • src/mcp/server.ts
  • src/mcp/standalone.ts
  • src/functions/smart-search.ts

@mturac mturac closed this Jul 5, 2026
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.

Project scoping not honored by MCP search tools (memory_smart_search / memory_recall) or /smart-search

1 participant