Skip to main content
Glama
hz1ulqu01gmnZH4

universal-memory-mcp

universal-memory-mcp

Persistent memory MCP server for single and multi-agent LLM systems. Gives AI agents long-term memory backed by SQLite with hybrid keyword + semantic search.

Features

  • Memory types: episodic (events/logs), semantic (facts/knowledge), procedural (how-to/workflows)

  • Hybrid search: FTS5 keyword search + cosine similarity over embeddings, with configurable weights

  • Knowledge graph: directed links between memories (caused_by, related_to, contradicts, supports, follows) with BFS traversal

  • Session checkpoints: save/restore agent state across conversations

  • Multi-agent support: scope memories by agent_id, session_id, or share globally

  • Optimistic locking: safe concurrent updates with version conflict detection

  • Pluggable embeddings: HuggingFace transformers (in-process) or llama-server (external HTTP)

Related MCP server: tartarus-mcp

Install

uv sync

Usage

Run as an MCP server (stdio transport):

uv run python server.py

Or via the wrapper script:

./run.sh

CLI

This package also installs a memory CLI:

uv run memory doctor

Ingest Claude/Codex logs

The log ingester reads local Claude/Codex JSONL/text logs, redacts common secrets, extracts durable memories, and stores only the extracted memories with log provenance metadata. Raw logs are not stored.

Dry-run first:

uv run memory ingest-logs codex --dry-run --root ~/.codex/sessions --extractor heuristic
uv run memory ingest-logs claude --dry-run --root ~/.claude/projects --extractor heuristic

Use a local llama-server OpenAI-compatible chat endpoint for extraction:

llama-server --model /path/to/chat-model.gguf --port 8080
uv run memory ingest-logs all --llm-url http://localhost:8080 --llm-model local

By default the CLI does not send max_tokens to the chat endpoint, which avoids truncating extraction responses from thinking models. Set an explicit cap only when you need one:

uv run memory ingest-logs codex --llm-max-tokens 4096

To also compute embeddings through a local embedding server:

llama-server --model embeddinggemma-300m-Q4_0.gguf --port 8787 --embedding --ctx-size 512
MEMORY_ENABLE_EMBEDDINGS=true \
MEMORY_EMBEDDING_BACKEND=llama-server \
MEMORY_EMBEDDING_DIMENSION=768 \
MEMORY_LLAMA_SERVER_URL=http://localhost:8787 \
uv run memory ingest-logs codex --llm-url http://localhost:8080

Incremental checkpoints are stored in SQLite, so later runs only consume new events. For polling:

uv run memory watch-logs all --interval 30 --llm-url http://localhost:8080

Claude Code config

Add to your MCP settings (~/.claude/settings.json or project .mcp.json):

{
  "mcpServers": {
    "memory": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/universal-memory-mcp", "python", "server.py"]
    }
  }
}

Configuration

All settings via environment variables (prefix MEMORY_):

Variable

Default

Description

MEMORY_DATABASE_PATH

./memory.db

SQLite database path

MEMORY_EMBEDDING_BACKEND

transformers

transformers or llama-server

MEMORY_EMBEDDING_MODEL

sentence-transformers/all-MiniLM-L6-v2

HuggingFace model name

MEMORY_EMBEDDING_DIMENSION

384

Embedding vector size

MEMORY_LLAMA_SERVER_URL

http://localhost:8787

llama-server endpoint

MEMORY_ENABLE_EMBEDDINGS

true

Set false for keyword-only search

MEMORY_KEYWORD_WEIGHT

0.4

Hybrid search keyword weight

MEMORY_SEMANTIC_WEIGHT

0.6

Hybrid search semantic weight

MEMORY_RECALL_MIN_RELEVANCE

0.25

Minimum cosine similarity for semantic-channel recall results (0 = disabled). Keyword matches always survive.

MEMORY_RECALL_SNIPPET_CHARS

600

Truncate recalled contents to this many chars (0 = disabled). Full text via exact fetch or full_content=true.

Using llama-server backend

For lower memory usage with a GGUF model:

llama-server --model embeddinggemma-300m-Q4_0.gguf --port 8787 --embedding --ctx-size 512
MEMORY_EMBEDDING_BACKEND=llama-server MEMORY_EMBEDDING_DIMENSION=768 uv run python server.py

MCP Tools

The surface is deliberately small — five tools, tiered by call frequency:

Tool

Description

recall_memories

One retrieval tool, three selectors: query (hybrid/keyword/semantic search), memory_id (exact fetch, full content), or entity (memories mentioning src/foo.py, an identifier, etc.). expand_links=N attaches graph neighbors to each result. Long contents are returned as snippets unless full_content=true.

store_memory

Store a memory with type, agent/session scope, importance; optional links creates graph edges to existing memories in the same call

update_memory

Update with optimistic locking (expected_version)

manage_session

action: create | checkpoint | restore — save/restore agent state across conversations

memory_admin

action: stats | dream_status | run_dream_jobs | extract_entities | check_contradictions | link | delete — statistics, background-job maintenance, manual graph links, and deletion (destructive ops gated behind one tool for per-tool permission allowlists)

Errors are raised as MCP tool errors (isError: true), never returned as data.

Breaking changes in 0.2.0

get_memory, delete_memory, link_memories, get_linked_memories, create_session, checkpoint_session, restore_session, get_stats, extract_entities, get_entity_neighbors, check_contradictions, dream_status, and run_dream_jobs were folded into the five tools above. recall_memories now returns {mode, count, memories} instead of a bare list, truncates long contents by default, and applies a semantic relevance cutoff (MEMORY_RECALL_MIN_RELEVANCE).

Tests

uv run pytest

License

WTFPL

A
license - permissive license
-
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

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/hz1ulqu01gmnZH4/universal-memory-mcp'

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