Mnemosyne MCP Server: Retrieve Memories Detail

Level 3 (Detail) — Exact step-by-step flow of the semantic search pipeline.

Concept

retrieve_memories accepts a natural language query, embeds it via Gemini, performs cosine similarity search in pgvector, and returns matching memories ranked by relevance.

Handler Flow (MCP Layer)

File: internal/mcp/mcp.gohandleRetrieve() (lines 101-126)

  1. Parse query (string, required) and limit (int, optional, default 5) from tool arguments
  2. Call controller.SearchMemories(query, limit, 0, "", "")
  3. Format results as --- [<id>] [<date>] ---\n<content>\n
  4. Return formatted text

Parameters NOT exposed:

  • daysBack — always passed as 0
  • startStr — always passed as ""
  • endStr — always passed as ""

Search Flow (Logic + DB Layer)

File: internal/logic/logic.goSearchMemories() (lines 145-177)

  1. Embed the query text via embed.GetEmbedding(query) — same Gemini API call as ingestion
  2. Parse temporal filters (all disabled from MCP):
    • daysBack > 0 → set start to now - daysBack
    • startStr != "" → parse as YYYY-MM-DD and set start
    • endStr != "" → parse as YYYY-MM-DD and set end
  3. Call db.Search(vector, limit, start, end)

File: internal/db/db.goSearch() (lines 113-150)

  1. Build SQL dynamically:
    SELECT id, timestamp, content
    FROM memories
    WHERE 1=1
      [AND timestamp >= $2]   -- if start is set
      [AND timestamp <= $3]   -- if end is set
    ORDER BY embedding <=> $1
    LIMIT $N
    
  2. <=> is pgvector’s cosine distance operator (0 = identical, 2 = opposite)
  3. Return []Memory with ID, timestamp, content

Result Formatting

Each result is formatted as:

--- [<uuid>] [<YYYY-MM-DD>] ---
<full content text>

The list_memories tool uses the same content but applies extractTitle() (lines 224-236):

  • Looks for a TITLE: prefix on any line
  • Falls back to first 50 characters of content

Temporal Filter Gap

The DB layer fully supports time-range queries. The controller parses daysBack, startStr, endStr correctly. The gap is purely in the MCP tool schema:

  • retrieve_memories only declares query and limit
  • The handler always passes 0, "", "" to SearchMemories()
  • Any client wanting time-filtered searches must call the controller directly (not possible over MCP)

Code Paths

FileFunctionLineRole
internal/mcp/mcp.gohandleRetrieve()101MCP handler, parses query/limit
internal/logic/logic.goSearchMemories()145Query embedding + temporal filter parsing
internal/db/db.goSearch()113Dynamic SQL + cosine similarity
internal/mcp/mcp.goextractTitle()224Title extraction for list display

See Also