Give your AI agent a memory — local-first, private, easy to install. Guided setup wizard; works out of the box on your own machine, no cloud. For everyday agent users, homelabs, and developers alike · 99.2% LongMemEval-S retrieval @ k=10 · Works with Claude · Gemini · Antigravity · OpenCode · OpenClaw · Hermes · any MCP agent (native + one-command plugins) · Hybrid search (FTS5 + vector + MMR) · GDPR · FIPS 140-3 deployment-ready · 100% local (fully offline) or cloud capable
This MCP server exposes 15 tools across admin, agent, and memory domains. Tools are explicitly registered with schemas and descriptions. However, quality is inconsistent: naming conventions are mostly strong (verb_noun pattern), but parameter descriptions are often generic, missing type constraints, and lack recovery guidance. Most critically, error handling is minimal, tools have no documented error cases, recovery paths, or actionable error messages. Schemas are present but sparse (many parameters lack type info or constraints like min/max, enums). Descriptions range from mediocre (generic 'unique agent identifier') to strong ('Register a tool domain's full surface...'). The tool inventory spans catalog management, GDPR compliance, and agent lifecycle, reasonable coverage, but design misses composition opportunities (e.g., m3_call and m3_load_domain could be unified; agent_heartbeat and agent_register overlap). Per-tool averages: naming 75, description 58, schema 45, yielding a blended 59 before penalties for missing error handling and weak parameter validation rules.
Get full record for one registered agent.
Update last_seen and set status=active. Errors if not registered.
List registered agents, optionally filtered by status and/or role.
Mark an agent as offline.
Register an agent (UPSERT). Sets status=active, last_seen=now.
Set an agent's trust score (0.5-1.0, clamped). Trust weights that agent's assertions in memory confidence aggregation; 1.0 is neutral. Upserts the agent if absent.
Enrich pending memory items with SLM-distilled facts. Default dry_run=true reports count + ETA; pass dry_run=false to execute.
Generic parameter descriptions across all tools. Most parameter annotations say only the bare name (e.g., 'Unique agent identifier', 'Data subject id') without format guidance, constraints, or examples. LLMs cannot infer whether to pass UUID, email, username, numeric ID, or other format.
Missing enum constraints on domain, status, kind, and role parameters. Parameters that accept a known set of values (domain, status, role, kind) should use JSON Schema enum declarations. Instead, valid values are only mentioned in descriptions, inviting hallucinated input.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 61 | 2026-07-28+ | v2 |
Export all memories for a data subject (GDPR data portability). Returns JSON with all memory items for the given user_id.
Right to be forgotten — hard-deletes ALL data for a user_id including memories, embeddings, relationships, and history.
Invoke ANY m3 catalog tool by name without loading its domain — the low-token path to the full tool surface. Single call: pass `tool` (e.g. 'files_stats') and `args` (an object). Batch: pass `batch`, a list of {tool, args} (each isolated — one failure won't abort the rest; capped at 100). Set `dry_run` to validate args + check the destructive gate WITHOUT executing. Returns JSON. Call `m3_index` first if you don't know a tool's args. Destructive tools require MCP_PROXY_ALLOW_DESTRUCTIVE=1.
Discover m3-memory tool capabilities, parameters, and availability. Allows filtering by a logical domain (memory, chatlog, files, entity, agent, tasks, conversations, admin, diagnostics) or searching by keywords.
List m3 catalog tools (optionally one domain) as structured rows: name, domain, one-line summary, destructive flag, and arg specs (name/type/required). Use this to discover the exact args for any tool before calling it via m3_call — cheaper than a failed call. Read-only catalog metadata; never returns tool output. Domains: memory, chatlog, files, entity, agent, tasks, conversations, diagnostics, admin.
Send a notification to an agent. Lightweight wake signal — agents poll notifications_poll.
List m3 tool domains (memory, chatlog, files, entity, agent, tasks, conversations, diagnostics, admin) and their tool counts. Call `tools_load_domain` to expose a domain's full tool surface.
Register a tool domain's full surface for the current MCP session. Use when you need tools beyond the essentials (memory_search, memory_write, memory_get, chatlog_search, chatlog_write, files_search). Valid domains: memory, chatlog, files, entity, agent, tasks, conversations, diagnostics, admin.
No error handling or recovery guidance. Tools have no documented error cases, error messages, or guidance on what the LLM should do if a call fails. For example, agent_heartbeat says 'Errors if not registered' but doesn't explain the error structure or recovery step (call agent_register first?).
Destructive and high-risk tools (gdpr_forget, m3_call with destructive flag) lack confirmation/dry-run safeguards in the interface. gdpr_forget is marked DESTRUCTIVE but has no built-in dry-run or confirmation request pattern to prevent accidental data loss.
m3_call is a generic invoke-any-tool gateway with no input validation of tool names or batch structure. Passing invalid tool names or malformed batch items will fail, but the schema and description do not document the expected structure of batch items {tool, args}.
Weak composition and discovery UX. Multiple overlapping tools (tools_load_domain, m3_call, m3_index, m3_help_capabilities) offer different discovery paths without clear guidance on which to call first or when. An LLM planning multi-step work must reason about tool relationships.
agent_heartbeat requires prior agent_register, creating a brittle multi-step pattern with no graceful fallback. If an LLM calls heartbeat before registering, it fails with no guidance on recovery.
Output schemas are not documented. Tools return JSON but the schema (fields, types, structure) is not described. For example, m3_index returns 'structured rows' and agent_list returns 'display string' or JSON (depending on as_records), but neither specifies the exact field names or types.