Memory Engine MCP Server
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., "@Memory Engine MCP Serversave that we chose SQLite for local persistence"
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.
Memory Engine MCP Server
Deprecated: Use ProjectContext.
A high-performance MCP (Model Context Protocol) server providing long-term memory storage with semantic and keyword search capabilities.
Features
Fast Semantic Search: Uses
fastembedwithBAAI/bge-small-en-v1.5for fast startup and low memory usageHybrid Search: Combines keyword (FTS5) and vector search using Reciprocal Rank Fusion (RRF)
Persistent Storage: SQLite-based storage with
sqlite-vecextensionSub-200ms Queries: Keep embedding model in memory for fast response times
MCP Native: Exposes
save_memoryandquery_memoryas native MCP tools
Related MCP server: Memento
Installation
# Clone the repository
git clone <repo-url>
cd agentmemory
# Install dependencies with uv
uv sync
# Or install globally
uv pip install -e .Usage
Running the Server
# Run directly
agentmemory
# Or with uv
uv run agentmemoryMCP Configuration
Add to your MCP client configuration (e.g., mcp.json):
{
"mcpServers": {
"memory": {
"command": "uv",
"args": ["run", "agentmemory"],
"cwd": "/path/to/agentmemory"
}
}
}Or using the installed script:
{
"mcpServers": {
"memory": {
"command": "agentmemory"
}
}
}MCP Tools
save_memory
Save a memory to long-term storage.
Arguments:
category(string): Category of the memory (e.g., "architecture", "preference", "bug_fix")topic(string): Short descriptive titlecontent(string): Detailed memory/decision text
Returns:
{
"status": "success",
"doc_id": 123,
"topic": "Example Topic",
"category": "architecture"
}query_memory
Query memories using semantic and keyword search.
Arguments:
query(string): Natural language search stringtop_k(integer, optional): Number of results to return (default: 3)
Returns:
[
{
"id": 123,
"category": "architecture",
"topic": "Example Topic",
"content": "Detailed content...",
"timestamp": "2024-02-04 13:22:00",
"last_verified": "2024-02-04 13:22:00",
"score": 0.8542
}
]Note: last_verified indicates when the memory was last confirmed as accurate. Use verify_memory to update this timestamp.
delete_memory
Delete a memory by ID.
Arguments:
doc_id(integer): The ID of the memory to delete
Returns:
{
"status": "success",
"message": "Memory 123 deleted"
}update_memory
Update a memory by ID.
Arguments:
doc_id(integer): The ID of the memory to updatecategory(string, optional): New categorytopic(string, optional): New topiccontent(string, optional): New content
Returns:
{
"status": "success",
"doc_id": 123,
"topic": "Updated Topic",
"category": "updated_category",
"message": "Memory updated"
}verify_memory
Mark a memory as verified by updating its last_verified timestamp to now.
Use this when:
You've confirmed a memory is still accurate
You've checked information against current code
You want to prevent hallucinations from stale data
Arguments:
doc_id(integer): The ID of the memory to verify
Returns:
{
"status": "success",
"doc_id": 123,
"message": "Memory verified and timestamp updated"
}Note: This helps track memory freshness. Memories with old last_verified timestamps should be treated with caution.
MCP Resources
memory://usage-guidelines
Provides comprehensive usage guidelines for AI agents using the memory system.
Access via MCP client:
content = await client.read_resource("memory://usage-guidelines")
print(content[0].text)Contains:
When to save memories (DO's and DON'Ts)
How to structure memories (category, topic, content)
How to query effectively
Best practices and common patterns
Search features and capabilities
Privacy and security considerations
Note: AI agents can read this resource to understand how to use the memory system effectively. The guidelines help ensure memories are saved consistently and can be retrieved efficiently.
Examples
Saving a Technical Decision
Agent: "I'll record that we've decided to use SQLite for its simplicity and local persistence."
save_memory(
category="architecture",
topic="Database Choice",
content="We chose SQLite with sqlite-vec for local vector storage. This avoids external dependencies and keeps data within the project git root."
)Retrieving Project Context
Agent: "Let me check our previous decisions about the tech stack."
query_memory(query="tech stack decisions")
# Returns: [Database Choice, Python version requirements, etc.]Preventing Stale Data
Agent: "I just verified that the Python version requirement is still 3.12."
verify_memory(doc_id=123)Architecture
Technology Stack
Framework: FastMCP (Python MCP library)
Embeddings: fastembed (
BAAI/bge-small-en-v1.5, 384-dim)Database: SQLite with
sqlite-vecandFTS5extensionsCommunication: JSON-RPC over stdio
Data Flow
Save: Content → Embedding → SQLite (docs + docs_fts + docs_vec)
Query: Query → Embedding → Parallel FTS5 + Vector Search → RRF Fusion → Ranked Results
Database Schema
-- Main documents table
CREATE TABLE docs (
id INTEGER PRIMARY KEY,
category TEXT,
topic TEXT,
content TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
last_verified DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- Full-text search index
CREATE VIRTUAL TABLE docs_fts USING fts5(
category, topic, content,
content='docs',
content_rowid='id'
);
-- Vector search index
CREATE VIRTUAL TABLE docs_vec USING vec0(
id INTEGER PRIMARY KEY,
embedding float[384]
);Storage Location
The database is stored in .ctxhub/memory.sqlite in the git root directory (or current working directory if not in a git repo). This allows the memory to travel with the project while remaining hidden from version control.
Performance
First Query: ~500ms (model initialization + query)
Subsequent Queries: <200ms (model kept in memory)
Embedding Model Size: ~133MB (BAAI/bge-small-en-v1.5)
Memory Usage: ~200MB base + model
Development
Project Structure
agentmemory/
├── src/
│ └── agentmemory/
│ ├── __init__.py
│ └── server.py # MCP server implementation
├── pyproject.toml # Project configuration
└── .agent-memory/
└── db.sqlite # Persistent database (in git root)Testing
The project includes a comprehensive test suite.
# Quick start: runs main tests and offers to start server
./quickstart.sh
# Run specific tests manually
uv run python tests/test_server.py
uv run python tests/test_freshness.py
uv run python tests/test_updates.pyMCP Inspector
You can also test the tools interactively using the MCP Inspector:
npx @modelcontextprotocol/inspector uv run agentmemoryLicense
GPLv3
Available Tools
5 toolsdelete_memoryA
Delete a memory by ID.
Args:
doc_id: The ID of the memory to delete
Returns:
A dictionary with status and message
| Name | Required | Description | Default |
|---|---|---|---|
| doc_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full burden of behavioral disclosure. It states it deletes a memory but does not disclose irreversibility, permission requirements, or behavior when doc_id is not found. The return type is vaguely described as 'a dictionary with status and message' without specifics.
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 concise and structured with Args and Returns sections. It contains no redundant sentences and is appropriately sized for a simple delete operation.
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?
For a simple delete tool with one parameter, the description covers purpose, parameter, and return. However, with no annotations, it lacks important context about permanence and error conditions, making it only minimally complete. It does not reference the existing output schema (if any) or provide example usage.
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 has no description for doc_id (0% coverage). The description compensates by explaining 'The ID of the memory to delete', adding meaning beyond the schema's bare integer type. However, it does not specify format or constraints beyond that.
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 'Delete a memory by ID', using a specific verb ('Delete') and resource ('memory'), which distinguishes it from siblings like save_memory and update_memory. The scope is precisely defined by ID.
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?
No guidance is provided on when to use this tool versus alternatives. It does not explicitly state that this is for permanent removal or mention any prerequisites or conditions. Sibling tools (update_memory, query_memory) are not referenced as alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_memoryA
Query memories using semantic and keyword search.
Args:
query: Natural language search string
top_k: Number of results to return (default: 3)
Returns:
A list of matching memories with similarity scores
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| top_k | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses the search method (semantic and keyword) and the return format (list with similarity scores). While it doesn't explicitly state read-only behavior, the word 'query' implies no mutation, and the description adds useful context beyond a simple 'Query memories.'
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 compact and well-structured with a clear one-sentence purpose followed by Args and Returns sections. Every sentence provides necessary information with no redundancy or fluff.
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?
For a 2-parameter query tool with an output schema, the description covers all essential aspects: purpose, parameter semantics, and return value shape. No additional context is needed for an agent to correctly select and invoke the tool.
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?
The input schema has 0% description coverage, but the description fully compensates by defining each parameter: query as 'Natural language search string' and top_k as 'Number of results to return (default: 3).' This adds semantic meaning beyond the schema's type and default.
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's function: 'Query memories using semantic and keyword search.' It specifies a specific verb (query), resource (memories), and distinguishes itself from sibling tools like save_memory and delete_memory by focusing on retrieval.
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 implies usage for searching memories but provides no explicit guidance on when to use this tool versus alternatives like search_agendas. It lacks exclusions or conditions, leaving the agent to infer based on the name and resource.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
save_memoryA
Save a memory to the long-term storage.
Args:
category: The category of the memory (e.g., "architecture", "preference", "bug_fix")
topic: A short descriptive title for the memory
content: The detailed memory/decision text
Returns:
A dictionary with status, doc_id, topic, and category
| Name | Required | Description | Default |
|---|---|---|---|
| topic | Yes | ||
| content | Yes | ||
| category | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must convey behavioral context. It mentions 'long-term storage' and a return dictionary containing a doc_id, which implies creation, but it does not disclose whether the operation overwrites existing memories, requires specific permissions, or has other side effects. This is a significant gap for a write operation.
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 highly concise, using a standard Args/Returns docstring format. Every sentence serves a purpose, and there is no redundant information. It is well-structured and immediately readable.
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?
The description covers the essential information: inputs and the return value, and an output schema exists. However, it omits usage scenarios, error conditions, and edge cases (e.g., duplicate topics). For a simple save tool, this is largely sufficient, but a bit more context would improve completeness.
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?
With 0% schema coverage, the description compensates well by explaining each parameter: 'category' includes examples, 'topic' is defined as a short title, and 'content' as detailed text. This adds value beyond the bare parameter names, though it lacks constraints on allowed values or formats.
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's function with a specific verb ('Save') and resource ('memory'), and mentions 'long-term storage' to indicate persistence. Sibling tools (delete/update/verify/query) confirm this is a creation operation, distinguishing it from related actions.
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 implies usage ('Save a memory') but provides no explicit guidance on when to use this tool versus alternatives like update_memory or query_memory. There are no exclusions or alternative recommendations, only the inferred distinction from sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_memoryA
Update a memory by ID.
Args:
doc_id: The ID of the memory to update
category: New category (optional)
topic: New topic (optional)
content: New content (optional)
Returns:
A dictionary with status and updated details
| Name | Required | Description | Default |
|---|---|---|---|
| topic | No | ||
| doc_id | Yes | ||
| content | No | ||
| category | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must disclose behavioral traits. It only states it updates by ID and returns a status dictionary, but misses crucial behavior such as handling of non-existent IDs, whether unspecified fields are left unchanged, or error conditions. This is a significant gap for a mutating tool.
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 concise and well-structured: a one-sentence purpose, followed by an Args section for each parameter and a Returns section. No redundancy, every sentence adds 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?
For a simple update tool, the description covers purpose, parameters, and return format. It misses edge-case behavior like invalid IDs, but given the presence of an output schema and simple params, it's largely complete. A 4 reflects minor 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?
The description explains each parameter with clear semantics: doc_id is the target, and category/topic/content are optional new values. Since the schema has no descriptions (0% coverage), the description provides complete parameter meaning beyond the schema.
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 'Update a memory by ID' with a specific verb and resource, distinguishing it from sibling tools like save_memory and delete_memory by focusing on modification of existing 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 implies usage for modifying an existing memory but doesn't explicitly say when not to use it or name alternatives. It provides no comparison with sibling tools like save_memory for creation, making usage context implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_memoryA
Mark a memory as verified, updating its last_verified timestamp to now.
Use this when you've confirmed the memory is still accurate and up-to-date.
This helps track memory freshness and prevents hallucinations from outdated information.
Args:
doc_id: The ID of the memory to verify
Returns:
A dictionary with status and message
| Name | Required | Description | Default |
|---|---|---|---|
| doc_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full burden. It discloses the main side effect (updating the last_verified timestamp) and the return type ('A dictionary with status and message'). However, it does not discuss error handling, permissions, or behavior when the doc_id does not exist, which are relevant for a write operation.
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 opening statement, a usage hint, a rationale, and an Args/Returns section. Each sentence earns its place and there is no redundancy.
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?
For a simple single-parameter tool, the description covers the core purpose, usage, parameter, and return value. The output schema existence reduces the need to describe return format, and the description does that anyway. Minor gaps remain regarding error cases, but it is sufficiently complete for an agent to apply it 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?
The input schema only provides the type (integer) and title for doc_id. The description compensates fully by explaining its meaning: 'doc_id: The ID of the memory to verify.' This is sufficient despite the schema's 0% coverage.
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 identifies the tool's purpose: 'Mark a memory as verified, updating its last_verified timestamp to now.' This is a specific verb+resource combination that distinguishes it from the sibling tools (save_memory, delete_memory, update_memory, query_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 provides explicit usage context: 'Use this when you've confirmed the memory is still accurate and up-to-date.' It does not explicitly mention alternatives or when not to use it, but the context is clear enough to guide the agent.
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.
5 tool updates
v1.0.0- First observed
delete_memory - First observed
query_memory - First observed
save_memory - First observed
update_memory - First observed
verify_memory
TDQS
Scored across 5 tools
Each tool targets a distinct memory operation: save (create), delete, update, verify, and query (search). There is no overlap in purpose, so an agent can easily select the right tool.
All tool names follow a consistent verb_noun pattern (e.g., save_memory, delete_memory, update_memory), making the API predictable and easy to navigate.
With exactly 5 tools, the server is well-scoped for a memory management domain, covering essential operations without unnecessary complexity.
The server provides full CRUD coverage (save, query, update, delete) plus a verify operation for freshness. No critical lifecycle steps are missing for long-term memory storage.
Maintenance
Related MCP Connectors
Cloud-hosted MCP server for durable AI memory
An MCP memory server. One memory your agents share — across models, devices and apps.
Capability registry for the agentic economy. Semantic search over verified MCP server listings.
Related MCP Servers
- AlicenseBqualityBmaintenanceA high-performance MCP server utilizing libSQL for persistent memory and vector search capabilities, enabling efficient entity management and semantic knowledge storage.693 npm88MIT
- AlicenseAqualityCmaintenanceA local, fully-offline MCP memory server that enables persistent storage and retrieval of information using SQLite with both keyword and semantic vector search capabilities.1019 npm13MIT
- FlicenseNot gradedqualityDmaintenanceAn MCP server for managing persistent AI memory using hybrid search (keyword + semantic vector) with SQLite storage and offline-first local embeddings.-
- AlicenseAqualityCmaintenancePersistent memory MCP server for AI agents, using SQLite with hybrid keyword and semantic search for long-term memory storage.5Do What The F*ck You Want To Public