mcp-automem
The AutoMem MCP server provides persistent, cross-session memory for AI assistants using a graph-vector hybrid backend (FalkorDB + Qdrant), enabling storage, retrieval, and management of memories across conversations and platforms.
Store Memories: Save individual memories or batch-ingest up to 500 at once. Supports 7 memory types (Decision, Pattern, Preference, Style, Habit, Insight, Context), tags, importance scores (0ā1), metadata, confidence, custom IDs, time-bounded validity, custom embeddings, and supersede/correct modes that automatically link old and new memories via
INVALIDATED_BYorEVOLVED_INTOrelationships.Recall Memories: Retrieve memories in three modes:
ID fetch: Retrieve a single memory by ID
Tag enumeration: Paginated exact-match listing by tag (up to 200/page) for audits or cleanup
Ranked retrieval: Hybrid semantic + keyword + tag + recency search with graph expansion, multi-hop reasoning (
expand_entities), language hints, score filtering, and state filtering (current vs. historical)
Associate Memories: Build a knowledge graph with 11 typed relationship types (RELATES_TO, LEADS_TO, OCCURRED_BEFORE, PREFERS_OVER, EXEMPLIFIES, CONTRADICTS, REINFORCES, INVALIDATED_BY, EVOLVED_INTO, DERIVED_FROM, PART_OF). Supports single-pair or batch mode (up to 500 associations) with customizable strength, reason, and context.
Update Memories: Modify content, tags, importance, type, confidence, metadata, or timestamps of existing memories without creating duplicates.
Delete Memories: Remove a single memory by ID, or bulk-delete all memories matching any of a given list of tags (irreversible).
Check Database Health: Monitor the AutoMem service, FalkorDB graph, and Qdrant vector databases, including memory/vector counts, sync status, vector dimensions, and enrichment diagnostics.
Connects to ElevenLabs Agents Platform via remote MCP, giving AI agents memory persistence and recall capabilities.
Integrates with GitHub Copilot to offer persistent memory, allowing the coding agent to recall user patterns and decisions across sessions.
Works with OpenAI Codex and ChatGPT (through remote MCP) to provide persistent memory, enabling the AI to remember context and user preferences across conversations.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-automemremember my preference for dark mode in code editors"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
AutoMem MCP: Give Your AI Perfect Memory
One command. Infinite memory. Perfect recall across all your AI tools.
npx @verygoodplugins/mcp-automem setupYour AI assistant now remembers everything. Forever. Across every conversation.
https://github.com/user-attachments/assets/fd79112b-5158-4320-a054-8c18ab1ea314
Works with Claude Desktop, Cursor IDE, Claude Code, GitHub Copilot (coding agent), ChatGPT, ElevenLabs, OpenAI Codex, OpenClaw, Hermes, Grok Build, Google Antigravity - any MCP-compatible AI platform.
The Problem We Solve
Every AI conversation starts from zero. Claude forgets your coding style. Cursor can't learn your patterns. Your assistant doesn't remember yesterday's decisions.
Until now.
AutoMem MCP connects your AI to persistent memory powered by AutoMem - a graph-vector memory service.
Related MCP server: my-memory-mcp
What You Get
š§ Persistent Memory Across Sessions
AI remembers decisions, patterns, and context forever
Works across all MCP platforms - Claude Desktop, Cursor, Claude Code, OpenAI Codex, OpenClaw, Hermes, Grok Build, Google Antigravity
Cross-device sync - same memory on Mac, Windows, Linux
š Graph-Vector Architecture
11 public authorable relationship types between memories (recall results may also include read-only system/internal relations that are not valid
associate_memoriesinputs)Research-validated approach (HippoRAG 2: 7% better associative memory)
Sub-second retrieval even with millions of memories
š Works Everywhere You Code
Platform | Support | Setup Time |
Claude Desktop | ā Full | 30 seconds |
Cursor IDE | ā Full | 30 seconds |
Claude Code | ā Full | 30 seconds |
GitHub Copilot | ā Full | 2 minutes |
OpenAI Codex | ā Full | 30 seconds |
OpenClaw | ā Full | 30 seconds |
Hermes Agent | ā Full | 30 seconds |
Grok Build | ā Full | 30 seconds |
Google Antigravity | ā Full | 30 seconds |
Any MCP client | ā Full | 30 seconds |
See It In Action
Claude Desktop with Personal Preferences
Claude automatically recalls memories using the Personal Preferences template
Cursor IDE with Memory Rules
Cursor uses automem.mdc rule to automatically recall and store memories
Claude Code with Session Memory
Session-start recall plus LLM-judged storage: Claude decides what's durable and stores it via the memory tools
More platform walkthroughs (Codex, Hermes, Antigravity, remote MCP) live in the Installation Guide.
Quick Start
1. Set Up AutoMem Service
You need a running AutoMem service (the memory backend). Choose one:
Option A: Local Development (fastest, free)
git clone https://github.com/verygoodplugins/automem.git
cd automem
make devService runs at http://localhost:8001 - perfect for single-machine use.
Option B: Railway Cloud (recommended for production)
One-click deploy with $5 free credits. Typical cost: ~$0.50-1/month after trial.
š AutoMem Service Installation Guide - Complete setup instructions for local, Railway, Docker, and production deployments.
2. Install MCP Client
Claude Desktop - One-Click Install
Download and double-click to install AutoMem in Claude Desktop:
ā¬ļø Download AutoMem for Claude Desktop (.mcpb)
After installing:
Claude Desktop will prompt you for your AutoMem Endpoint (
http://127.0.0.1:8001for local)Optionally enter your API Key (required for Railway, skip for local)
Click Enable
Then add the paste-ready Personal Preferences starter from templates/CLAUDE_DESKTOP_INSTRUCTIONS.md. That's it: Claude now has persistent memory and knows when to use it.
Other Platforms
Connect your AI tools to the AutoMem service you just started.
# Guided install - pick where AutoMem runs, verify it, write .env, and
# configure your agents (Codex, Claude Code, Cursor, OpenClaw, Hermes)
npx @verygoodplugins/mcp-automem installEvery change is shown in a review plan before anything is written, and each
modified file keeps a .bak backup. Add --dry-run to preview, --yes to
apply non-interactively. See the Installation Guide
for all flags.
Just need the .env + config snippets without the agent setup? Use the lighter wizard:
# Creates .env and prints config for your AI platform
npx @verygoodplugins/mcp-automem setupWhen prompted:
AutoMem Endpoint:
http://localhost:8001(or your Railway URL if deployed)API Key: Leave blank for local development (or paste your token for Railway)
The wizard will:
ā Save your endpoint and API key to
.envā Generate config snippets for Claude Desktop/Cursor/Code
ā Validate connection to your AutoMem service
3. Platform-Specific Setup
For Claude Code (plugin ā recommended):
# In Claude Code:
/plugin marketplace add verygoodplugins/mcp-automem
/plugin install automem@verygoodplugins-mcp-automemClaude Code prompts for your AutoMem URL and API key at enable time, bundles the MCP server and silent recall/store-tracking hooks, and auto-updates. Prefer hooks and permissions written directly into ~/.claude/ instead? Run npx @verygoodplugins/mcp-automem claude-code.
On Windows, the hook payload assumes a POSIX shell environment such as Git Bash, MSYS2, or WSL ā only bash is required (the hooks are pure bash+sed).
For Cursor IDE:
# Or use CLI to install automem.mdc rule file
npx @verygoodplugins/mcp-automem cursorOther platforms ā Claude Desktop (one-click .mcpb above, plus the Personal Preferences template), OpenAI Codex, Hermes Agent, Grok Build, OpenClaw, Google Antigravity, and GitHub Copilot:
š Full Installation Guide for every platform's setup and verification steps
Remote MCP via HTTP
An optional sidecar service (deployable to Railway or any Docker host) connects AutoMem to platforms that support remote MCP over Streamable HTTP or SSE ā ChatGPT (Developer Mode connectors), Claude.ai web and Claude Mobile, and ElevenLabs Agents.
š Remote MCP setup for deployment, connect URLs, and per-platform screenshots.
Architecture
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Your AI Platforms ā
ā Claude Desktop ā Cursor ā Claude Code ā
āāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā MCP Protocol
ā¼
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā @verygoodplugins/mcp-automem (this repo) ā
ā ⢠Translates MCP calls ā AutoMem API ā
ā ⢠Platform integrations & rules ā
ā ⢠Handles authentication ā
āāāāāāāāāāāāāāāā¬āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā HTTP API
ā¼
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā AutoMem Service (separate repo) ā
ā github.com/verygoodplugins/automem ā
ā āāāāāāāāāāāāāā āāāāāāāāāāāāāā ā
ā ā FalkorDB ā ā Qdrant ā ā
ā ā (Graph) ā ā (Vectors) ā ā
ā āāāāāāāāāāāāāā āāāāāāāāāāāāāā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāThis repo (mcp-automem):
MCP client that connects AI platforms to AutoMem
Platform-specific integrations (Cursor rules, Claude Code hooks, etc.)
Setup wizards and configuration tools
Backend memory service with graph + vector storage
Deployment guides (local, Railway, Docker, production)
API server with FalkorDB + Qdrant
Features
Core Memory Operations
store_memoryā Save memories with content, tags, importance, metadata. Two modes:Single (default): top-level
contentplus optional fields, includingembedding,t_valid,t_invalid, customid.Batch:
memories: [...](ā¤500 items) for bulk ingestion. Per-itemid/embedding/t_valid/t_invalidare not supported in batch mode.
recall_memoryā Three modes selected by which params you pass:ID fetch:
memory_idā fetches one memory by ID; updateslast_accessed.Tag enumeration:
tags+exhaustive: trueā paginated exact-match listing for cleanup/audit workflows where ranked recall undercounts. Pair withlimit(ā¤200) andoffset; returnshas_more.Ranked retrieval (default): hybrid search across vector, keyword, tags, recency/state controls, score filters, and graph expansion. Supports
state_mode,recency_bias,scope_fallback,expand_respect_tags,min_score,adaptive_floor, and diagnostics such astag_scope,score_filter,query_time_ms,vector_search, and per-resultoutside_tag_scope/state_replaces.
associate_memoriesā Create relationships (11 public authorable types; recall results may also include read-only system relations). Supports single-pair mode and batch mode viaassociations: [...](ā¤500) with relation-specific props likereason,context,resolution,observations,transformation, androle.update_memoryā Modify existing memoriesdelete_memoryā Two modes:Single (default):
memory_idā removes one memory and its embedding.Bulk-by-tag:
tags: [...]ā bulk-delete all memories matching ANY tag (exact, case-insensitive). No dry-run; verify withrecall_memory({ tags, exhaustive: true })first.
check_database_healthā Monitor service health, degraded state, sync counts, vector dimensions, and enrichment diagnostics when the service provides them
Advanced Recall (v0.8.0+)
Multi-hop Reasoning - Answer complex questions like "What is Amanda's sister's career?"
mcp__memory__recall_memory({
query: "What is Amanda's sister's career?",
expand_entities: true, // Finds "Amanda's sister is Rachel" ā memories about Rachel
});Context-Aware Coding - Recall prioritizes language and style preferences
mcp__memory__recall_memory({
query: "error handling patterns",
language: "typescript",
context_types: ["Style", "Pattern"],
});Platform Integrations
Cursor IDE
ā Memory-first rule file (
automem.mdcin.cursor/rules/)ā Automatic memory recall at conversation start
ā Auto-detects project context (package.json, git remote)
ā Global user rules option for all projects
ā Simple setup via CLI or one-click install
Claude Code
ā Native plugin - MCP server, silent hooks, and skill in one
/plugin install, with enable-time config prompts and auto-updatesā LLM-judged storage - session-start guidance nudges Claude to store, verify, and associate durable memories during normal work
ā Memory rules in CLAUDE.md guide Claude's memory usage
GitHub Copilot
ā Standalone hook JSON files installed into
$COPILOT_HOME/hooks/or~/.copilot/hooks/ā Memory rules template for
copilot-instructions.mdā Format flag -
--format cli(camelCase) or--format vscode(PascalCase)ā Setup:
npx @verygoodplugins/mcp-automem copilot --yes
Claude Desktop
ā Direct MCP integration
ā Paste-ready Personal Preferences starter template
ā Full memory API access
Why AutoMem MCP?
vs. Building Your Own
ā 2 years of R&D already done
ā Research-validated architecture (HippoRAG 2, MELODI, A-MEM)
ā Working integrations across all MCP platforms
ā Active development and community
vs. Other Memory Solutions
ā True graph relationships (not just vector similarity)
ā Universal MCP compatibility (works with any MCP client)
ā 7 memory types (Decision/Pattern/Preference/Style/Habit/Insight/Context)
ā Self-hostable ($5/month vs $150+ for alternatives)
vs. Native AI Memory
ā Persistent across sessions (not just context window)
ā Cross-platform (same memory in Claude, Cursor, Code)
ā Structured relationships (not just RAG)
ā Infinite scale (no context window limits)
Documentation
MCP Client & Integrations (this repo)
š¦ Installation Guide - MCP client setup for all platforms
š Remote MCP via HTTP - Connect ChatGPT, Claude Web/Mobile, ElevenLabs
šÆ Cursor Setup - IDE integration with rules
š¤ Claude Code Setup - Plugin install, hooks, and memory rules
ā ļø Deprecations - History of the plugin deprecation and its reversal
š OpenAI Codex Setup - Codex CLI/IDE/Cloud integration
šŖ Google Antigravity Setup - Raw MCP config via Antigravity's MCP Store
š MCP Tools Reference - All memory operations
š Changelog - Release history
AutoMem Service (separate repo)
šļø AutoMem Service - Backend repository
š Service Installation - Local, Railway, Docker deployment
āļø API Documentation - REST API reference
š§Ŗ Evaluation Lab - Exploratory recall-quality benchmarks and ruleset A/B testing
The Science Behind AutoMem
The AutoMem service implements cutting-edge 2025 research:
HippoRAG 2 (OSU, June 2025): Graph-vector approach achieves 7% better associative memory
A-MEM (July 2025): Dynamic memory organization with Zettelkasten principles
MELODI (DeepMind, 2025): 8x memory compression without quality loss
ReadAgent (DeepMind, 2024): 20x context extension through gist memories
This MCP package provides the bridge between your AI and that research-validated memory system. The backend has also been benchmarked on the neutral Agent Memory Benchmark, including BEAM large-context scaling tiers ā reproducible end to end, so you can run it yourself.
Community & Support
š¬ Discord - Join the community, get help, share feedback
š¦ X Community - Discussion and updates
š£ @automem_ai - Official announcements
š¦ NPM Package - This MCP client
š¬ AutoMem Service - Backend repo with deployment guides
š GitHub Issues - Bug reports and feature requests
Contributing
We welcome contributions! Please:
Fork the repository
Create a feature branch
Make your changes with tests
Submit a pull request with a Conventional Commit title such as
fix:,feat:,docs:, orchore:Do not prefix the PR title with labels like
[codex]or[wip]because the squash-merge commit is taken from the PR title
License
MIT - Because great memory should be free.
Ready to give your AI perfect memory?
npx @verygoodplugins/mcp-automem setupBuilt with obsession. Validated by neuroscience. Powered by graph theory. Works with every MCP-enabled AI.
Designed by Jack Arturo at Very Good Plugins š§”
Transform your AI from a tool into a teammate. Start now.
Available Tools
6 toolsassociate_memoriesAssociate MemoriesAIdempotent
Create typed relationships between memories. This builds a knowledge graph that improves recall by surfacing related context. Supports single-pair mode or batch mode with associations[] (max 500).
When to use:
After storing a new memory: link it to related existing memories
When a bug fix relates to an original feature implementation
When a new decision updates or invalidates a previous one
To connect patterns with their concrete examples
Authorable relationship types:
RELATES_TO: General relationship (default)
LEADS_TO: Causal relationship (A caused B)
OCCURRED_BEFORE: Temporal ordering
PREFERS_OVER: Chosen alternative
EXEMPLIFIES: Concrete example of a pattern
CONTRADICTS: Conflicts with another memory
REINFORCES: Strengthens another memory's validity
INVALIDATED_BY: Superseded by another memory
EVOLVED_INTO: Updated version of a concept
DERIVED_FROM: Implementation of a decision/pattern
PART_OF: Component of a larger effort
Read-only/internal relations:
System/internal relations such as SIMILAR_TO, PRECEDED_BY, EXPLAINS, SHARES_THEME, PARALLEL_CONTEXT, and DISCOVERED may appear in recall results, but they are not valid inputs for associate_memories.
Examples:
associate_memories({ memory1_id: "bug-fix-123", memory2_id: "feature-456", type: "RELATES_TO", strength: 0.9 })
associate_memories({ memory1_id: "new-decision", memory2_id: "old-decision", type: "EVOLVED_INTO", strength: 0.8 })
associate_memories({ associations: [{ memory1_id: "a", memory2_id: "b", type: "RELATES_TO", strength: 0.8 }] })
| Name | Required | Description | Default |
|---|---|---|---|
| role | No | Relation-specific role for PART_OF associations. | |
| type | No | Relationship type between the two memories | |
| reason | No | Relation-specific reason for PREFERS_OVER, CONTRADICTS, INVALIDATED_BY, or EVOLVED_INTO associations. | |
| context | No | Relation-specific context for PREFERS_OVER or PART_OF associations. | |
| strength | No | Relationship strength: 0.9+ direct causation, 0.7-0.9 strong relation, 0.5-0.7 moderate | |
| timestamp | No | Relation-specific timestamp for INVALIDATED_BY associations. | |
| confidence | No | Relation-specific confidence for EXEMPLIFIES, EVOLVED_INTO, or DERIVED_FROM. | |
| memory1_id | No | ID of the source memory (from store_memory response or recall results) | |
| memory2_id | No | ID of the target memory to link to | |
| resolution | No | Relation-specific resolution for CONTRADICTS associations. | |
| associations | No | Batch mode. Up to 500 associations. Do not combine with top-level memory1_id/memory2_id/type/strength. | |
| observations | No | Relation-specific observations for REINFORCES associations. | |
| pattern_type | No | Relation-specific pattern label for EXEMPLIFIES associations. | |
| transformation | No | Relation-specific transformation note for DERIVED_FROM associations. |
Output Schema
| Name | Required | Description |
|---|---|---|
| failed | No | Batch mode: failed association records with errors. |
| message | Yes | Confirmation message |
| success | Yes | Whether every requested association was created. False for partial batch responses. |
| summary | No | Batch mode: service summary. |
| succeeded | No | Batch mode: successful association records. |
| failed_count | No | Batch mode: number of associations that failed. |
| created_count | No | Batch mode: number of associations created. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=false, idempotentHint=true, destructiveHint=false, which describe the tool as non-destructive and idempotent. The description adds that batch mode supports up to 500 associations, lists valid authorable relationship types, and notes that internal relation types appear in recall but are not valid inputs. This provides rich behavioral context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: overview, when-to-use, relationship types list, examples. It uses bullet points for readability and avoids unnecessary repetition. Every sentence serves a purpose, and the length is appropriate for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (14 parameters, batch mode, many relationship types), the description covers all key aspects: purpose, usage scenarios, relationship type explanations, batch mode limits, and examples. The presence of an output schema means return values don't need to be described. The description is fully adequate for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% (all parameters have descriptions in the schema). The description adds value by explaining which parameters are relation-specific (e.g., reason for PREFERS_OVER, confidence for EXEMPLIFIES) and by listing relationship types with meanings. The examples also illustrate parameter usage. Overall, the description enhances understanding beyond the schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'creates typed relationships between memories' and explains it improves recall via a knowledge graph. This distinguishes it from sibling tools like store_memory (store a single memory) and recall_memory (retrieve memories).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes a 'When to use' section with specific scenarios (e.g., after storing a new memory, when a bug fix relates to a feature). It also distinguishes between single-pair and batch mode, and clarifies which relationship types are not valid inputs. However, it does not explicitly state when not to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_database_healthCheck Database HealthARead-onlyIdempotent
Check the health status of the AutoMem service and its connected databases (FalkorDB graph + Qdrant vectors).
When to use:
Before a session to verify the memory service is available
When memory operations are failing unexpectedly
To check storage statistics
Example:
check_database_health({})
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| error | No | Error message if status is error |
| status | Yes | Overall health status. degraded means the service is reachable but a backend or sync check needs attention. |
| backend | Yes | Backend type (automem) |
| statistics | No | Database statistics and diagnostics, including memory/vector counts, sync_status, vector_dimensions, and enrichment state when provided. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint false. Description adds value by specifying the components checked (FalkorDB graph + Qdrant vectors) and the service context (AutoMem). No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise: one-line purpose, bulleted use cases, and example. Every sentence adds value. Front-loaded with key information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters and the presence of an output schema, the description is complete. It covers purpose, usage guidance, and provides an example. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters (0 params, baseline 4). Schema coverage is 100%, so description does not need to compensate. The description effectively explains the tool's purpose without needing parameter details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states verb+resource: 'check the health status of the AutoMem service and its connected databases'. Differentiates from sibling tools like store_memory and recall_memory which are CRUD operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-to-use scenarios: before a session, when memory operations fail, and to check statistics. Does not mention when not to use or alternatives, but sibling differentiation makes it clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_memoryDelete MemoryADestructive
Delete a memory by ID (memory_id) or bulk-delete by tag (tags). Use sparingly ā consider update_memory instead.
Mode 1 ā Single (default): pass memory_id to delete one memory and its embedding. Idempotent: re-running on the same ID is a no-op.
Mode 2 ā Bulk-by-tag: pass tags: [...] to delete ALL memories tagged with ANY of these tags. Tag matching is exact (case-insensitive), any-of mode. There is NO dry-run. This can delete thousands of memories in one call. NOT idempotent in practice ā re-running may catch new memories that were tagged the same way after the first call. Verify with recall_memory({ tags, exhaustive: true }) first if uncertain.
When to use:
Memory contains incorrect information that can't be corrected (Mode 1)
Memory is a duplicate (Mode 1)
Cleanup of benchmark/test data scoped by tag (Mode 2)
Removing all memories under a deprecated tag namespace (Mode 2)
Examples:
delete_memory({ memory_id: "abc123" }) // Mode 1
delete_memory({ tags: ["benchmark-test"] }) // Mode 2, bulk by tag
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Bulk-delete mode (XOR with `memory_id`). Bulk-deletes ALL memories tagged with ANY of these tags. Exact match, case-insensitive. No dry-run. | |
| memory_id | No | Single-delete mode (XOR with `tags`). ID of the memory to delete (from store_memory or recall results). |
Output Schema
| Name | Required | Description |
|---|---|---|
| tags | No | Bulk-delete result: tags that were used for the bulk delete. |
| message | Yes | Confirmation message |
| memory_id | No | Single-delete result: ID of the deleted memory. |
| deleted_count | No | Bulk-delete result: number of memories deleted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Disclosures beyond annotations: idempotent for single mode, not idempotent for bulk, exact case-insensitive tag matching, no dry-run, potential for mass deletion. No contradiction with annotations indicating destructive and non-idempotent behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with headings, bullet points, and examples. Information is presented efficiently and front-loaded with core action, making it easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With output schema present and parameters fully described, the description covers all essential aspects: modes, usage context, safety warnings, and verification steps. No important gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but description adds XOR relationship, mode differentiation, exact tag matching details, and no-dry-run warning. This significantly enhances understanding beyond schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool deletes memories by ID or bulk by tag, specifying two modes with distinct behaviors. It differentiates from sibling tools like update_memory, providing a precise action and resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly advises to use sparingly and consider update_memory instead, and provides specific scenarios for each mode, including verification steps for bulk deletion. This gives clear when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recall_memoryRecall MemoryARead-onlyIdempotent
Recall memories from AutoMem in one of three modes. The mode is selected by which params you pass.
Mode 1 ā ID fetch: pass memory_id to retrieve a single memory by ID. All other params are ignored. Routes to GET /memory/{id} and updates last_accessed.
Mode 2 ā Tag enumeration: pass tags + exhaustive: true for paginated exact-match listing (NOT ranked retrieval). Use this for cleanup/audit workflows where ranked retrieval silently undercounts large tag sets. Pair with limit (ā¤200) and offset. Returns has_more/limit/offset page metadata. Tag matching is exact, case-insensitive, any-of mode ā tag_match: "prefix" and tag_mode: "all" are rejected in this mode.
Mode 3 ā Ranked retrieval (default): hybrid search across vector, keyword, tags, recency, and optional graph expansion. The primary tool for finding relevant context. By default, ranked recall requests current active memories only; set current_only: false for audits.
When to use ranked (mode 3):
At conversation start: recall context about the current project/topic
Before making decisions: check for past decisions on similar topics
When debugging: search for similar past errors and their solutions
For complex questions: use
expand_entitiesfor multi-hop reasoning
When to use enumeration (mode 2): when you need to know how many memories carry a tag, or to walk all of them for cleanup/migration. Ranked recall ignores low-importance hits ā enumeration does not.
Examples:
recall_memory({ query: "database architecture decisions", tags: ["my-project"], limit: 5 })
recall_memory({ memory_id: "abc123" }) // Mode 1
recall_memory({ tags: ["benchmark-test"], exhaustive: true, limit: 50 }) // Mode 2 (add offset for later pages)
recall_memory({ query: "auth", exclude_tags: ["deprecated"] }) // Mode 3 with exclusion
recall_memory({ query: "What is Sarah's sister's job?", expand_entities: true }) // Mode 3 multi-hop
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | ISO timestamp upper bound | |
| sort | No | Result ordering (use time_* for chronological recaps) | |
| tags | No | Filter by tags. Use project name as first tag for scoping. | |
| limit | No | Max memories to return. Schema allows 1ā200; in enumeration mode (`exhaustive: true`) the server honors up to 200, while ranked mode is typically clamped server-side to ~50. Default 5. | |
| query | No | Semantic search query (natural language). Describe what you're looking for. | |
| start | No | ISO timestamp lower bound (alternative to time_query) | |
| format | No | Output format: text (default), items (one block per memory), detailed (adds type/confidence/metadata keys/relation stubs), json (raw per-memory fields incl. full content/metadata/relations; whole-response token budget still applies). text/items/detailed show a content preview (default 400 chars) and keep any stored summary as an additive field ā fetch a full record via memory_id. | text |
| offset | No | Result offset for pagination | |
| context | No | Context label (e.g., "coding-style", "architecture"). Boosts matching preferences. | |
| queries | No | Multiple queries for broader recall. Results are deduplicated server-side. | |
| language | No | Programming language hint (e.g., "python", "typescript"). Prioritizes language-specific memories. | |
| tag_mode | No | "any" matches memories with any tag (default), "all" requires all tags | |
| embedding | No | Optional embedding vector for direct similarity search | |
| memory_id | No | MODE: ID fetch. When set, fetches the single memory by ID and IGNORES all other params. Routes to GET /memory/{id}; updates last_accessed. | |
| min_score | No | Ranked-mode only. Minimum final score threshold before results are returned. | |
| tag_match | No | "exact" for exact tag match (default), "prefix" for starts-with matching | |
| exhaustive | No | MODE: tag enumeration. When true, requires non-empty `tags`. Routes to GET /memory/by-tag for paginated exact-match listing ā NOT ranked retrieval. Use for cleanup/audit workflows where ranked recall undercounts. `limit` is clamped to 200. `tag_match: "prefix"` and `tag_mode: "all"` are rejected in this mode. | |
| state_mode | No | Ranked-mode only. `current` returns active memories; `history` allows superseded/invalidated memories for audit timelines. Prefer this over current_only for new clients. | |
| time_query | No | Natural language time filter: "today", "yesterday", "last week", "last 30 days" | |
| active_path | No | Current file path for language auto-detection (e.g., "src/auth.ts") | |
| state_debug | No | Ranked-mode only. Include state-filter suppression/replacement IDs and reasons when current_only is true. | |
| context_tags | No | Priority tags to boost in results (e.g., ["coding-style", "preferences"]) | |
| current_only | No | Ranked-mode only. When true, server suppresses archived, not-yet-valid, expired, invalidated, or superseded memories from active context. | |
| exclude_tags | No | Ranked-mode only. Tags to exclude from results (any match excludes). Independent of `tag_match` ā supports both exact and prefix matching internally on the server. | |
| priority_ids | No | Specific memory IDs to ensure are included in results | |
| recency_bias | No | Ranked-mode only. Controls service recency boosting: auto lets the service infer, on forces boosting, off disables it. | |
| context_types | No | Priority memory types to boost (e.g., ["Style", "Preference"]) | |
| adaptive_floor | No | Ranked-mode only. Enable the service's adaptive score floor when filtering weak matches. | |
| auto_decompose | No | Auto-extract entities and topics from query to generate supplementary searches. | |
| relation_limit | No | Max relations to follow per seed memory (default: 5) | |
| scope_fallback | No | Ranked-mode only. Allow fallback outside the requested tag scope when scoped recall has weak evidence; diagnostics report tag_scope and outside_tag_scope. | |
| expand_entities | No | Enable multi-hop reasoning via entity expansion. Finds memories about people/places mentioned in seed results. Use for "What is X's sister's job?" type questions. | |
| expansion_limit | No | Max total expanded memories (default: 25) | |
| per_query_limit | No | Per-query result limit when using queries[] (default: 5) | |
| expand_relations | No | Follow graph relationships from seed results to find related memories. | |
| expand_min_strength | No | Minimum relation strength to follow during graph expansion. Only traverses edges above this threshold. Recommended: 0.3 for exploratory, 0.6+ for high-confidence connections only. Does not affect entity expansion. | |
| expand_respect_tags | No | Ranked-mode only. When true, graph/entity expansion stays within the original tag scope; when false, expansion may include related context outside the tags. | |
| expand_min_importance | No | Minimum importance score for expanded results. Filters out low-relevance memories during graph/entity expansion. Recommended: 0.3-0.5 for broad context, 0.6-0.8 for focused results. Seed results are never filtered, only expanded ones. |
Output Schema
| Name | Required | Description |
|---|---|---|
| mode | No | Mode that produced the result. |
| sort | No | Sort mode applied by the service. |
| count | Yes | Number of memories returned |
| limit | No | Enumeration mode only: page size used for this response. |
| query | No | Query text executed by ranked recall. |
| offset | No | Enumeration mode only: offset used for this response. |
| queries | No | Query variants executed by the service. |
| results | Yes | Array of matching memories with scores |
| entities | No | Entity identity diagnostics injected by the service. |
| has_more | No | Enumeration mode only: true if more pages exist past `offset + limit`. |
| tag_scope | No | Tag-scope diagnostics including whether scoped evidence was strong enough. |
| state_mode | No | State mode applied by ranked recall. |
| truncation | No | Present when trailing results were dropped to fit the response budget: { applied, omitted_results, reason }. |
| exclude_tags | No | Tags excluded from ranked recall. |
| recency_bias | No | Recency bias mode applied by the service. |
| score_filter | No | Score filtering diagnostics such as min_score, adaptive_floor, and filtered_count. |
| state_filter | No | Current-state filtering diagnostics. Includes aggregate counts by default and detailed IDs/reasons only when state_debug=true. |
| dedup_removed | No | Number of duplicate results removed (when using multiple queries) |
| query_time_ms | No | Service recall latency in milliseconds. |
| vector_search | No | Vector-search diagnostics from the service. |
| scope_fallback | No | True when recall allowed outside-scope fallback results. |
| jit_enriched_count | No | Number of memories enriched inline during recall. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, and the description adds valuable behavioral detail beyond that: ID fetch routes to GET /memory/{id} and updates last_accessed, enumeration uses paginated exact-match listing, ranked mode clamps server-side to ~50 results, and mode-specific options are rejected. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but appropriately structured for a tool with 38 parameters and three modes: it front-loads the mode-selection rule, uses clear headers, gives explicit when-to-use bullets, and ends with examples. Minor redundancy exists, such as repeating the cleanup/audit rationale in both Mode 2 and the usage section, but the overall organization is efficient for the complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 38 parameters, a rich schema, and an output schema, the description covers the decision space comprehensively: it explains all three modes, which params are ignored or rejected, pagination metadata, output format options, and when each mode is appropriate. The examples cover representative calls for each mode, and nothing critical for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3; the description still adds value by explaining how parameters select modes, how limit behaves differently in enumeration vs ranked mode, and by showing realistic parameter combinations in examples. It does not need to restate every schema field, and the mode-selection semantics go beyond what the schema alone conveys.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool recalls memories from AutoMem and immediately differentiates three distinct modes based on which parameters are passed. It names each mode, the route it uses, and the outcome, and provides concrete examples for every mode, so an agent cannot confuse this with sibling tools like store_memory or delete_memory.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: ranked retrieval for conversation start, decision-making, debugging, and multi-hop reasoning; tag enumeration when the agent needs exact counts or cleanup/audit walks. It also states exclusions such as 'NOT ranked retrieval' and which parameter combinations are rejected, leaving no ambiguity about mode selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
store_memoryStore MemoryA
Store memory in one of two modes ā single-memory (set top-level content) or batch (set memories: [...] for up to 500).
Mode 1 ā Single (default): pass top-level content plus any optional fields (tags, importance, metadata, type, confidence, embedding, t_valid, t_invalid, etc.).
Mode 1b ā Supersede/correct: pass top-level content plus supersedes_memory_id. The server stores the replacement, marks the old memory invalid with t_invalid=now, merges supersede metadata, and associates old ā new with INVALIDATED_BY (default) or EVOLVED_INTO.
Mode 2 ā Batch: pass memories: [{ content, tags?, importance?, metadata?, timestamp?, type?, confidence? }, ...] to store up to 500 memories in one request. Faster for bulk ingestion (imports, benchmark seeding). Batch mode does NOT accept embedding, t_valid, or t_invalid per-item ā use single mode for those.
Content size guidelines (per item):
Target: 150-300 characters (one meaningful paragraph)
Maximum: 500 characters (auto-summarized if exceeded)
Hard limit: 2000 characters (rejected)
Format: "Brief title. Context and details. Impact/outcome."
When to use:
After making a decision: store the reasoning and outcome
When discovering a pattern: store the pattern and where it applies
After fixing a bug: store the root cause and solution
When learning user preferences: store what they prefer and why
For bulk ingestion (imports, seeding): use batch mode
Examples:
store_memory({ content: "Chose PostgreSQL over MongoDB for user service. Need ACID for transactions.", tags: ["architecture", "database"], importance: 0.9 })
store_memory({ content: "User prefers early returns over nested conditionals.", tags: ["code-style"], importance: 0.7 })
store_memory({ content: "User now prefers SQLite for small local tools.", supersedes_memory_id: "old-id", supersede_reason: "Correction from user" })
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | Single-memory mode. Tags to categorize the memory (e.g., ["project-name", "bug-fix", "auth"]) | |
| type | No | Single-memory mode. Memory type for classification | |
| content | No | Single-memory mode (XOR with `memories`). The memory content to store. Be specific: include context, reasoning, and outcome. | |
| t_valid | No | Single-memory mode only. ISO 8601 timestamp when the memory becomes valid. Not supported in batch mode. | |
| memories | No | Batch mode (XOR with `content`). Up to 500 memory objects to store in one call. Each item supports content (required), tags, importance, timestamp, type, confidence, metadata. Batch mode does NOT support `embedding`, `t_valid`, or `t_invalid` per-item ā use single-memory mode for those. | |
| metadata | No | Single-memory mode. Optional structured metadata (e.g., { files_modified: ["auth.ts"], error_type: "timeout" }) | |
| embedding | No | Single-memory mode only. Optional embedding vector for semantic search (auto-generated if omitted). Not supported in batch mode. | |
| t_invalid | No | Single-memory mode only. ISO 8601 timestamp when the memory expires. Not supported in batch mode. | |
| timestamp | No | Single-memory mode. Optional ISO timestamp (defaults to now) | |
| confidence | No | Single-memory mode. Classification confidence (0-1, default 0.9 when type provided) | |
| importance | No | Single-memory mode. Importance: 0.9+ critical decisions, 0.7-0.9 patterns/bugs, 0.5-0.7 minor notes | |
| updated_at | No | Single-memory mode. ISO 8601 last-updated timestamp | |
| last_accessed | No | Single-memory mode. ISO 8601 last-accessed timestamp | |
| supersede_reason | No | Single-memory supersede mode. Optional reason stored on the old memory's metadata. | |
| supersede_relation | No | Single-memory supersede mode. Relationship to create from old memory to new memory. | INVALIDATED_BY |
| supersedes_memory_id | No | Single-memory supersede mode. Existing memory ID that this new memory replaces or corrects. |
Output Schema
| Name | Required | Description |
|---|---|---|
| qdrant | No | Batch-mode result: Qdrant indexing summary from the server. |
| stored | No | Batch-mode result: number of memories stored. |
| message | Yes | Confirmation message |
| memory_id | No | Single-mode result: unique ID of the stored memory (use for associations) |
| enrichment | No | Batch-mode result: enrichment status from the server. |
| memory_ids | No | Batch-mode result: IDs of the stored memories. |
| query_time_ms | No | Batch-mode result: server-reported execution time in milliseconds. |
| association_created | No | Supersede-mode result: whether old ā new association was created. |
| superseded_memory_id | No | Supersede-mode result: ID of the old memory marked invalid. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals substantial non-obvious behavior: supersede invalidates the old memory, sets t_invalid=now, merges metadata, and links old-to-new via INVALIDATED_BY/EVOLVED_INTO. It also discloses size limits, auto-summarization over 500 characters, rejection over 2000, and batch-mode field exclusionsāall beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but earned: it is organized into modes, size guidelines, when-to-use, and examples, making it scannable despite its length. The most important distinction (single vs batch) is front-loaded, and every section adds reusable decision value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a 16-parameter tool with nested objects, three behavioral modes, and multiple constraints, the description is remarkably complete. It covers entry points, per-parameter limitations, workflow patterns, content quality guidance, and representative examples. The presence of an output schema reduces the need to document return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds meaning the schema alone does not convey: mutual exclusivity of content vs memories is explained with mode-based grouping, content size targets are given, supersede parameter behavior is clarified, and three realistic examples show how parameters combine.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The verb 'store' plus 'memory' and the explicit description of two operating modes (single and batch) make the purpose unmistakable. The supersede/correct mode is also described with concrete behavior, distinguishing it from a plain append operation even without naming siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
A dedicated 'When to use' section lists concrete scenarios, and batch mode is specifically recommended for bulk ingestion. However, it never explicitly contrasts this tool with update_memory or delete_memory, so the guidance is clear but lacks exclusions/alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_memoryUpdate MemoryAIdempotent
Update an existing memory's content, tags, importance, or metadata. Use this to correct or enhance memories rather than storing duplicates.
When to use:
To correct inaccurate information in a memory
To add tags that were forgotten
To adjust importance based on new understanding
To add metadata after the fact
Examples:
update_memory({ memory_id: "abc123", importance: 0.95 }) // Increase importance
update_memory({ memory_id: "abc123", tags: ["project-x", "critical", "auth"] }) // Add tags
update_memory({ memory_id: "abc123", content: "Updated: PostgreSQL chosen for ACID + team expertise" })
| Name | Required | Description | Default |
|---|---|---|---|
| tags | No | New tags (replaces existing) | |
| type | No | Memory type classification | |
| content | No | New content (replaces existing) | |
| t_valid | No | ISO 8601 timestamp when the memory becomes valid | |
| metadata | No | New metadata (merged with existing) | |
| memory_id | Yes | ID of the memory to update (from store_memory or recall results) | |
| t_invalid | No | ISO 8601 timestamp when the memory expires or was superseded | |
| timestamp | No | Override creation timestamp | |
| confidence | No | Confidence score for the memory | |
| importance | No | New importance score | |
| updated_at | No | Explicit update timestamp | |
| last_accessed | No | Last access timestamp |
Output Schema
| Name | Required | Description |
|---|---|---|
| message | Yes | Confirmation message |
| memory_id | Yes | ID of the updated memory |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate idempotentHint=true and destructiveHint=false, which the description does not contradict. The description adds context about 'correct or enhance' but does not detail update semantics like overwriting vs merging (e.g., metadata merges per schema). Since annotations cover the core behavioral traits, the description provides moderate added value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear header, a bulleted 'When to use' list, and examples. It is concise (5 sentences plus examples) and front-loaded. Slightly more could be trimmed but overall efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 12 parameters (all documented in schema), an output schema exists, and annotations are present, the description provides sufficient context for the main purpose and use cases. It lacks error behavior details but these are not critical given the schema coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add additional meaning beyond the schema; it only groups parameters in the first sentence. Examples illustrate some parameters but no new semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Update' and the resource 'memory', and lists the updateable fields (content, tags, importance, metadata). It distinguishes from the sibling tool 'store_memory' by advising against storing duplicates.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'When to use' section provides four explicit use cases (correct inaccuracies, add tags, adjust importance, add metadata) and implicitly advises against using store_memory for updates. However, it does not mention when not to use this tool (e.g., if memory should be deleted entirely) or prerequisites (e.g., memory must exist).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.14.2- Changed
recall_memory4 fields changed- changed
Input schema / properties / format / descriptionPrevious value: -"Output format: text (default), items (one block per memory), detailed (adds type/confidence/metadata keys/relation stubs), json (raw per-memory fields incl. full content/metadata/relations; whole-response token budget still applies). text/items/detailed are summary-first: each memory shows its stored 1-2 sentence summary when available, else a content preview ā fetch a full record via memory_id."New value: +"Output format: text (default), items (one block per memory), detailed (adds type/confidence/metadata keys/relation stubs), json (raw per-memory fields incl. full content/metadata/relations; whole-response token budget still applies). text/items/detailed show a content preview (default 400 chars) and keep any stored summary as an additive field ā fetch a full record via memory_id." - changed
Output schema / properties / results / items / properties / content / descriptionPrevious value: -"Memory content (preview in budgeted formats; omitted when summary is shown)."New value: +"Memory content (preview-capped in budgeted formats)." - changed
Output schema / properties / results / items / properties / content_chars / descriptionPrevious value: -"Original content length when content was previewed or replaced by summary."New value: +"Original content length when content was previewed." - changed
Output schema / properties / results / items / properties / summary / descriptionPrevious value: -"Stored 1-2 sentence summary. In budgeted formats it replaces content when present."New value: +"Stored 1-2 sentence summary when the server provides one. Additive in budgeted formats; does not replace content."
- Changed
store_memory2 fields changed- removed
Input schema / properties / idRemoved value: -{ - "description": "Single-memory mode only. Custom memory ID (auto-generated if omitted). Not supported in batch mode.", - "type": "string" -} - changed
Input schema / properties / memories / descriptionPrevious value: -"Batch mode (XOR with `content`). Up to 500 memory objects to store in one call. Each item supports content (required), tags, importance, timestamp, type, confidence, metadata. Batch mode does NOT support `id`, `embedding`, `t_valid`, or `t_invalid` per-item ā use single-memory mode for those."New value: +"Batch mode (XOR with `content`). Up to 500 memory objects to store in one call. Each item supports content (required), tags, importance, timestamp, type, confidence, metadata. Batch mode does NOT support `embedding`, `t_valid`, or `t_invalid` per-item ā use single-memory mode for those."
5 tool updates
v0.14.1- Changed
associate_memories17 fields changed- added
Input schema / properties / associationsAdded value: +{ + "description": "Batch mode. Up to 500 associations. Do not combine with top-level memory1_id/memory2_id/type/strength.", + "items": { + "properties": { + "confidence": { + "description": "Relation-specific confidence for EXEMPLIFIES, EVOLVED_INTO, or DERIVED_FROM.", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "context": { + "description": "Relation-specific context for PREFERS_OVER or PART_OF associations.", + "type": "string" + }, + "memory1_id": { + "description": "ID of the source memory", + "type": "string" + }, + "memory2_id": { + "description": "ID of the target memory", + "type": "string" + }, + "observations": { + "description": "Relation-specific observations for REINFORCES associations.", + "items": { + "type": "string" + }, + "type": "array" + }, + "pattern_type": { + "description": "Relation-specific pattern label for EXEMPLIFIES associations.", + "type": "string" + }, + "reason": { + "description": "Relation-specific reason for PREFERS_OVER, CONTRADICTS, INVALIDATED_BY, or EVOLVED_INTO associations.", + "type": "string" + }, + "resolution": { + "description": "Relation-specific resolution for CONTRADICTS associations.", + "type": "string" + }, + "role": { + "description": "Relation-specific role for PART_OF associations.", + "type": "string" + }, + "strength": { + "description": "Relationship strength from 0 to 1", + "maximum": 1, + "minimum": 0, + "type": "number" + }, + "timestamp": { + "description": "Relation-specific timestamp for INVALIDATED_BY associations.", + "type": "string" + }, + "transformation": { + "description": "Relation-specific transformation note for DERIVED_FROM associations.", + "type": "string" + }, + "type": { + "description": "Relationship type between the two memories", + "enum": [ + "RELATES_TO", + "LEADS_TO", + "OCCURRED_BEFORE", + "PREFERS_OVER", + "EXEMPLIFIES", + "CONTRADICTS", + "REINFORCES", + "INVALIDATED_BY", + "EVOLVED_INTO", + "DERIVED_FROM", + "PART_OF" + ], + "type": "string" + } + }, + "required": [ + "memory1_id", + "memory2_id", + "type", + "strength" + ], + "type": "object" + }, + "maxItems": 500, + "minItems": 1, + "type": "array" +} - added
Input schema / properties / confidenceAdded value: +{ + "description": "Relation-specific confidence for EXEMPLIFIES, EVOLVED_INTO, or DERIVED_FROM.", + "maximum": 1, + "minimum": 0, + "type": "number" +} - added
Input schema / properties / contextAdded value: +{ + "description": "Relation-specific context for PREFERS_OVER or PART_OF associations.", + "type": "string" +} - added
Input schema / properties / observationsAdded value: +{ + "description": "Relation-specific observations for REINFORCES associations.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / pattern_typeAdded value: +{ + "description": "Relation-specific pattern label for EXEMPLIFIES associations.", + "type": "string" +} - added
Input schema / properties / reasonAdded value: +{ + "description": "Relation-specific reason for PREFERS_OVER, CONTRADICTS, INVALIDATED_BY, or EVOLVED_INTO associations.", + "type": "string" +} - added
Input schema / properties / resolutionAdded value: +{ + "description": "Relation-specific resolution for CONTRADICTS associations.", + "type": "string" +} - added
Input schema / properties / roleAdded value: +{ + "description": "Relation-specific role for PART_OF associations.", + "type": "string" +} - added
Input schema / properties / timestampAdded value: +{ + "description": "Relation-specific timestamp for INVALIDATED_BY associations.", + "type": "string" +} - added
Input schema / properties / transformationAdded value: +{ + "description": "Relation-specific transformation note for DERIVED_FROM associations.", + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "memory1_id", - "memory2_id", - "type", - "strength" -] - added
Output schema / properties / created_countAdded value: +{ + "description": "Batch mode: number of associations created.", + "type": "integer" +} - added
Output schema / properties / failedAdded value: +{ + "description": "Batch mode: failed association records with errors.", + "items": { + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / failed_countAdded value: +{ + "description": "Batch mode: number of associations that failed.", + "type": "integer" +} - added
Output schema / properties / succeededAdded value: +{ + "description": "Batch mode: successful association records.", + "items": { + "type": "object" + }, + "type": "array" +} - changed
Output schema / properties / success / descriptionPrevious value: -"Whether the association was created"New value: +"Whether every requested association was created. False for partial batch responses." - added
Output schema / properties / summaryAdded value: +{ + "description": "Batch mode: service summary.", + "type": "string" +}
- Changed
check_database_health3 fields changed- changed
Output schema / properties / statistics / descriptionPrevious value: -"Database statistics (memory counts, etc.)"New value: +"Database statistics and diagnostics, including memory/vector counts, sync_status, vector_dimensions, and enrichment state when provided." - changed
Output schema / properties / status / descriptionPrevious value: -"Overall health status"New value: +"Overall health status. degraded means the service is reachable but a backend or sync check needs attention." - changed
Output schema / properties / status / enumPrevious value: -[ - "healthy", - "error" -]New value: +[ + "healthy", + "degraded", + "error" +]
- Changed
recall_memory33 fields changed- added
Input schema / properties / adaptive_floorAdded value: +{ + "description": "Ranked-mode only. Enable the service's adaptive score floor when filtering weak matches.", + "type": "boolean" +} - added
Input schema / properties / current_onlyAdded value: +{ + "default": true, + "description": "Ranked-mode only. When true, server suppresses archived, not-yet-valid, expired, invalidated, or superseded memories from active context.", + "type": "boolean" +} - added
Input schema / properties / expand_respect_tagsAdded value: +{ + "description": "Ranked-mode only. When true, graph/entity expansion stays within the original tag scope; when false, expansion may include related context outside the tags.", + "type": "boolean" +} - changed
Input schema / properties / format / descriptionPrevious value: -"Output format: text (default), items (per-memory), detailed (with metadata), json (raw)"New value: +"Output format: text (default), items (one block per memory), detailed (adds type/confidence/metadata keys/relation stubs), json (raw per-memory fields incl. full content/metadata/relations; whole-response token budget still applies). text/items/detailed are summary-first: each memory shows its stored 1-2 sentence summary when available, else a content preview ā fetch a full record via memory_id." - added
Input schema / properties / min_scoreAdded value: +{ + "description": "Ranked-mode only. Minimum final score threshold before results are returned.", + "maximum": 1, + "minimum": 0, + "type": "number" +} - added
Input schema / properties / recency_biasAdded value: +{ + "description": "Ranked-mode only. Controls service recency boosting: auto lets the service infer, on forces boosting, off disables it.", + "enum": [ + "auto", + "on", + "off" + ], + "type": "string" +} - added
Input schema / properties / scope_fallbackAdded value: +{ + "description": "Ranked-mode only. Allow fallback outside the requested tag scope when scoped recall has weak evidence; diagnostics report tag_scope and outside_tag_scope.", + "type": "boolean" +} - added
Input schema / properties / state_debugAdded value: +{ + "default": false, + "description": "Ranked-mode only. Include state-filter suppression/replacement IDs and reasons when current_only is true.", + "type": "boolean" +} - added
Input schema / properties / state_modeAdded value: +{ + "description": "Ranked-mode only. `current` returns active memories; `history` allows superseded/invalidated memories for audit timelines. Prefer this over current_only for new clients.", + "enum": [ + "current", + "history" + ], + "type": "string" +} - added
Output schema / properties / entitiesAdded value: +{ + "description": "Entity identity diagnostics injected by the service.", + "items": { + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / exclude_tagsAdded value: +{ + "description": "Tags excluded from ranked recall.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / jit_enriched_countAdded value: +{ + "description": "Number of memories enriched inline during recall.", + "type": "integer" +} - added
Output schema / properties / queriesAdded value: +{ + "description": "Query variants executed by the service.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / queryAdded value: +{ + "description": "Query text executed by ranked recall.", + "type": "string" +} - added
Output schema / properties / query_time_msAdded value: +{ + "description": "Service recall latency in milliseconds.", + "type": "number" +} - added
Output schema / properties / recency_biasAdded value: +{ + "description": "Recency bias mode applied by the service.", + "enum": [ + "auto", + "on", + "off" + ], + "type": "string" +} - added
Output schema / properties / results / items / properties / content / descriptionAdded value: +"Memory content (preview in budgeted formats; omitted when summary is shown)." - added
Output schema / properties / results / items / properties / content_charsAdded value: +{ + "description": "Original content length when content was previewed or replaced by summary.", + "type": "integer" +} - added
Output schema / properties / results / items / properties / content_truncatedAdded value: +{ + "description": "True when content is a preview; fetch the full record via recall_memory({ memory_id }).", + "type": "boolean" +} - added
Output schema / properties / results / items / properties / deduped_fromAdded value: +{ + "description": "Result IDs merged into this result during multi-query deduplication.", + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / results / items / properties / jit_enrichedAdded value: +{ + "description": "True when the service enriched the memory during recall.", + "type": "boolean" +} - added
Output schema / properties / results / items / properties / outside_tag_scopeAdded value: +{ + "description": "True when scope_fallback admitted this result outside the requested tag scope.", + "type": "boolean" +} - added
Output schema / properties / results / items / properties / state_replacesAdded value: +{ + "description": "ID of the suppressed memory this result replaced during current-state filtering.", + "type": "string" +} - added
Output schema / properties / results / items / properties / summaryAdded value: +{ + "description": "Stored 1-2 sentence summary. In budgeted formats it replaces content when present.", + "type": "string" +} - added
Output schema / properties / results / items / properties / updated_atAdded value: +{ + "type": "string" +} - added
Output schema / properties / scope_fallbackAdded value: +{ + "description": "True when recall allowed outside-scope fallback results.", + "type": "boolean" +} - added
Output schema / properties / score_filterAdded value: +{ + "description": "Score filtering diagnostics such as min_score, adaptive_floor, and filtered_count.", + "type": "object" +} - added
Output schema / properties / sortAdded value: +{ + "description": "Sort mode applied by the service.", + "type": "string" +} - added
Output schema / properties / state_filterAdded value: +{ + "description": "Current-state filtering diagnostics. Includes aggregate counts by default and detailed IDs/reasons only when state_debug=true.", + "type": "object" +} - added
Output schema / properties / state_modeAdded value: +{ + "description": "State mode applied by ranked recall.", + "enum": [ + "current", + "history" + ], + "type": "string" +} - added
Output schema / properties / tag_scopeAdded value: +{ + "description": "Tag-scope diagnostics including whether scoped evidence was strong enough.", + "type": "object" +} - added
Output schema / properties / truncationAdded value: +{ + "description": "Present when trailing results were dropped to fit the response budget: { applied, omitted_results, reason }.", + "type": "object" +} - added
Output schema / properties / vector_searchAdded value: +{ + "description": "Vector-search diagnostics from the service.", + "type": "object" +}
- Changed
store_memory5 fields changed- added
Input schema / properties / supersede_reasonAdded value: +{ + "description": "Single-memory supersede mode. Optional reason stored on the old memory's metadata.", + "type": "string" +} - added
Input schema / properties / supersede_relationAdded value: +{ + "default": "INVALIDATED_BY", + "description": "Single-memory supersede mode. Relationship to create from old memory to new memory.", + "enum": [ + "INVALIDATED_BY", + "EVOLVED_INTO" + ], + "type": "string" +} - added
Input schema / properties / supersedes_memory_idAdded value: +{ + "description": "Single-memory supersede mode. Existing memory ID that this new memory replaces or corrects.", + "type": "string" +} - added
Output schema / properties / association_createdAdded value: +{ + "description": "Supersede-mode result: whether old ā new association was created.", + "type": "boolean" +} - added
Output schema / properties / superseded_memory_idAdded value: +{ + "description": "Supersede-mode result: ID of the old memory marked invalid.", + "type": "string" +}
- Changed
update_memory2 fields changed- added
Input schema / properties / t_invalidAdded value: +{ + "description": "ISO 8601 timestamp when the memory expires or was superseded", + "type": "string" +} - added
Input schema / properties / t_validAdded value: +{ + "description": "ISO 8601 timestamp when the memory becomes valid", + "type": "string" +}
6 tool updates
v0.14.0- First observed
associate_memories - First observed
check_database_health - First observed
delete_memory - First observed
recall_memory - First observed
store_memory - First observed
update_memory
TDQS
Scored across 6 tools
Each tool targets a clearly distinct operation: store, recall, associate, update, delete, and health-check. Even though recall_memory has multiple modes, the mode selection is explicit and non-overlapping with other tools.
The core tools follow a consistent verb_noun pattern: store_memory, recall_memory, update_memory, delete_memory. Minor deviations are associate_memories (plural) and check_database_health (different object noun), but the convention remains predictable and readable.
Six tools is well-scoped for a memory server: basic CRUD, relationship management, and health checking. Each tool serves a distinct purpose and none feel redundant or excessive.
The tool surface covers the full memory lifecycle: store, recall, update, delete, and graph association. Recalled enumeration and bulk delete modes also cover maintenance/audit workflows, leaving no obvious dead ends.
Maintenance
Related MCP Connectors
Persistent, portable memory for AI assistants ā your private memory graph, from any MCP client.
- EngramOAuthapp.getengram
Persistent, verbatim, searchable memory for AI assistants ā one memory across every MCP client.
Persistent personal memory for AI assistants ā save, search, and recall across every MCP client.
Cross-tool persistent memory and context for AI assistants over MCP.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceA personal AI memory hub that stores and retrieves personal data from any MCP-enabled AI assistant, enabling persistent memory across conversations.5MIT
- FlicenseNot gradedqualityDmaintenanceA MCP server that provides persistent memory for AI assistants, storing personal information, relationships, and observations to enable personalized and contextual conversations.4-
- AlicenseAqualityDmaintenanceA persistent, self-organizing memory MCP server for AI assistants, using semantic search, knowledge graphs, and reinforcement learning to automatically manage and retrieve memories.13MIT
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to have a living memory with atomic knowledge storage, multi-factor recall, organic decay, automatic learning, and graph traversal via MCP.1MIT