thecodacus/understory

understory — memory that grows. Self-wiring, plain-markdown memory for AI agents (MCP + local models + a living graph).

understory – A self‑wiring markdown knowledge base for LLM agents

What it is

  • A lightweight, file‑based “memory” that agents can read, write, and query. The memory lives as a collection of plain‑markdown files that follow the Open Knowledge Format (OKF) v0.1 – each concept is a markdown file with a small YAML front‑matter block (type, etc.).
  • The repository ships a server that wraps this bundle with a tool‑calling interface (MCP), a React web UI, and a CLI. The server can be run locally (Docker or from source) and talks to any OpenAI‑compatible or Anthropic‑compatible LLM endpoint.

Key ideas

  1. Deterministic bundle layer – the code, not the LLM prompt, guarantees that every mutation produces a valid OKF bundle (front‑matter present, index files regenerated, log appended, paths sandboxed).
  2. Agent‑driven updates – the LLM is asked what to change; the server applies the change safely.
  3. Graph view & traces – concepts are visualised as a force‑directed graph (Obsidian‑style) and every agent interaction is recorded as a trace that can be replayed on the graph.
  4. Profiles – a single server can host many isolated memories, each selected by its own API key.
  5. Maintenance tool – memory_maintain lints the graph for orphaned concepts or broken links and asks the internal agent to repair them.

How you interact

Interface What it does
MCP server (/mcp or stdio) Provides the tool set memory_query, memory_add, memory_update, memory_status, memory_maintain. Calls are streamed, so the LLM can see tool results in real time.
Web UI (http://localhost:3800) Browse the bundle tree, see the live graph, view update logs, and chat with the same agent. Tool calls appear inline; traces can be replayed.
CLI (pnpm agent:query …, pnpm agent:mutate …) Quick command‑line access for testing or scripting.
Profiles CLI (`profiles create list

Quick start (Docker)

services:
  understory:
    image: ghcr.io/thecodacus/understory:latest
    ports: ["3800:3800"]
    extra_hosts: ["host.docker.internal:host-gateway"]
    volumes:
      - understory-memory:/bundle   # your markdown bundle lives here
    environment:
      BUNDLE_ROOT: /bundle
      LLM_API_BASE_URL: ${LLM_API_BASE_URL}
      LLM_API_KEY: ${LLM_API_KEY}
      LLM_API_FORMAT: openai   # or "anthropic"
      LLM_MODEL: ${LLM_MODEL:-}
docker compose up -d   # UI at http://localhost:3800, MCP at http://localhost:3800/mcp

You can point the server at any OKF bundle (local folder, named volume, or bind‑mount). The LLM endpoint can be OpenAI, DeepSeek, Anthropic, Groq, or a locally‑run llama.cpp server.

Typical workflow

  1. Start a session – the server injects a concise overview of the current knowledge base into the LLM’s system prompt and the memory_query tool description.
  2. Ask the agent – e.g. memory_query "What is our deployment schedule?".
  3. Add new fact – memory_add "We deploy on Fridays, never Mondays". The agent creates a markdown concept, updates backlinks, and the UI instantly shows the new node.
  4. Maintain – run memory_maintain periodically (or schedule it) to auto‑fix orphans and broken links.
  5. Replay – open a trace in the UI to see exactly which concepts were read/written during the interaction.

Why use it?

  • Human‑readable & version‑controlled – the memory lives in plain markdown, diffable in Git, so you can audit changes or roll back.
  • Model‑agnostic – works with any LLM that supports tool calling; the server does the heavy lifting.
  • Self‑organising – the internal agent keeps the graph tidy, reducing drift as the knowledge base grows.
  • Multi‑tenant – profiles let you keep separate knowledge graphs (work, health, side‑project) on the same host.

Limitations / current scope

  • Search is a simple linear scan; it scales to a few thousand concepts but isn’t yet a full‑text index or embedding‑based retrieval.
  • The UI is a single‑page React app; no authentication beyond a bearer token (recommended only for LAN use).
  • Graph‑level schemas (typed entities, richer relationships) are planned but not implemented.

Getting involved

  • Run the repo from source with pnpm install && pnpm build; the monorepo contains core, server, and web packages.
  • Tests (pnpm test) cover bundle validation, concurrency, and the MCP round‑trip.
  • Contribute via issues/PRs on GitHub; the project is MIT‑licensed and welcomes extensions (e.g., FTS5/embedding search, custom page‑type schemas).

Understory lets you give your LLM agents a persistent, editable, and visual knowledge graph that lives in plain markdown – a “memory that grows” without locking you into proprietary databases.

Related

  • Project
  • Project
  • Project
  • Project
  • Project