A lightweight, structured, token-efficient local-first MCP memory server (Drizzle + libSQL)
Strong tool naming (verb_noun pattern), excellent descriptions with USE WHEN/DO NOT USE guidance, and comprehensive parameter documentation. All 9 tools have clear, actionable descriptions (avg ~250 chars, well within 10-1024 range). Tool annotations (readOnly, idempotent) are properly declared. However, input schemas lack explicit JSON Schema type definitions in the visible code, parameters are documented in descriptions but not formally typed in schema objects. Output schemas are documented in descriptions but not formally structured. Error handling guidance is minimal. No evidence of pagination support for search results.
Return the user's cross-project global memory summary (coding style, recurring preferences, stable workflow conventions). USE WHEN: the request depends on durable user-level preferences that apply across projects. DO NOT USE WHEN: the question is project-specific, purely syntactic, or self-contained. RETURNS: { found, summary? } where summary has { id, title, summary, updated_at }.
Load the full body of a specific memory by id. USE WHEN: a search_memory_light candidate looks relevant and you need its full content / metadata. DO NOT USE WHEN: you have not identified a specific memory id, or you are tempted to call this many times in a row. LIMIT: call at most 3 times per user turn. RETURNS: { found, memory? } where memory has { id, title, summary, content, memory_type, level, importance, source, metadata, created_at, updated_at }.
Return the concise summary for the current project (architecture, key decisions, conventions). USE WHEN: the request depends on project-level context — architecture, conventions, long-term decisions, or project overview. DO NOT USE WHEN: the request is about the current task's state, global preferences, or is self-contained. CALL ORDER: prefer this before search_memory_light. Pass workspace_path OR git_root OR remote_url OR project_id so the server can identify the project. RETURNS: { project_id, found, summary? } where summary has { id, title, summary, updated_at }.
Return the current task summary (what was done, blockers, next steps). USE WHEN: the user asks to continue, resume, or recall recent work on a task. DO NOT USE WHEN: there is no prior task state referenced, or the request is about global / project-level context. RETURNS: { project_id, found, summary? } where summary has { id, title, summary, updated_at }.
Input schemas lack formal JSON Schema type definitions. Parameters are documented in descriptions but not declared with 'type', 'enum', 'minimum', 'maximum' in schema objects. This forces LLMs to parse descriptions rather than reading machine-readable constraints.
Output schemas are documented only in descriptions (e.g., 'RETURNS: { found, summary? }') but not formally structured. LLMs cannot parse unstructured text to understand response fields, types, and nesting.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 47 | 2025-06-18+ | v2 |
Persist a durable technical decision (architecture choice, trade-off, accepted pattern, rejected alternative). USE WHEN: the user confirms a decision that should outlive the current session. DO NOT USE WHEN: the info is a transient fact/command (use remember_fact) or raw chat log. IMPORTANCE: defaults to 0.8 — override only if the user signals otherwise. RETURNS: { project_id, memory_id }.
Persist a concise atomic memory: fact, command, gotcha, link, or convention. USE WHEN: the user gives concrete reusable info (a command, env detail, integration note, rule). DO NOT USE WHEN: the info is a major decision (use remember_decision) or a summary (use upsert_*_summary). FACT TYPES: fact | command | gotcha | link | convention | decision (prefer remember_decision for 'decision'). RETURNS: { project_id, memory_id }.
Lexical FTS5 search across atomic memories. Returns compact candidate records only — not full content. USE WHEN: the summary tools above do not provide enough context AND the request includes a concrete search phrase (command name, symbol, past event). DO NOT USE WHEN: summaries already answer the question, the query is empty/too vague, or you only need the global/project/task summary. CALL ORDER: always call summary tools first. Then follow up this tool's top 1-3 results with get_memory_detail — never dump all candidates. RETURNS: { count, results: [{ id, title, summary, memory_type, level, importance, updated_at }] }.
Idempotently create or replace the structured project summary node. USE WHEN: architecture, conventions, or key decisions changed enough that a fresh summary is worth storing. DO NOT USE WHEN: the change is a single fact / decision (use remember_fact or remember_decision). RETURNS: { project_id, summary_id }.
Idempotently create or replace the current task summary (progress, blockers, next steps). USE WHEN: meaningful progress was made, a blocker appeared, or the plan changed and the next session must resume. DO NOT USE WHEN: the update fits better as a single fact or decision. RETURNS: { project_id, summary_id }.
search_memory_light returns 'compact candidate records' but lacks pagination parameters (limit, offset, cursor). Large result sets risk context window exhaustion. No documented result cap or pagination guidance.
Error handling is not documented. No guidance on retryability, user-fixable vs fatal errors, or recovery steps. Tools like remember_decision and remember_fact (WRITE operations) lack confirmation or dry-run patterns.
Project/task identification accepts multiple optional parameters (project_id, workspace_path, git_root, remote_url) without documenting mutual exclusivity or precedence. LLMs may pass conflicting values.