Athena Diary

Off-context journal for long-running Letta (and other MCP) agents

A SQLite-backed MCP server that gives agents a place to write freely, without stuffing narrative into core memory. Athena Diary ships as a small server with four tools, a turn-based sleeptime clerk, and an embeddings layer that returns summaries โ€” not bodies โ€” on search.

On the name. Athena Diary is named after Athena, SanctumOS's first long-running agent โ€” the user #1 of this pattern. The pattern is not Athena-only. Any agent host that speaks MCP can run an instance with its own diary database. Skip the "Athena's diary" reading; this is a module, not an instance.

Repository: sanctumos/athena-diary Status: v0.1.0 ยท License: AGPL-3.0 (code) ยท CC-BY-SA 4.0 (docs)

Read first: Athena Diary blog post ยท Full docs in the repo


What it is for

Audience What Athena Diary gives you
Agent builders MCP tools to capture and retrieve journal entries without growing core blocks
Operators running long-lived agents One SQLite file per agent, stdio or SSE MCP, an embed mode that fits your stack
Sleeptime / clerk passes A turn-based clerk that tags, lesson-families, links near-duplicates, and re-embeds

The shape follows Origin Conversation: SQLite for the durable store, MCP for the wire. The job is to keep the agent's free writing off the always-loaded budget.


Where it fits in the surface area

Hot agent / sleeptime companion / Cursor / Claude
        โ”‚  MCP (stdio or SSE)
        โ–ผ
  athena-diary MCP server
        โ”‚
        โ–ผ
  SQLite (entries + FTS5 + optional sqlite-vec on summaries)

Hot agent / sleeptime companion / Cursor / Claude โ”‚ MCP (stdio or SSE) โ–ผ athena-diary MCP server โ”‚ โ–ผ SQLite (entries + FTS5 + optional sqlite-vec on summaries)

Hot agent / sleeptime companion / Cursor / Claude
        โ”‚  MCP (stdio or SSE)
        โ–ผ
  athena-diary MCP server
        โ”‚
        โ–ผ
  SQLite (entries + FTS5 + optional sqlite-vec on summaries)

Athena Diary sits beside other SanctumOS surfaces. It doesn't replace any of them.

Surface Holds Trade-off
Core memory Always-loaded identity, active rules, the current window Every word is paid for on every turn โ€” keep this thin
Athena Diary Experiential noticing, lessons, first-person journal entries Off-context. Search returns summaries; body on demand
Letta archival Reference facts for structured recall Durable store of long-form recall material
Broca human block Intimate, medical, human-gated content Instructional privacy layer; not a writing surface

The key call: never paste diary bodies into core memory. Core may hold a skinny pointer โ€” an entry id, a lesson-family name, a date โ€” and nothing more. The diary is the surface for body-level free writing; core is the surface for thin always-loaded context.


MCP tools

The agent sees exactly four tools on the wire.

Tool Purpose When to use it
diary_write Append a free-form entry. Body required; optional summary and metadata. Whenever the agent notices something worth remembering, including running narrative.
diary_get Fetch one entry by id, returning the full body. When the agent has decided a specific entry is in scope and wants the body.
diary_search Keyword or semantic search. Returns ids and summaries, not bodies. First-pass recall. The agent then picks entries to diary_get for the body.
diary_sleeptime_pass Clerk pass over a batch: tags, lesson-family, templated summary, see-also links, re-embed. Run from the agent's sleeptime, in turn, on a frequency the agent decides.

Full wire shape per tool: TOOL_REFERENCE.md


What belongs where

Kind of content Surface Why
Experiential noticing ("the user prefers short answers when tired") Diary First-person lesson; retrieved on cue
Reference facts about the world ("the API returns JSON over HTTPS") Archival Stable, structured recall
Always-needed identity / active rules / current window Core Thin, always loaded
Intimate, medical, human-gated material Broca human block The human owns it; the diary does not
Diary bodies pasted into system prompts Don't That's a core-stuffing anti-pattern

The routing rule is short: free writing in the diary, recall in archival, identity in core, private in Broca. Mixing them by accident is the kind of mistake the agent will make without thinking; the module doc exists so the routing is explicit on the operator side.


Quick start

git clone https://github.com/sanctumos/athena-diary.git
cd athena-diary
python3 -m venv .venv && source .venv/bin/activate
pip install -e '.[mcp]'             # core install
# pip install -e '.[mcp,vec]'       # optional: add sqlite-vec KNN

export DIARY_DB=./db/athena-diary.db
export DIARY_EMBED_MODE=letta       # or 'external' + DIARY_EMBED_ knobs

athena-diary-mcp serve              # stdio transport (Letta / Cursor)
# athena-diary-mcp serve --sse      # optional HTTP SSE

git clone https://github.com/sanctumos/athena-diary.git cd athena-diary python3 -m venv .venv && source .venv/bin/activate pip install -e '.[mcp]' # core install

pip install -e '.[mcp,vec]' # optional: add sqlite-vec KNN

export DIARY_DB=./db/athena-diary.db export DIARY_EMBED_MODE=letta # or 'external' + DIARY_EMBED_ knobs

athena-diary-mcp serve # stdio transport (Letta / Cursor)

athena-diary-mcp serve --sse # optional HTTP SSE

Hot agent / sleeptime companion / Cursor / Claude
        โ”‚  MCP (stdio or SSE)
        โ–ผ
  athena-diary MCP server
        โ”‚
        โ–ผ
  SQLite (entries + FTS5 + optional sqlite-vec on summaries)

Attach the server to the hot agent and to the sleeptime companion. Client recipes across MCP clients: MCP_CLIENTS.md.

The first production attach was Athena + sleeptime on Sanctum, and that deploy is what validated the design โ€” but the install is the same install regardless of which agent runs it. One agent, one database, one connection.


Configuration

Variable Meaning
DIARY_DB Path to the SQLite file. One per agent in v1.
DIARY_EMBED_MODE letta โ€” share the host's embed stack. external โ€” bring your own embed API.
DIARY_EMBED_BASE_URL Required when DIARY_EMBED_MODE=external. OpenAI-compatible base URL.
DIARY_EMBED_MODEL Required when DIARY_EMBED_MODE=external. Model name (e.g. text-embedding-3-small).
DIARY_EMBED_API_KEY Required when DIARY_EMBED_MODE=external.
MCP_HOST / MCP_PORT Bind address when running --sse transport.

Full env and runtime options: CONFIGURATION.md

The cross-cutting rule on embeddings: the vector index holds summaries, not bodies. That keeps vector recall cheap and keeps the agent's context budget paid only on entries the agent has selected. With sqlite-vec available, KNN runs against the summary index. FTS5 indexes body and summary in parallel so a weak summary cannot silent-hole an entry.


Design notes (v1)

These are the postulates the module ships with; reading them is what saves you from re-discovering them.

  • No write gates. Volume belongs in the diary. The cost of writing is small; the cost of writing into core is cumulative, paid on every turn. The clerk cost is paid in batched sleeptime, not on every write.
  • Embed summaries; FTS for safety. The vector index never holds bodies. FTS5 runs as a parallel index on the same summaries so a query the embed model misses still surfaces the entry.
  • Sleeptime-only clerk path. Default v1. The agent runs diary_sleeptime_pass in turn, on a frequency the agent decides. A backlog CLI exists for manual ops, but it is not a cron job.
  • Sensitive material is not a diary concern. Intimate, medical, and human-gated content goes to the Broca human block. v1 ships with this routing as a rule, not a guideline, and the architecture is built so the diary cannot quietly become a vault.

Not in v1

The shape this far is the shape that ships. None of the following is in v1, on purpose, and the module will be honest about scope rather than marketing over it.

  • Per-human vaults. Single-agent-per-database. Multi-user vaults, partitioned diaries, per-human writes are not part of this design.
  • Auto-promote into core. The diary does not write back into core. Promoting an entry is the agent's choice.
  • Cron-as-clerk. The clerk is turn-based, not cron-based. Cron fires on time. Turn fires when the agent is paying attention.
  • Soft ACL over intimate text. There is no soft-ACL posture in this module; the rule is the rule.
  • Replacement for archival. Diary is the free-writing channel. Archival is the durable recall record. Two surfaces, two jobs.

See also