Skip to main content
Glama

Montauk

Relationship memory for personal agents: durable, private, structured memory of the people in one person's life, with a web dashboard for the owner and an MCP server for their agent.

The canonical store is PostgreSQL, workspace-scoped, with field-level revision history. An agent reaches it over an authenticated MCP endpoint; the owner curates it through a server-rendered web dashboard. montauk_phase2_build_and_migration_spec.md and docs/adr/ are the design record.

Montauk began as a Markdown-file store with a stdio MCP server (montauk_phase1_build_spec.md). That store and its server were removed once the PostgreSQL store, the migrator that imported it, and this MCP surface were all live. The retrieval engine (person_context.py) and the local semantic index (semantic_index.py, now PostgreSQL-backed -- ADR 0005) carried over.

Identity vs. name. Each person has a permanent, generic ID (P0001, P0002, ...) that Montauk assigns and never changes or reuses. The person's name is just the best label currently known -- it can be partial or wrong at first and corrected later with update_person_name (former spellings are kept as searchable aliases), without touching the ID.

Briefing-first retrieval. The normal agent call is prepare_person_briefing(person_id, purpose, detail_level, mode): it selects the relevant curated evidence, compresses it with a configured low-cost model into a short, factual, purpose-specific briefing, and returns that plus lightweight source_refs. The agent drills into individual records with get_context_sources / get_facts / get_interactions only to verify a claim or get detail the briefing left out. A narrow factual question ("what is X's birthday?") is answered from the structured field with no model call. prepare_person_context is the deterministic, no-LLM path -- ranked raw records, hybrid BM25 + semantic retrieval, no synthesis. search_people matches names, aliases and contact details, and also vague descriptions ("the robotics guy from the MIT mixer") by semantic similarity over facts and interactions. Montauk never generates advice, quotations, or missing facts; that is the agent's job.

Running it

uv sync
export MONTAUK_DATABASE_URL=postgresql://user:pass@localhost:5432/montauk
export MONTAUK_MASTER_KEY=$(python -c "import base64,os;print(base64.b64encode(os.urandom(32)).decode())")

uv run montauk db upgrade      # create / update the schema
uv run montauk dashboard       # http://127.0.0.1:8817  (first visit = setup wizard)
uv run montauk mcp             # http://127.0.0.1:8766/mcp  (agent endpoint)
  • MONTAUK_MASTER_KEY (32 bytes, base64) encrypts stored model-provider API keys. Without it, briefings fall back to the deterministic evidence packet.

  • Both servers refuse to start against a stale schema; run montauk db upgrade after a pull.

  • Semantic search uses a local embedding model (fastembed, all-MiniLM-L6-v2, ~90 MB), downloaded from Hugging Face on first use. Set FASTEMBED_CACHE_PATH to a persistent, writable directory (the default is under /tmp). The index maintains itself on read; montauk semantic status reports coverage and montauk semantic rebuild warms it after a deploy. If the model can't load, retrieval falls back to lexical and reports semantic_available: false.

  • Put a TLS-terminating reverse proxy in front for anything beyond loopback. One hostname can serve both: route /mcp* to the MCP port, everything else to the dashboard (docs/deploy-phase2-shared-host.md).

Related MCP server: Link

Agent access

Create a bearer token for the agent in the dashboard (Settings -> agent tokens), then point an MCP-compatible host at the streamable-HTTP endpoint with Authorization: Bearer <token>. Every request is authenticated against the workspace's agent_credentials; the memory_read and memory_write capabilities gate reads and writes per tool.

The MCP surface: search_people, prepare_person_briefing, get_context_sources, prepare_person_context, get_person / get_facts / get_interactions / get_full_record, list_people, get_upcoming_birthdays, list_overdue_contacts, get_connector_health, and the write tools (create_person, add/update/remove fact, record/update/remove/reattribute interaction, contact/summary/name/birthday/cadence, update_person_batch, archive/restore).

Sources

Two ways to archive real conversations (both sides, text only — no attachments):

  • Manual import — WhatsApp chat exports (.txt), on the Transcripts page.

  • WhatsApp connector — a receive-only linked device (Baileys sidecar) that syncs enabled conversations continuously. Connectors → Connect WhatsApp. It never sends, replies, or marks anything read. Setup: docs/adr/0004-whatsapp-inbound-connector.md and sidecars/whatsapp/README.md.

Archived messages are immutable evidence; you map each sender to a person, then the extraction model turns new messages into facts and per-day interaction summaries.

Model provider

Briefings need a low-cost model, configured per purpose in Settings -> Model & provider:

  • Local claude / codex CLI -- reuses the machine's Claude Code / Codex subscription auth; no API key. Extended thinking is disabled for these (every task here is compression, not reasoning).

  • Anthropic API or an OpenAI-compatible endpoint -- with a stored, encrypted API key.

Month-to-date usage, a spend/token ceiling, and a hard pause switch live under Settings -> LLM cost controls.

Development

uv sync
uv run pytest              # needs Docker (spins a postgres testcontainer) or MONTAUK_TEST_DATABASE_URL
uv run ruff check . && uv run ruff format --check && uv run mypy

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Enables AI agents to maintain a persistent, queryable memory stored as user-owned Markdown files, with dual-channel retrieval (FTS5 and optional semantic search) and an audited write pipeline.
    11
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to capture, structure, remember, and retrieve source-backed memory as local Markdown files, with reviewable writes and no cloud dependency.
    216
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Local-first memory for AI agents about the people in your life. MCP server + CLI on SQLite. Never phones home.
    41
    81 PyPI
    58
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents like Codex, Grok Build, and Antigravity to share persistent local memory, preferences, project context, tasks, and handoffs using Markdown and SQLite.
    1
    MIT