stonemem Documentation
Institutional memory for AI agents. FTS5 search, entity graphs, temporal scoring, supersession chains. Your agents remember everything — and know what matters now.
1. Overview
stonemem is a compiled Rust binary that runs as a local MCP (Model Context Protocol) server, providing persistent, searchable memory to any AI agent platform. It stores structured entries in a SQLite database with WAL mode, offering full-text search via FTS5, automatic entity extraction, temporal relevance scoring, and supersession chains that keep knowledge current.
Key Capabilities
- Full-text search (FTS5) — BM25-ranked retrieval across all stored entries. Finds what your agent wrote three weeks ago in under 1ms.
- Entity extraction — Automatically identifies people, projects, technologies, URLs, and other entities from stored content. Builds a queryable relationship graph.
- Temporal scoring — Recent knowledge ranks higher. An entry from yesterday outweighs one from last month on the same topic, unless the older one is pinned.
- Supersession chains — When facts change, new entries supersede old ones. Your agent always gets the current state, not the historical noise.
- Namespace isolation — Each agent can write to its own namespace for private storage, or use shared namespaces for cross-agent knowledge.
- Auto-deduplication — Duplicate or near-duplicate entries are detected and merged on save.
- Agent registry — Track which agents are active, their roles, and session IDs.
Architecture
stonemem runs as a single-process HTTP server on port 3391 (configurable). All data is stored locally in a SQLite database — nothing leaves your machine. The MCP transport layer allows any MCP-compatible agent framework to connect directly via stdio or HTTP.
Data locality guarantee: stonemem never phones home, never uploads data, and never requires an internet connection to function. Your agent's memory stays on your infrastructure.
2. Installation
macOS (Homebrew)
brew install keystoneproject/tap/stonemem
macOS (Direct Download)
# Apple Silicon (M1/M2/M3/M4)
curl -L https://keystoneproject.dev/releases/stonemem/darwin-aarch64/stonemem-v1.1.0-darwin-aarch64.tar.gz | tar xz
sudo mv stonemem /usr/local/bin/
# Intel
curl -L https://keystoneproject.dev/releases/stonemem/darwin-x86_64/stonemem-v1.1.0-darwin-x86_64.tar.gz | tar xz
sudo mv stonemem /usr/local/bin/
Linux
# x86_64
curl -L https://keystoneproject.dev/releases/stonemem/linux-x86_64/stonemem-v1.1.0-linux-x86_64.tar.gz | tar xz
sudo mv stonemem /usr/local/bin/
# ARM64 (aarch64)
curl -L https://keystoneproject.dev/releases/stonemem/linux-aarch64/stonemem-v1.1.0-linux-aarch64.tar.gz | tar xz
sudo mv stonemem /usr/local/bin/
Verify Installation
stonemem --version
# stonemem 1.1.0
3. Quick Start
Step 1: Activate your license
Every installation requires a license key, including the free tier. You receive your key via email after checkout.
# Activate with your license key
stonemem activate --key SM-XXXX-XXXX-XXXX-XXXX
# Verify activation
stonemem status
Step 2: Start the server
# Start with default settings (port 3391, data in ~/.stonemem/)
stonemem serve
# Or specify a custom data directory
stonemem serve --data-dir /path/to/data --port 3391
Step 3: Connect your agent
Add stonemem to your agent's MCP configuration:
{
"mcpServers": {
"stonemem": {
"command": "stonemem",
"args": ["serve"],
"transport": "stdio"
}
}
}
Or connect via HTTP:
{
"mcpServers": {
"stonemem": {
"url": "http://localhost:3391",
"transport": "http"
}
}
}
Step 4: Test it
# Save an entry
curl -X POST http://localhost:3391/save \
-H "Content-Type: application/json" \
-d '{"agent_id": "test-agent", "content": "The database migration runs at 3am UTC every Tuesday.", "tags": ["operations", "database"]}'
# Search for it
curl -X POST http://localhost:3391/search \
-H "Content-Type: application/json" \
-d '{"query": "database migration schedule"}'
4. Configuration
Configuration File
stonemem reads configuration from ~/.stonemem/config.toml (or the path specified by --config):
[server]
host = "127.0.0.1"
port = 3391
data_dir = "~/.stonemem"
[license]
key_file = "~/.stonemem/license.key"
license_server = "https://license.keystoneproject.dev"
[engine]
max_entry_size = 65536 # Maximum content size per entry (bytes)
dedup_threshold = 0.85 # Similarity threshold for deduplication (0.0-1.0)
entity_extraction = true # Enable automatic entity extraction
temporal_decay_days = 90 # Days after which temporal score begins decaying
[logging]
level = "info" # trace, debug, info, warn, error
format = "json" # json or text
Environment Variables
All configuration can be overridden via environment variables with the STONEMEM_ prefix:
STONEMEM_PORT=3391
STONEMEM_DATA_DIR=/var/lib/stonemem
STONEMEM_LOG_LEVEL=debug
Command Line Options
stonemem serve [OPTIONS]
OPTIONS:
--port Server port [default: 3391]
--host Bind address [default: 127.0.0.1]
--data-dir Data directory [default: ~/.stonemem]
--config Config file path
--log-level Log level (trace/debug/info/warn/error)
5. API Reference
All endpoints accept and return JSON. The server listens on http://localhost:3391 by default.
Save an entry to memory. Automatically extracts entities, checks for duplicates, and assigns temporal scores.
Request Body
{
"agent_id": "string", // Required. Agent identifier.
"content": "string", // Required. The content to store.
"namespace": "string", // Optional. Default: "default".
"tags": ["string"], // Optional. Metadata tags for filtering.
"supersedes": 123 // Optional. ID of entry this replaces.
}
Response
{
"id": 42,
"status": "saved",
"entities_extracted": ["PostgreSQL", "migration", "UTC"],
"deduplicated": false
}
Tier Limits
- Free: 10,000 entries, 1 namespace
- Pro: Unlimited entries, unlimited namespaces
- Enterprise: Same as Pro + shared memory features
Full-text search across stored entries using FTS5 with BM25 ranking.
Request Body
{
"query": "string", // Required. FTS5 search query.
"agent_id": "string", // Optional. Filter by agent.
"namespace": "string", // Optional. Default: "default".
"limit": 10, // Optional. Max results. Default: 10.
"tags": ["string"], // Optional. Filter by tags.
"time_range": { // Optional. Filter by time window.
"start": "2026-01-01T00:00:00Z",
"end": "2026-06-01T00:00:00Z"
}
}
Response
{
"results": [
{
"id": 42,
"content": "The database migration runs at 3am UTC...",
"agent_id": "ops-agent",
"namespace": "default",
"tags": ["operations", "database"],
"score": 12.45,
"created_at": "2026-06-01T12:00:00Z"
}
],
"total": 1
}
Temporal recall — retrieves the most relevant recent entries for a query, weighted by recency.
Request Body
{
"query": "string", // Required. What to recall.
"agent_id": "string", // Optional. Filter by agent.
"namespace": "string", // Optional. Default: "default".
"limit": 5, // Optional. Max results. Default: 5.
"time_window": "7d" // Optional. Look back period (e.g., "7d", "30d", "1h").
}
Response
{
"results": [
{
"id": 42,
"content": "...",
"temporal_score": 0.95,
"relevance_score": 8.2,
"combined_score": 14.6
}
]
}
Query the entity graph — find people, projects, technologies mentioned across entries.
Request Body
{
"query": "string", // Required. Entity name or partial match.
"entity_type": "string", // Optional. Filter: "person", "project", "technology", etc.
"limit": 10 // Optional. Max results. Default: 10.
}
Response
{
"entities": [
{
"id": 7,
"name": "PostgreSQL",
"entity_type": "technology",
"mention_count": 34,
"first_seen": "2026-03-15T09:00:00Z",
"last_seen": "2026-06-10T04:00:00Z"
}
],
"total": 1
}
Pro/Enterprise only. Entity queries require a Pro or Enterprise license. Free tier returns a 402 response.
Register an agent with the memory server. Tracks active agents, their roles, and session IDs.
Request Body
{
"agent_id": "string", // Required. Unique agent identifier.
"role": "string", // Optional. Agent role description.
"session_id": "string" // Optional. Current session ID.
}
Deregister an agent from the memory server.
Request Body
{
"agent_id": "string" // Required.
}
List all registered agents with their status, roles, and last-seen timestamps.
Response
{
"agents": [
{
"id": "research-agent",
"role": "Research and analysis",
"session_id": "sess-abc123",
"registered_at": "2026-06-10T02:00:00Z",
"last_seen": "2026-06-10T04:30:00Z",
"status": "active"
}
]
}
Server statistics — entry counts, namespace counts, database size, daily usage.
Response
{
"entry_count": 15234,
"namespace_count": 8,
"agent_count": 3,
"entity_count": 1204,
"db_size": 45678912,
"today_saves": 127,
"today_recalls": 342,
"today_searches": 89
}
Health check endpoint. Returns server status, version, and license tier.
Response
{
"status": "ok",
"version": "1.1.0",
"tier": "pro",
"uptime_seconds": 86400
}
6. MCP Tool Reference
When connected as an MCP server, stonemem exposes the following tools to your agent:
mem_save
Save structured content to memory with automatic entity extraction and deduplication.
Tool: mem_save
Parameters:
- content (string, required): Content to store
- namespace (string, optional): Namespace for isolation. Default: "default"
- tags (array of strings, optional): Metadata tags
- supersedes (integer, optional): ID of entry to replace
Example:
mem_save({
content: "Sprint 14 shipped the auth middleware rewrite. Uses ed25519 now.",
namespace: "engineering",
tags: ["sprint-14", "auth", "security"]
})
mem_search
Full-text search with BM25 ranking, tag filtering, and time range support.
Tool: mem_search
Parameters:
- query (string, required): Search query
- namespace (string, optional): Namespace to search
- limit (integer, optional): Max results (default 10)
- tags (array of strings, optional): Filter by tags
- time_range (object, optional): { start, end } ISO timestamps
Example:
mem_search({ query: "auth middleware ed25519", limit: 5 })
mem_recall
Temporal recall — combines relevance and recency for the most useful results.
Tool: mem_recall
Parameters:
- query (string, required): What to recall
- namespace (string, optional): Namespace
- limit (integer, optional): Max results (default 5)
- time_window (string, optional): Look back period (e.g., "7d")
Example:
mem_recall({ query: "deployment schedule", time_window: "30d" })
mem_entity_query
Query the entity graph for people, projects, technologies, and their relationships.
Tool: mem_entity_query
Parameters:
- query (string, required): Entity name or partial
- entity_type (string, optional): Filter type
- limit (integer, optional): Max results (default 10)
Example:
mem_entity_query({ query: "PostgreSQL", entity_type: "technology" })
7. Use Cases by Platform
Session Continuity Across Conversations
Claude Code sessions lose context when the conversation ends. With stonemem, critical decisions, architectural choices, and debugging findings persist across sessions.
// Agent saves a decision
mem_save({
content: "Decided to use ed25519 for license keys instead of RSA. Reason: faster signing, smaller keys, no padding oracle attacks.",
namespace: "architecture",
tags: ["decision", "cryptography"]
})
// Three days later, a new session recalls it
mem_recall({ query: "license key signing algorithm decision" })
// Returns: "Decided to use ed25519 for license keys..."
Result: New sessions start warm, not cold. The agent doesn't re-derive decisions already made.
Shared Knowledge Across Crew Members
In a CrewAI crew with a Researcher, Writer, and Editor, all three agents share knowledge through stonemem's shared namespaces.
// Researcher agent stores findings
mem_save({
content: "Market analysis: AI agent infrastructure growing 340% YoY. Key players: LangChain, CrewAI, Haystack.",
namespace: "shared-research",
tags: ["market", "competitive-intel"]
})
// Writer agent recalls research without re-searching
mem_recall({ query: "AI agent market growth", namespace: "shared-research" })
Result: Crew members build on each other's work instead of repeating research.
State Persistence Across Graph Executions
LangGraph workflows can checkpoint state into stonemem, enabling recovery and cross-run learning.
// Save workflow state at a checkpoint
mem_save({
content: JSON.stringify({ step: "validation", results: validationResults }),
namespace: "workflow-runs",
tags: ["workflow-id-abc123", "checkpoint"]
})
// On retry or next run, recall previous state
mem_search({
query: "workflow validation results",
namespace: "workflow-runs",
tags: ["workflow-id-abc123"]
})
Result: Failed workflows resume from the last checkpoint instead of starting over.
Codebase Knowledge Accumulation
OpenHands agents exploring a large codebase store architectural insights for future reference.
// Agent discovers something non-obvious about the codebase
mem_save({
content: "The auth module at src/auth/ uses a custom JWT implementation (not a library) because of FIPS compliance requirements. Do not replace with jsonwebtoken crate.",
namespace: "codebase-knowledge",
tags: ["auth", "constraint", "compliance"],
supersedes: 12 // Replaces an earlier, less accurate understanding
})
Result: Future agents don't waste time trying to "fix" intentional design decisions.
Multi-Agent Memory Federation
Google ADK agents running across different services share institutional knowledge through stonemem's namespace federation (Enterprise tier).
// Customer service agent logs a product issue pattern
mem_save({
content: "3 customers this week reported timeout errors on the /api/export endpoint when exporting > 10k rows. Engineering aware, fix in sprint 22.",
namespace: "customer-issues",
tags: ["export", "performance", "sprint-22"]
})
// Product team agent reviews customer pain points
mem_search({
query: "customer reported issues performance",
namespace: "customer-issues",
time_window: "30d"
})
RAG Pipeline Enhancement
Enhance Haystack RAG pipelines by caching retrieval results and user feedback in stonemem.
// Cache a successful retrieval pattern
mem_save({
content: "Query 'quarterly revenue' maps best to documents in the finance/reports/ collection, not the general knowledge base.",
namespace: "rag-patterns",
tags: ["routing", "finance"]
})
// Use cached patterns to improve routing
mem_recall({ query: "quarterly revenue document routing", namespace: "rag-patterns" })
Enterprise Agent Fleet Coordination
In large enterprise deployments with hundreds of agents, stonemem provides the shared memory layer that prevents duplicated work and conflicting actions.
// Compliance agent records an audit finding
mem_save({
content: "PCI DSS audit finding: S3 bucket acme-prod-logs has public read ACL. Ticket JIRA-4521 created. Deadline: 2026-06-30.",
namespace: "compliance",
tags: ["pci-dss", "s3", "critical"]
})
// Security agent checks for open findings before its scan
mem_search({
query: "open compliance findings s3",
namespace: "compliance",
tags: ["critical"]
})
// Avoids duplicating the ticket
Entity Graph for Organizational Knowledge
Over time, stonemem builds an entity graph that maps the relationships between people, projects, technologies, and decisions in your organization.
// After months of agent activity, query the entity graph
mem_entity_query({ query: "PostgreSQL" })
// Returns: mentioned 34 times, first seen March 2026, linked to:
// - "migration" (co-occurrence: 28 times)
// - "performance" (co-occurrence: 12 times)
// - "Alice Chen" (person, 8 co-occurrences — she's the DBA)
mem_entity_query({ query: "Alice Chen", entity_type: "person" })
// Returns: mentioned 45 times, linked to PostgreSQL, infrastructure, on-call
8. Tier Comparison
| Feature | Free | Pro ($9/mo) | Enterprise ($49/mo) |
|---|---|---|---|
| Entries | 10,000 | Unlimited | Unlimited |
| Namespaces | 1 ("default") | Unlimited | Unlimited |
| Full-text search (FTS5) | Yes | Yes | Yes |
| Basic recall | Yes | Yes | Yes |
| Entity graph | No | Yes | Yes |
| Temporal scoring | No | Yes | Yes |
| Supersession chains | No | Yes | Yes |
| Multi-agent shared memory | No | No | Yes |
| Team namespace federation | No | No | Yes |
| Usage analytics | No | No | Yes |
| Daily heartbeat | Yes | Yes | Yes |
| Support | Community | Priority email | Priority email |
All tiers require license registration. There is no anonymous usage. Free keys are issued instantly via Stripe checkout ($0).
9. License Management
Activation
# Activate with your key (received via email after checkout)
stonemem activate --key SM-XXXX-XXXX-XXXX-XXXX
# Check license status
stonemem status
# Output:
# License: Active
# Tier: Pro
# Key: SM-XXXX-****-****-XXXX
# Activated: 2026-06-10T04:00:00Z
# Next heartbeat: 2026-06-11T04:00:00Z
Heartbeat
stonemem sends a daily heartbeat to the license server. This is telemetry only — a missing heartbeat does not disable your software. The heartbeat reports:
- License key hash (not the full key)
- Current tier
- Entry count
- Version
No content, no queries, no agent data. The heartbeat response may carry a SIGIL die command if the key has been revoked.
Upgrading
# Upgrade from Free to Pro
# 1. Purchase Pro license at https://keystoneproject.dev/#pricing
# 2. You'll receive a new key via email
# 3. Activate the new key
stonemem activate --key SM-YYYY-YYYY-YYYY-YYYY
# Your data is preserved — only the tier changes
Key Revocation (SIGIL)
If a key is revoked (e.g., due to fraud or chargeback), the license server sends a SIGIL die command via the heartbeat response. The binary will gracefully shut down and require reactivation with a valid key.
10. Troubleshooting
Common Issues
Port already in use
# Check what's using port 3391
lsof -i :3391
# Use a different port
stonemem serve --port 3392
License activation fails
# Verify internet connectivity to license server
curl https://license.keystoneproject.dev/health
# Check key format (should be SM-XXXX-XXXX-XXXX-XXXX)
stonemem activate --key SM-XXXX-XXXX-XXXX-XXXX --verbose
Database locked errors
stonemem uses WAL mode, which supports concurrent reads. If you see lock errors, ensure only one stonemem process is writing to the same data directory.
# Check for multiple processes
ps aux | grep stonemem
# If stuck, the WAL can be checkpointed manually
sqlite3 ~/.stonemem/stonemem.db "PRAGMA wal_checkpoint(TRUNCATE);"
Free tier limit reached
# Check current usage
curl http://localhost:3391/stats
# If entry_count is near 10,000, upgrade to Pro
# Or delete old entries:
# (Note: stonemem does not expose a delete endpoint —
# supersede old entries or upgrade to Pro for unlimited storage)
MCP connection issues
# Test HTTP connectivity
curl http://localhost:3391/health
# For stdio transport, verify the binary is in PATH
which stonemem
# Check logs for connection errors
stonemem serve --log-level debug
Getting Help
- Email: [email protected]
- GitHub: github.com/keystoneproject/stonemem/issues