Skip to main content
Glama
asd-noor

Memory Engine MCP Server

by asd-noor

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 fastembed with BAAI/bge-small-en-v1.5 for fast startup and low memory usage

  • Hybrid Search: Combines keyword (FTS5) and vector search using Reciprocal Rank Fusion (RRF)

  • Persistent Storage: SQLite-based storage with sqlite-vec extension

  • Sub-200ms Queries: Keep embedding model in memory for fast response times

  • MCP Native: Exposes save_memory and query_memory as 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 agentmemory

MCP 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 title

  • content (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 string

  • top_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 update

  • category (string, optional): New category

  • topic (string, optional): New topic

  • content (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-vec and FTS5 extensions

  • Communication: JSON-RPC over stdio

Data Flow

  1. Save: Content → Embedding → SQLite (docs + docs_fts + docs_vec)

  2. 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.py

MCP Inspector

You can also test the tools interactively using the MCP Inspector:

npx @modelcontextprotocol/inspector uv run agentmemory

License

GPLv3

Available Tools

5 tools
delete_memoryA

Delete a memory by ID.

Args:
    doc_id: The ID of the memory to delete

Returns:
    A dictionary with status and message
ParametersJSON Schema
NameRequiredDescriptionDefault
doc_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It states the deletion action and return dictionary but does not mention whether the operation is irreversible, what happens if doc_id doesn't exist, or any side effects or failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise with a clear top statement, followed by a neatly structured Args and Returns section. Every sentence earns its place; there is zero fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter delete tool with an output schema, the description covers the action, parameter semantics, and return format. It lacks broader context about when to use it or long-term effects, but given the tool's triviality and the presence of an output schema, it is nearly complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has no parameter descriptions (0% coverage), but the description explicitly explains 'doc_id: The ID of the memory to delete.' This fully compensates for the schema gap, giving the agent complete semantic understanding of the single parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

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 by ID). This unambiguously distinguishes it from sibling tools like save_memory, update_memory, verify_memory, and query_memory.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus alternatives, no prerequisites, and no exclusions. The description only states what the tool does, leaving the agent to infer usage purely from the tool name and action.

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
ParametersJSON Schema
NameRequiredDescriptionDefault
queryYes
top_kNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions semantic and keyword search and returns a list of matching memories with similarity scores, which is useful context. However, it does not explicitly state that it is a read-only operation or disclose any limitations, such as behavior with empty queries or potential side effects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured, with a clear one-sentence purpose followed by parameter definitions and return value explanation. Every sentence contributes meaningful information without unnecessary elaboration.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter read tool, the description is fairly complete. It covers the purpose, parameter semantics, and return format. The existence of an output schema means the return value details are adequately supplemented, though it lacks explicit usage guidance, which is a minor gap given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the description fully compensates by defining 'query' as a natural language search string and explaining 'top_k' as the number of results to return with a default value of 3. This adds significant meaning beyond the bare type information in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool queries memories using semantic and keyword search. The verb 'Query' plus the resource 'memories' and the specific search methods distinguish it from sibling tools like save_memory, delete_memory, and update_memory.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage is implied by the tool's name and description, but there is no explicit guidance on when to use this tool versus alternatives. It does not mention scenarios like 'when you need to retrieve stored information' or exclude contexts where other memory tools are more appropriate.

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
ParametersJSON Schema
NameRequiredDescriptionDefault
topicYes
contentYes
categoryYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines3/5

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
ParametersJSON Schema
NameRequiredDescriptionDefault
topicNo
doc_idYes
contentNo
categoryNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden for behavioral disclosure. It only states that it updates and returns a dictionary, but does not mention side effects, permission requirements, or behavior for non-existent doc_ids. For a mutation tool, this is insufficient transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured, using a standard Args/Returns format. Every sentence contributes useful information without redundancy, and it is easy to scan quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema and the relative simplicity of an update operation, the description is mostly complete. It mentions the return format (dictionary with status and details). However, it lacks error-handling context (e.g., what happens if doc_id not found), which would make it more robust.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema has 0% description coverage, the tool description provides meaningful explanations for each parameter (doc_id as the target, and category/topic/content as optional updates). This adds value beyond the schema's bare type and default information.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action: "Update a memory by ID." This specifies the verb (update), resource (memory), and key identifier (ID), effectively distinguishing it from sibling tools like save_memory (create) 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.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for updating existing memories by providing doc_id and optional fields, but it does not explicitly mention when to choose this over siblings or note any prerequisites. There is no exclusion guidance, making it merely implied 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
ParametersJSON Schema
NameRequiredDescriptionDefault
doc_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters5/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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. Dates show when Glama detected each change.

  1. 5 tool updatesv1.0.0
    • First observeddelete_memory
    • First observedquery_memory
    • First observedsave_memory
    • First observedupdate_memory
    • First observedverify_memory

TDQS

A4.2/5.0
Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

With exactly 5 tools, the server is well-scoped for a memory management domain, covering essential operations without unnecessary complexity.

Completeness5/5

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

ActivityInactive
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/asd-noor/agentmemory'

If you have feedback or need assistance with the MCP directory API, please join our Discord server