Skip to main content
Glama

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)

from sandbook import Memory, MemorySettings, MemoryEntry, …

in-process

Standalone server

python -m sandbook.mcp.standalone

streamable-HTTP — stochastic MCP at /mcp and thin engine RPC at /v1

Engine RPC client

from sandbook.client import MemoryClient, AsyncMemoryClient

sync + async over /v1

Memory web UIs

graph explorer at /graph, timeline at /memory/timeline (on the standalone server)

HTML over HTTP

Claude Code plugin

.claude-plugin/plugin.json (uv-launched stdio)

stdio MCP

Anthropic memory_20250818 adapter

sandbook.adapters.anthropic_memory.AnthropicMemoryTool

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.

Multi-surface architecture overview — four consumer surfaces (Python app, MCP client, /v1 HTTP client, Claude Code plugin) converge on one Memory facade (the MemoryLike protocol), which sits over the two-wheel split: sandbook-core, the always-present markdown floor backing the Markdown store and the SQLite timeline, and the sandbook engine — retrieval, storage, consolidation — backing the Chroma vector LTM and the Neo4j graph LTM.

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:

For per-persona quickstarts with verify and troubleshoot steps, see docs/integration.md.

Requirements

  • Python 3.11+

  • pip or uv

Install

NOTE

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 sandbook pulls sandbook-core automatically (it is a dependency) — you almost never install sandbook-core by hand. See Minimal footprint below for the one case you might.

Two-wheel install profiles — pip install sandbook-core gives the dependency-light markdown floor; pip install sandbook gives the engine wheel, which pulls sandbook-core. Additive extras layer on the engine: ltm-vector adds Chroma plus embeddings; ltm-graph adds Neo4j plus PPR and implies ltm-vector; mcp adds the servers, /v1, and web UIs; client adds the sync and async /v1 clients.

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 .md files are the source of truth for every memory

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 (recall_events) with no vector store required

Event-family registry

A typed registry for custom event kinds

A host registers and queries its own event families (register_event_family / query_by_family)

Memory Python API

The from sandbook import Memory facade — remember / recall / recall_events

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

pip install "sandbook[ltm-vector]"

ChromaDB vector store + sentence-transformers embeddings

Semantic recall over the whole corpus — find by meaning, not just keyword

ltm-graph

pip install "sandbook[ltm-graph]"

Neo4j knowledge graph + Personalized-PageRank retrieval (implies ltm-vector)

Multi-hop "what relates to X" recall over an entity/fact graph

mcp

pip install "sandbook[mcp]"

The stdio + HTTP MCP servers, the deterministic /v1 engine RPC, and the graph + timeline web UIs

Serve memory to Claude (and any MCP client) as a tool surface; inspect it in a browser

client

pip install "sandbook[client]"

The sync + async /v1 clients (sandbook.client)

Talk to a warm sandbook server over HTTP instead of embedding the engine — for hooks and non-MCP consumers

anthropic / agent-sdk

pip install "sandbook[anthropic]"

The Anthropic / Agent-SDK clients for LLM-backed consolidation + the memory_20250818 adapter

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 extras

from 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

uv run --all-extras sandbook-server

HTTP MCP, the /v1 engine RPC, and the web UIs at :8765 (/ home, /mcp, /v1, /graph, /memory/timeline)

mcp ltm-vector ltm-graph

uv run --extra mcp --extra ltm-vector --extra ltm-graph sandbook-stdio

stdio MCP server (the Claude Code plugin entry)

mcp ltm-vector ltm-graph

uv run sandbook-evals

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 8765

The 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/sandbook

Claude 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-memory

First-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=false

Verify the end-to-end chain with the built-in doctor command:

uv run sandbook-doctor

sandbook-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

SANDBOOK_MEMORY_DIR

— (required; no default)

markdown data root for from_env(); raises MemoryConfigError if unset (conventional value ~/.sandbook/memory)

SANDBOOK_CONSOLIDATORS_ENABLED

true

background consolidation

Neo4j / ChromaDB settings

see sandbook.config.toml

graph + vector backends

NOTE

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.

NOTE

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 --llm

Programmatic 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 /v1 client): 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 :8765 daemon autospawn, and the opt-out path.

  • docs/v1-api.md — the /v1 engine 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, /v1 health, CLI flags, env vars, authentication.

  • README_DEV.md — development workflow, independence testing, and publishing sandbook as a Claude Code plugin via a marketplace.

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

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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