Jobs to be done
| JTBD | Tool(s) |
|---|---|
| “Persist something worth keeping” | remember |
| ”Find what I know” (memories + facts, supersession-aware, time-travel) | search |
| ”Correct the record” (supersede, extend, resolve, archive) | revise, resolve |
| ”Start my session oriented” | briefing |
| ”Carry context to another tool/agent” | handoff |
| ”What is currently true about X” | get_facts |
| ”Organize my memory space” | configure_scope |
| ”Review what the consolidator proposes” | review_proposals |
| ”Know what this server can do / how I’m set up” | describe_environment |
v1 tools (10)
remember— append a memory (type, scope, project). Never merges. Returns the created memory + any consolidation proposals it triggered (advisory).search— unified retrieval: semantic + FTS + recency fusion; filters (type/scope/project/status);as_offor bi-temporal time travel;memory_idsfor direct lookup; returns coverage envelope. One unified retrieval tool in place of several specialist search tools. The web UI exposes a user-selectable result limit (5 / 10 / 25, defaulting to 5); the hard ceiling isMAX_SEARCH_LIMIT = 25(packages/schemamcp.ts).revise— the correction surface: create asupersedes/updates/extendsedge with new content, or archive. Unifies update and supersession logic in one tool. Never edits in place destructively.resolve/ unresolve (flag) — commitment/blocker FSM transitions.briefing— structured: commitments, blockers, overdue, stale, recent decisions, preferences. Requires explicit selector (scope/project/all) — carry forward the no-firehose rule.briefmode default.handoff— export structured context for another provider/agent.get_facts— currently-valid facts for a subject (bi-temporal aware).configure_scope— scope CRUD + aliases + mappings.review_proposals— list/accept/reject consolidation proposals (the human-in-the-loop side of background consolidation).describe_environment— capabilities, config, scopes, stats.
Server architecture
- Official TS SDK pinned
1.29.0+ express. Streamable HTTP, stateless. Hono revisited at SDK v2 GA as a deliberate bump. - Strict OAuth resource server: validate JWT
aud+ RFC 8707 resource indicators. No token proxying (the FastMCP CVE class). - Every tool: Zod input schema +
outputSchema(structured output) frompackages/schema— same types the REST API and SDK use. - Output size discipline: structured,
briefmodes, pagination — oversized responses are an easy trap, so design the size discipline in from the start. - MCP and REST are thin adapters over the same
packages/coreservice layer — no logic in the transport layer, no MCP↔API drift. - Prompts: start with 2 (
briefing,debrief) as code-defined templates. Resources: defer until a client demonstrably uses them. GET /api/v1/memories/facets: returns{ scopes: string[], projects: string[] }— DISTINCT live-corpus values for the browse filter UI. Registered beforeGET /api/v1/memories/:idto prevent Express matching “facets” as an:idparam. Also extendsGET /api/v1/memoriesto accept repeated?project=params for multi-project IN filtering.
Search — fusion detail
Thesearch tool runs a weighted-sum fusion of three legs (vector, FTS, recency). Weights are policy-owned by packages/core; the SQL is owned by packages/db.
Short queries (≤2 whitespace tokens) activate a topic entity-match bonus (topicMatch weight 0.5): memories whose topic contains the query string score +0.5. This surfaces person-identity facts for first-name searches without affecting long-query MRR (all golden-set queries are 6+ tokens).
Rate limiting & sessions
Redis-backed, per-user + per-key. Session binding to authenticated principal per SDK ≥1.27 semantics. Sessions are stateless by design: all MCP session state lives in Postgres/Redis, never in-process — any server instance serves any request. This makes redeploys non-events..well-known/mcp server metadata (SEP-1649) is tracked but deferred until the SEP stabilizes.