Skip to content

feat(mcp): add mem_find_project tool for cross-project relevance routing #172

@carlos-mora-sm

Description

@carlos-mora-sm

📋 Pre-flight Checks

  • I have searched existing issues and this is not a duplicate
  • I understand this issue needs status:approved before a PR can be opened

🔍 Problem Description

When searching for a memory without knowing which project it belongs to, the only option is to call mem_search repeatedly with different project values.

There's no way to ask: "which of my projects has memories relevant to X?"

This is a routing problem — before searching deep, you need to know where to search.

Real scenario: I'm working on project-A and need to find context about "auth middleware". I don't know if I logged that under project-B, project-C, or somewhere else. Today there's no tool to answer that question in one call.

💡 Proposed Solution

New tool mem_find_project(query) that searches across all projects and returns which ones have relevant memories, ordered by relevance score.

Example usage:

mem_find_project(query: "auth middleware")

Expected output:

Projects with relevant memories:

plt-gatekeeper  (3 matches)
  → "JWT auth middleware decision"

plt-nexxo  (1 match)
  → "Auth token refresh pattern"

This is a directory lookup, not a deep search. The agent uses the result to know where to call mem_search next.

📦 Affected Area

MCP Server (tools, transport) + Store (database, queries)

🔄 Alternatives Considered

Using mem_search with all_projects: true returns individual memories but doesn't answer "where should I look?" — the result set can be large and unfocused across many projects when the agent doesn't know which project to target.

📎 Additional Context

The store already has the building blocks:

  • SearchResult already includes Project *string via embedded Observation (store.go:57)
  • Search() uses FTS5 full-text search and returns ranked results (store.go:1462)
  • ListProjectNames() lists all distinct projects (store.go:2287)
  • sanitizeFTS() handles query sanitization and is reusable

What's missing is a SearchProjectsGrouped(query) function that runs FTS5 across all projects and groups results by project, ordered by max relevance score per group.

Implementation outline:

  1. New store.SearchProjectsGrouped() — FTS5 query without project filter, group results by project in memory, order by max(rank) per group
  2. New MCP tool mem_find_project — registers the tool, calls SearchProjectsGrouped, formats output as project → match count + top match preview

This pairs naturally with mem_search(all_projects: true) as a two-step workflow:

  1. mem_find_project("topic") → discover which projects are relevant
  2. mem_search("topic", project: "the-right-project") → retrieve the actual memories

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions