sandbook

sandbook

A multi-tiered memory subsystem for AI agents with markdown, vector, and graph long-term memory, usable as a standalone memory MCP server for Claude.

Category
Visit Server

README

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.

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)

<details> <summary>Full extras reference (ltm-vector · ltm-graph · mcp · client · anthropic / agent-sdk)</summary>

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)

</details>

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 are SANDBOOK_*. 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 an isolated, 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.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured