sandbook
Click on "Install 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., "@sandbookremember that the project deadline is next Friday"
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.
sandbook
A multi-tiered memory subsystem for AI agents — markdown + vector + graph long-term memory — usable as a standalone memory MCP server for Claude, independent of any host application.
sandbook is a dependency-light Python package that works standalone: in a clean virtualenv, from sandbook import Memory works with no host application on the path.
What you get
Surface | Entry point | Transport |
Python library (embedded) |
| in-process |
Standalone server |
| streamable-HTTP — stochastic MCP at |
Engine RPC client |
| sync + async over |
Memory web UIs | graph explorer at | HTML over HTTP |
Claude Code plugin |
| stdio MCP |
Anthropic |
| Messages API memory tool |
The embedded Memory and the AsyncMemoryClient both satisfy the MemoryLike operations protocol (sandbook.operations), so a consumer can run the engine in-process or talk to a warm server without changing call sites.
The public API (50 names) is whatever sandbook/__init__.py re-exports. Everything heavier — the MCP transports (sandbook.mcp), the on-disk config (sandbook.config), the timeline subsystem (sandbook.timeline), and the adapters (sandbook.adapters) — lives in sub-namespaces that are not auto-imported, keeping the core import light.
Related MCP server: Recall
Pick your path
sandbook exposes three integration surfaces (Python API · MCP server · Claude Code plugin), plus the /v1 RPC client and web UIs. Jump to the section that fits your use case:
Plugin user — wire memory into Claude Code sessions via hooks; no Python code required.
Library embedder —
import sandbookand drive the engine in-process.MCP server / remote client — run a warm server and connect any MCP client or the
/v1RPC to it.
For per-persona quickstarts with verify and troubleshoot steps, see docs/integration.md.
Requirements
Python 3.11+
pip or uv
Install
sandbook is alpha and not yet on PyPI — install from source today (see the uv sync commands below). The pip install lines describe the published-package shape for when the package reaches general availability.
pip install sandbook is the base install — it gives you the base memory layer with only light dependencies (pydantic, loguru, pyyaml), and pip install "sandbook[…]" layers on the heavier capability tiers. The import path is identical either way (from sandbook import Memory) — installing an extra upgrades the same import in place.
pip install sandbook # base memory — start here
pip install "sandbook[ltm-vector]" # + semantic (vector) long-term memory
pip install "sandbook[ltm-vector,ltm-graph,mcp]" # + graph LTM + the MCP server
# With uv, from the sandbook/ checkout:
uv sync # base memory only
uv sync --extra mcp # + the server + web UIs (one extra)
uv sync --all-extras # everything, incl. the ML deps
pip install sandbookpullssandbook-coreautomatically (it is a dependency) — you almost never installsandbook-coreby hand. See Minimal footprint below for the one case you might.
Base memory (pip install sandbook)
The base install needs no heavy backends (no ChromaDB / Neo4j / ML deps). It composes six pieces:
Piece | What it is | Why it's useful |
Markdown stores | Human-readable | Inspectable, diffable, portable; survives any backend swap; the floor every heavier tier rebuilds from |
Scratchpad | A working-memory note the agent reads and writes within a session | Holds in-progress reasoning and intermediate state without polluting long-term memory |
Session log | An append-only write-ahead log of the conversation turns | Lets recall reconstruct "what we just discussed" and feeds the consolidation pipeline |
Timeline (SQLite) | A queryable event overlay over the markdown entries | Episodic "when did we discuss X" enumeration ( |
Event-family registry | A typed registry for custom event kinds | A host registers and queries its own event families ( |
| The | One object, identical across every profile; degrades to the markdown floor when no engine tier is installed |
Capability tiers (extras)
Each extra is additive — pick the smallest set that covers what you need. The LTM (long-term-memory) store tiers are named for what they are, not the generic "memory".
Extra | Install | Adds | Why you'd add it |
ltm-vector |
| ChromaDB vector store + sentence-transformers embeddings | Semantic recall over the whole corpus — find by meaning, not just keyword |
ltm-graph |
| Neo4j knowledge graph + Personalized-PageRank retrieval (implies | Multi-hop "what relates to X" recall over an entity/fact graph |
mcp |
| The stdio + HTTP MCP servers, the deterministic | Serve memory to Claude (and any MCP client) as a tool surface; inspect it in a browser |
client |
| The sync + async | Talk to a warm sandbook server over HTTP instead of embedding the engine — for hooks and non-MCP consumers |
anthropic / agent-sdk |
| The Anthropic / Agent-SDK clients for LLM-backed consolidation + the | Higher-quality reflection/consolidation when an LLM is available (degrades to deterministic when it isn't) |
Minimal footprint: sandbook-core
sandbook ships as two wheels under one sandbook import namespace (dec-036). pip install sandbook is the engine wheel; it pulls sandbook-core automatically, so most users never install sandbook-core directly — exactly like pip install langchain pulls langchain-core. The one case for installing it alone is an embedded, size-constrained consumer that wants only the base-memory layer above with zero engine modules on disk:
pip install sandbook-core # markdown floor only — no engine code, no extrasfrom sandbook import Memory is identical for both; the core-only profile degrades to the markdown floor. See Install profiles (two wheels) for the full contract and the degradation semantics.
Run the parts (uv)
From the sandbook/ directory, uv runs each part of the system through its console entry points. The heavy backends are optional extras, so pass them on the uv run line (or use --all-extras):
Command | Runs | Extras |
| HTTP MCP, the |
|
| stdio MCP server (the Claude Code plugin entry) |
|
| deterministic memory-quality eval suite | core only |
Each entry point is also a plain module — python -m sandbook.mcp.standalone, python -m sandbook.mcp.stdio, python -m sandbook.evals — for non-uv environments.
Run as a memory MCP server for Claude
The standalone server is agentless: it builds a Memory from the environment via Memory.from_env() and serves the full memory + graph tool set over streamable-HTTP at /mcp.
uv run --all-extras sandbook-server --host 0.0.0.0 --port 8765
# or, without uv:
python -m sandbook.mcp.standalone --host 0.0.0.0 --port 8765The same server also hosts the memory web UIs, so it doubles as a memory-inspection dashboard. Open http://localhost:8765/ for the home menu; a shared top-nav links the memory timeline (/memory/timeline), reflection history (/memory/reflections), and the knowledge-graph explorer (/graph).
The graph explorer mounts only when the graph tier is enabled. Set SANDBOOK_GRAPH_ENABLED=true and a reachable Neo4j (SANDBOOK_GRAPH_NEO4J_URI, SANDBOOK_GRAPH_NEO4J_USER, SANDBOOK_GRAPH_NEO4J_PASSWORD); otherwise the Graph entry is shown disabled and /graph returns 404. These can be passed as env vars or kept in a .env file (auto-loaded from the working directory, or --env-file PATH) — copy .env.example to .env and fill it in; .env is gitignored, so the password stays out of git. Resolution precedence is env vars > .env > sandbook.config.toml [graph] > defaults. (Live timeline SSE reflects this server's own activity; cross-process events appear as history on query.)
Connect Claude Code to it — via the CLI:
claude mcp add --transport http sandbook-memory http://localhost:8765/mcp…or in a project / user .mcp.json:
{
"mcpServers": {
"sandbook-memory": {
"type": "http",
"url": "http://localhost:8765/mcp"
}
}
}Then /mcp inside Claude Code lists sandbook-memory and its tools.
Other MCP clients
The same package ships a stdio entry point (python -m sandbook.mcp.stdio) that any stdio-MCP client launches as a subprocess. Each snippet below assumes sandbook[mcp,ltm-vector,ltm-graph] is installed in the Python environment that python resolves to.
Claude Desktop — add to claude_desktop_config.json:
{
"mcpServers": {
"sandbook-memory": {
"command": "python",
"args": ["-m", "sandbook.mcp.stdio"],
"env": { "SANDBOOK_MEMORY_DIR": "~/.sandbook/memory" }
}
}
}Cursor — add to the project's .cursor/mcp.json (same shape):
{
"mcpServers": {
"sandbook-memory": {
"command": "python",
"args": ["-m", "sandbook.mcp.stdio"]
}
}
}ChatGPT / Codex — declare the same stdio command in the client's MCP config (the OpenAI MCP spec uses the same command + args shape).
Gemini — Gemini speaks MCP over HTTP. Run the standalone HTTP server (uv run --all-extras sandbook-server) and point Gemini's MCP bridge at http://localhost:8765/mcp.
Install as a Claude Code plugin
sandbook ships a Claude Code plugin manifest (.claude-plugin/plugin.json) that launches its memory MCP server over stdio via uv. Claude Code clones the plugin and runs the server for you — no manual pip install, no separate server process.
The fully-local path (no marketplace, no publishing) loads the plugin straight from your checkout:
claude --plugin-dir /path/to/sandbookClaude Code reads .claude-plugin/plugin.json, launches sandbook-memory via uv run --project mcp/sandbook-memory python -m sandbook_memory_mcp (which builds an isolated, cached venv from mcp/sandbook-memory/pyproject.toml on first launch), and the memory + graph tools appear under /mcp.
Prewarm the plugin venv before first launch to avoid a multi-minute download inside a live Claude session:
uv sync --project mcp/sandbook-memoryFirst-launch timing. On first use, uv downloads sentence-transformers and its transitive dependencies (several hundred MB, potentially 1–3 GB with CUDA wheels). This is a one-time cost — subsequent launches start in under a second from the cached venv.
Data safety under uninstall. Plugin memory lives at the configured memory_dir (default ~/.sandbook/memory) — outside the sandbook checkout and outside Claude Code's plugin data directory. Uninstalling the plugin or deleting the repo does not remove your memories. To relocate or remove memory before uninstalling, move or delete your configured memory_dir. Note: ~/.sandbook/plugin is the hook cursor-file root (SANDBOOK_PLUGIN_DATA_ROOT) and the legacy path used by pre-update installs; your actual memories live at memory_dir. See Host Integration Contract § 4.
Disable autospawn. By default the hooks auto-start the sandbook daemon when it is not running. To manage the daemon yourself (e.g. with a process supervisor), set:
export SANDBOOK_HOOK_AUTOSPAWN=falseVerify the end-to-end chain with the built-in doctor command:
uv run sandbook-doctorsandbook-doctor checks the hook registration, store-path coherence, daemon reachability, the /v1/recall contract, and LLM consolidation wiring — and prints a three-part fix for anything that is broken.
To publish sandbook for others via a marketplace, see README_DEV.md.
Use as a library
from sandbook import Memory, MemoryCategory
memory = Memory.from_env() # data root from SANDBOOK_MEMORY_DIR
await memory.startup_check()
await memory.remember("the user prefers dark mode", category=MemoryCategory.PREFERENCE)
response = await memory.recall("ui preferences") # the semantic read → MemoryResponse
print(response.context)The core verbs are remember (write) and recall (the semantic read); recall_events(topic, since=…, until=…) is the episodic "when did we discuss X" enumeration. To talk to a warm server instead of embedding the engine, swap Memory for sandbook.client.AsyncMemoryClient (same recall/remember surface over /v1).
Configuration
Selected variables; the full model is MemorySettings over sandbook.config.toml:
Env var | Default | Meaning |
| — (required; no default) | markdown data root for |
|
| background consolidation |
Neo4j / ChromaDB settings | see | graph + vector backends |
All environment variables areSANDBOOK_*. SANDBOOK_MEMORY_DIR is required and has no default — from_env() raises MemoryConfigError when it is unset; ~/.sandbook/memory is only the conventional location (and the plugin manifest's default). The other path settings do default under ~/.sandbook/ (e.g. SANDBOOK_MEMORY_VECTOR_STORE_PATH → ~/.sandbook/chroma) — defaults, not hard constants — override them via environment, TOML, MemorySettings, or Memory(memory_dir=...). Data written by earlier sandbook versions under the legacy ~/.francisco data root can be moved with the one-shot sandbook-migrate-chroma-path script (dry-run by default; --apply performs the move).
Evaluate memory quality
sandbook ships an independent eval suite that reports the current state, quality, behaviour, and performance of the memory system. It drives the public Memory API with synthetic scenarios and scores four groups — Correctness, Quality, Behaviour, Performance — fully deterministically (zero network/LLM). An optional LLM-judged Cognition group runs when you provide a callback.
The suite installs synthetic test entries, so it runs against anisolated, fresh memory dir by default — your real ~/.sandbook/memory is never touched.
# With uv: `uv run sandbook-evals [args]`. Without uv: `python -m sandbook.evals [args]`.
# Deterministic report (text)
uv run sandbook-evals
# JSON, one group, or a single scenario
uv run sandbook-evals --json
uv run sandbook-evals --group correctness
uv run sandbook-evals --scenario abstention
# Also run the LLM-judged cognition group (needs the anthropic extra + ANTHROPIC_API_KEY)
uv run --extra anthropic sandbook-evals --llmProgrammatic use (pass any Memory; inject llm_callback to enable cognition):
from sandbook.evals import run_memory_evals, format_text_report
report = await run_memory_evals(memory) # deterministic
print(format_text_report(report))
print(report.composite_score, report.below_threshold)The exit code is non-zero when any scored scenario falls below its threshold (CI-friendly). An MCP tool run_memory_eval is also exposed by the standalone server (it runs against an isolated instance). Authoring new scenarios: drop YAML into sandbook/evals/scenarios/ — see README_DEV.md.
Documentation
Start here by goal:
docs/integration.md — per-persona quickstarts (plugin user / library embedder / remote
/v1client): install → configure → verify → troubleshoot, plus the embed lifecycle.docs/configuration.md — config precedence, per-topology patterns, the consolidation-ownership matrix, secrets, and reserved knobs.
docs/hooks.md — the four Claude Code plugin hooks, the six env toggles, the
:8765daemon autospawn, and the opt-out path.docs/v1-api.md — the
/v1engine RPC guide (quickstart + conventions); the generated per-route reference is docs/openapi/v1-reference.md.docs/upgrading.md — migration steps,
sandbook-migrate-*commands, and the deprecation schedule.docs/deployment.md — deployment and security: the per-surface auth posture and safe binding patterns.
Reference and internals:
docs/memory_system.md — the memory system itself: five tiers, retrieval depths, consolidation pipeline, self-healing, knowledge graph, full configuration reference.
docs/host_integration.md — the consumer contract: versioning,
/v1health, CLI flags, env vars, authentication.README_DEV.md — development workflow, independence testing, and publishing sandbook as a Claude Code plugin via a marketplace.
This server cannot be installed
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/francisco-perez-sorrosal/sandbook'
If you have feedback or need assistance with the MCP directory API, please join our Discord server