{"id":50172649,"url":"https://github.com/fjwood69/mori","last_synced_at":"2026-07-21T20:01:56.436Z","repository":{"id":359567233,"uuid":"1236820003","full_name":"fjwood69/mori","owner":"fjwood69","description":"mori MCP server — A shared memory layer for AI coding agents — one that compounds.","archived":false,"fork":false,"pushed_at":"2026-06-01T13:43:24.000Z","size":789,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-01T14:14:05.684Z","etag":null,"topics":["ai-agents","anthropic","claude-code","dream-pipeline","llm","mcp","mcp-server","memory","multi-agent","persistent-memory"],"latest_commit_sha":null,"homepage":"https://moriapp.dev/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fjwood69.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-12T15:50:04.000Z","updated_at":"2026-06-01T13:50:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/fjwood69/mori","commit_stats":null,"previous_names":["fjwood69/mori"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/fjwood69/mori","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjwood69%2Fmori","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjwood69%2Fmori/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjwood69%2Fmori/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjwood69%2Fmori/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fjwood69","download_url":"https://codeload.github.com/fjwood69/mori/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fjwood69%2Fmori/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33990887,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-06T02:00:07.033Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","anthropic","claude-code","dream-pipeline","llm","mcp","mcp-server","memory","multi-agent","persistent-memory"],"created_at":"2026-05-25T00:09:23.206Z","updated_at":"2026-07-21T20:01:56.425Z","avatar_url":"https://github.com/fjwood69.png","language":"Python","funding_links":["https://ko-fi.com/moriapp"],"categories":[],"sub_categories":[],"readme":"![mori — A governed shared memory layer for AI coding agents](https://raw.githubusercontent.com/fjwood69/mori/main/docs/assets/header-dark-v0_1_5.svg)\n\n**Mori (森) — a governed shared-memory layer for AI coding agents.**\n\nMori gives an agent provenance-scoped memory: the decisions and patterns a human chose to\nkeep, surfaced to every session — and only where they apply. It's the institutional memory\nyour agents pull from, self-hosted and agent-neutral, so the knowledge outlives whichever\nmodel you're using this year.\n\nWhat it doesn't do — and I tested this at length — is *control* what an agent does. No memory\nlayer can. Across a multi-model, multi-harness stress test (**5,000+ runs, a dozen models**),\nthe most capable coding model broke the build *every time*; the *same* model did the right\nthing, then the wrong thing, on identical input; and an agent handed a tool that flagged its\nown change as build-breaking **read the warning and shipped the break anyway**. Capability\ndoesn't fix this, and neither does better retrieval. What holds is **enforcement at a boundary\nthe agent can't reach** — and that's a separate piece of work.\n\n\u003e 📄 **The research behind this** — the Promotion-Boundary Governance Framework: what can and\n\u003e can't actually be enforced on an AI coding agent, every null, every retraction.\n\u003e **[Read the whitepaper →](https://moriapp.dev/pbgf)**\n\n---\n\n## Why use mori?\n\nYou're right to be sceptical of \"memory systems\" — most are a vector DB with a retrieval\nprompt bolted on. So I ran the experiments, published the nulls, and lead with the result\nthat held up.\n\n**The failure mode mori fixes is cross-contamination.** Curation decides *what to keep*;\n**provenance** decides *where it's valid* — and across a team's many repos that's the line\nbetween a shared brain and a liability. A memory that's true in one repo, surfaced while you\nwork another, makes the agent confidently reach for an API that doesn't exist here —\n*retrieval interference*. I reproduced it and the fix: with out-of-scope memory in the brief,\nagents chased phantom APIs in **20/20 runs**; with provenance-safe scoping (`MORI_BRIEF_SCOPE`,\non by default), **0/20** — across two independent frontier-class models (Fisher *p* ≈ 0). The\nmemory was deliberately seeded from a prior repo, so it's a stress test of what canon-drift\ndoes over months, not a natural-incidence rate — but the mechanism is clean and\nmodel-independent. **Ungated memory isn't shared memory — it's cross-contamination.**\n\n**The other failure mode is obedience — and it's where mori is going, not where it is today.**\nProvenance fixes what an agent *knows*; it doesn't fix what an agent *does*. In a pre-registered\ncross-repo benchmark, I gave frontier agents a tool to see downstream impact *and* a\nplain-language warning that a change would break a build — and they broke it anyway, **15/15**,\nacross four models and three harnesses. *Information without enforcement is fatal — you cannot\ngovern an enterprise in token-space.* That result is the thesis behind mori's *next* layer:\n**governed playbooks** — a deterministic, pre-compute gate that checks a repo's lockfiles\nagainst human-approved patterns and refuses an unsafe migration *before it runs*, independent\nof prompt wording or model obedience. *(Scope: pre-registered npm-dependency migrations; the\ngate is built and benchmarked, **not yet a shipped product surface** — I lead with what I\nproved, not what I hope. The full argument is the [whitepaper](https://moriapp.dev/pbgf).)*\n\n---\n\n## Multi-Instance Visibility\n\n![One Forest, Many Agents](https://raw.githubusercontent.com/fjwood69/mori/75c495f3f49e9ee53645bbe0de7aa11da43ad50d/docs/assets/figure-5-one-forest.svg)\n\nIf you run AI coding agents across multiple machines, profiles, or in a team — one focused on the API layer, another on the frontend, a third on infrastructure — you already know the problem: each instance is brilliant in isolation, but none of them know what the others decided.\n\nInstance B doesn't know that Instance A just changed the auth contract. Instance C\ndoesn't know that Instance B's deployment assumptions shifted. They find out the\nhard way, mid-task, when something breaks.\n\nMori gives every instance the same **shared picture**. Every coding agent instance sends\nits session events to the shared Mori server; the dream pipeline distils those events from\n**all instances** into a unified memory store, and `/brief` surfaces them at the start of\nany session. Be clear about what that buys, though: a shared picture is **visibility, not\ncoherence you can bank on**. Surfacing what Instance A decided does not make Instance B act\non it — a coding agent can read another instance's change and proceed against it anyway (I\nmeasured exactly that, 15/15). So this is real value for a *cooperative* team — everyone\nopens a session knowing what the others changed — but it is **awareness, not enforcement**.\nMaking one instance actually honour another's decision is the enforcement problem, and where\nit can be solved at all it's solved at the promotion boundary on the committed artifact —\nnot by what any session was shown.\n\n---\n\n## Quickstart\n\n![Runs Anywhere](https://raw.githubusercontent.com/fjwood69/mori/75c495f3f49e9ee53645bbe0de7aa11da43ad50d/docs/assets/figure-3-runs-anywhere.svg)\n\n### 1. Deploy your server\n\nEvery Mori instance is yours — deployed into your own account, never shared.\nPick a path:\n\n**Cloud — deploy into your own account:**\n\n| | Platform | Persistence | ~Cost |\n|---|---|---|---|\n| [![Deploy on Railway](https://railway.app/button.svg)](https://railway.app/new/template?template=https://github.com/fjwood69/mori) | **Railway** + free Postgres ([Neon](https://neon.tech) / [Supabase](https://supabase.com)) | ✅ free Postgres | ~$5/mo + $0 Postgres |\n| [![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](https://render.com/deploy?repo=https://github.com/fjwood69/mori) | **Render** (persistent disk in config) | ✅ SQLite on disk | ~$7/mo |\n| [![Run on Google Cloud](https://storage.googleapis.com/cloudrun/button.svg)](https://deploy.cloud.run/?git_repo=https://github.com/fjwood69/mori) | **Cloud Run** + free Postgres ([Neon](https://neon.tech) / [Supabase](https://supabase.com)) | ✅ free Postgres | Pay-per-use |\n| [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/fjwood69/mori) | **GitHub Codespaces** — evaluate Mori with no local setup | ⚠️ ephemeral | free tier |\n\n**Fly.io (CLI):** free persistent volume + SQLite, ~$3–5/mo — see [one-click-deploy.md](docs/getting-started/one-click-deploy.md).\n\n\u003e **Persistence note:** SQLite needs a persistent disk or volume; stateless platforms\n\u003e (Railway, Cloud Run, Render free tier) lose data on restart without Postgres. The deploy\n\u003e script and guide walk through connecting a free Neon or Supabase database — the recommended\n\u003e $0 durable path. Codespaces are ephemeral by design — use them to evaluate Mori, then\n\u003e deploy to a persistent host when you're ready.\n\nFull guide: [docs/getting-started/one-click-deploy.md](docs/getting-started/one-click-deploy.md)\n\n\u003cimg src=\"https://brew.sh/assets/img/homebrew.svg\" width=\"20\" alt=\"Homebrew\"\u003e **macOS (Homebrew):**\n\n```bash\nbrew tap fjwood69/mori\nbrew install mori\nmori-setup   # wizard: API key, LLM provider, start service\n```\n\n**Or run locally with Docker Compose:**\n\n```bash\ngit clone https://github.com/fjwood69/mori.git\ncd mori\ncp deploy/homelab/.env.example deploy/homelab/.env\n# Edit .env: set MORI_API_KEY to your provider key (Novita, DeepInfra, OpenAI, …)\n# and MORI_BASE_URL to the provider's OpenAI-compatible endpoint.\ndocker compose -f deploy/homelab/docker-compose.yml up -d\n```\n\n### 2. Verify\n\n```bash\ncurl http://localhost:8968/health\n# {\"status\":\"ok\",\"service\":\"mori-advisor\"}\n```\n\n### 3. Connect your agent\n\n**Claude Code — install as a plugin (recommended).** Inside Claude Code, run:\n\n```\n/plugin marketplace add fjwood69/mori\n/plugin install mori@mori\n```\n\nYou'll be prompted for your Mori server URL and API key on enable (the key is stored\nin your OS keychain, not in `settings.json`). Then `/reload-plugins` or restart.\n\nThe same plugin package (`plugins/mori/`) also targets **OpenCode**, **Codex**,\n**Cursor**, and **Google Antigravity** — MCP connection and skills work across all five;\nclient-specific hooks land per platform. See the platform guides.\n\n**Or use the legacy installer scripts** (bespoke; superseded by the plugin):\n\n```bash\n./scripts/legacy/install-mori-claude.sh   # Claude Code\n./scripts/install-mori-cursor.sh          # Cursor\npowershell -File scripts/legacy/install-mori-claude.ps1   # Windows\n```\n\n### Platform guides\n\n| Platform | Install | Full guide |\n|----------|---------|------------|\n| Claude Code | Plugin: `/plugin marketplace add fjwood69/mori` → `/plugin install mori@mori` (or `./scripts/legacy/install-mori-claude.sh`) | [docs/getting-started/claude-code.md](docs/getting-started/claude-code.md) |\n| OpenCode | `./scripts/install-mori-opencode.sh` (or `.\\scripts\\install-mori-opencode.ps1` on Windows) | [docs/getting-started/opencode.md](docs/getting-started/opencode.md) |\n| Codex | Plugin package `plugins/mori/` → `codex plugin install mori` | [docs/getting-started/codex.md](docs/getting-started/codex.md) |\n| Cursor | Plugin package `plugins/mori/` (or `./scripts/install-mori-cursor.sh`) | [docs/getting-started/cursor.md](docs/getting-started/cursor.md) |\n| Google Antigravity IDE | Plugin package `plugins/mori/` (or `./scripts/install-mori-antigravity.sh`) | [docs/getting-started/antigravity.md](docs/getting-started/antigravity.md) |\n| Cline | `./scripts/install-mori-cline.sh` | [docs/getting-started/cline.md](docs/getting-started/cline.md) |\n\n---\n\n## Capabilities\n\n| Capability | What it does | Slash command |\n|-----------|-------------|---------------|\n| **Dream pipeline** | Auto-distils session events into structured memories | `/dream` |\n| **Session grounding** | Loads shared context at session start — not per-query RAG; lightweight delta re-grounding after context compaction | `/brief`, `/brief --post-compact` |\n| **Memory search** | Ranked full-text search and browse across the shared store (SQLite FTS5 / Postgres `tsvector`) | `/pensieve` |\n| **Web dashboard** | Built-in memory browser served at the mori root URL — search, browse, unfurl | — |\n| **Universal ingestion** | Feed PDFs, images, git, transcripts into the memory store | `/ingest` |\n| **Strategic review** | LLM guidance with focus areas and auto-injected standards | `/consult` |\n| **Requirements tracking** | Lightweight project checklist surfaced via `/brief` | `/req` |\n| **Governance** | Capability-scoped API keys (read/write/dreamer roles), versioning, trusted dreamers, rollback, attribution; a universal in-transaction write-audit + tier-capability \u0026 anatomy enforcement at the `store.write` chokepoint (flag-gated, audit-mode by default) | — |\n| **Curation queue** | Ingestion's canonical/standard proposals await trusted-dreamer sign-off in a review UI (`/review`, with source/diff/approve-reject) before becoming canonical — memory that's *curated*, not just accumulated | — |\n| **One-click deploy** | Stand up your own server on Render / Railway / Fly / Cloud Run (or free managed Postgres + any stateless host) | — |\n| **NATS messaging** | Real-time cross-device awareness | `/nats` |\n| **Inter-agent messaging** | Send tasks, questions, and decisions across the device network | `/msg` |\n| **Skill deployment** | Push slash commands to all devices in one step | `/update` |\n\nFull reference: [docs/reference/slash-commands.md](docs/reference/slash-commands.md)\n\n---\n\n## Pairs well with\n\n**Mori is your team's *earned* memory — not a docs cache.** It remembers what your agents\ndecided and learned across sessions and devices. It complements tools that supply *live\nexternal knowledge*:\n\n- **[Context7](https://github.com/upstash/context7)** — up-to-date, version-specific library\n  and framework documentation injected into the prompt. Where Mori remembers *\"we chose X, and\n  why\"*, Context7 supplies *\"here is X's current API.\"* Different layer, complementary purpose.\n- **Your platform's own docs** — for fast-moving tool and harness behaviour (hook schemas,\n  config formats), consult the current official docs rather than training-data recall. See the\n  *Read the current manual, not your memory* practice in\n  [agent-working-practices](standards/agent-working-practices.md).\n\n---\n\n## How it works\n\n### Dream pipeline — the proposal half of the gate\n\nThe dream pipeline is the *proposal* mechanism, not the product. It runs at **high\nrecall**: it turns session activity into candidate memories and deliberately\nover-produces — recall over precision — because nothing it emits reaches canon\nwithout a human promoting it (see [Governance](#governance--the-gate) below). That\ndivision of labour — machine proposes, human disposes — is the gate the benchmark\nmeasures.\n\nSession events are captured via agent lifecycle hooks (Claude Code, Cursor,\nAntigravity) and distilled into structured memories by a configurable LLM.\n\n![Dream Pipeline](https://raw.githubusercontent.com/fjwood69/mori/75c495f3f49e9ee53645bbe0de7aa11da43ad50d/docs/assets/figure-1-dream-pipeline.svg)\n\n```\nHook fires  →  POST /api/events/raw  →  events table (SQLite/Postgres)\n                                             ↓\nPreCompact  →  POST /api/precompact  →  dream_run() reads since watermark\n                                             ↓\n                                      LLM distills events → structured memories\n                                             ↓\n                                      memories written to store (with attribution)\n                                             ↓\n                                      watermark advanced\n```\n\n![The compaction boundary — nothing lost at the moment it matters most](https://raw.githubusercontent.com/fjwood69/mori/8f5df1412e69553a4dbf66aaf9f21b84ad50cead/docs/assets/figure-9-compaction-lifecycle.svg)\n\nThe `PreCompact` hook triggers an immediate synchronous dream before context\ncompression — so nothing is lost at the moment it matters most.\n\nIts counterpart works **after** compression: a `SessionStart` hook fires when the\nsession resumes post-compaction (`source: \"compact\"`) and runs `/brief --post-compact`\n— a lightweight *delta* that surfaces only what changed in the shared store since\nyour last brief (new, superseded, and evicted memories), skipping the full base\nreload and the freshness scan. PreCompact preserves what this session learned;\nSessionStart re-grounds it on what every other instance changed while it was busy.\n\n**What it captures:** `PostToolUse`, `PostToolUseFailure`, `PreCompact`,\n`UserPromptSubmit`, `Stop` — tool calls, prompts, errors, stop reasons,\nsession ID, hostname, working directory, transcript path, and (on `Stop`)\nthe assistant's own reasoning — the plans, analysis, and decisions behind\neach turn.\n\n### Governance — the gate\n\nProposals don't become canon on their own. Both the dream pipeline (your sessions)\nand the autonomous-agent intake path (other agents) write to a **review queue**, not\nto canon. A **trusted dreamer** — a human — reviews candidates and promotes the\nload-bearing ones; every promotion is versioned and `write_audit`-logged. Agents\n*read* canon; they never silently write it.\n\nUnderneath, **every** write — the dreamer's included — passes one audited authorization\nchokepoint: a structured provenance lands a `write_audit` row in the same transaction as the\nwrite, and tier-capability + anatomy enforcement gate *who* may write *what* (both ship\naudit-mode by default, so the policy is measured before it bites).\n\nTo keep that review cheap, mori **rolls up near-duplicate candidates** so the\nreviewer disposes of a *convention* once instead of many times. The proposal side\nruns at high recall; the gate is what makes high recall affordable instead of\nexhausting. This is the line the benchmark measures — and the commercial seam too:\nstandards and policy packs enter through the *same* gate (signed in, versioned,\naudited), not by trusting the filesystem.\n\n### Memory store\n\n![The Forest Remembers](https://raw.githubusercontent.com/fjwood69/mori/75c495f3f49e9ee53645bbe0de7aa11da43ad50d/docs/assets/figure-2-the-forest-remembers.svg)\n\nMemories live in the store — SQLite (`memories.db`) for solo/sync deployments,\nPostgres for team/async — with three tiers:\n\n\u003e **SQLite vs Postgres is a trust boundary, not just a backend toggle.** SQLite is the\n\u003e *one-human, one-writer* mode — the zero-config default for a single user on one\n\u003e machine, where you are the only thing that writes. Postgres is the *team* mode —\n\u003e many machines, many agents, concurrent writers — and it's **mandatory** for anything\n\u003e beyond solo: SQLite's file-level locking serialises writes and cannot sustain it.\n\u003e Capabilities that exist *because* multiple writers do (the autonomous-agent intake /\n\u003e governance pipeline) are **Postgres-only by design**. The curation queue still runs on\n\u003e SQLite in degraded single-writer form — one human gating their own agents — so the gate\n\u003e is never unavailable; it just doesn't need concurrency until a team does. Choose Postgres\n\u003e for production/team use.\n\n| Tier | Scope | Lifecycle |\n|------|-------|-----------|\n| **Ephemeral** | Session summaries | Auto-expire unless explicitly saved |\n| **Working** | Patterns, decisions, project context | Flagged after 30 days without retrieval |\n| **Canonical** | Explicitly promoted by a trusted dreamer | Indefinite, freshness-checked via `/brief` |\n\nVersioning, diff, rollback, attribution, and governance built in.\nSee [docs/reference/configuration.md](docs/reference/configuration.md).\n\n### Universal ingestion\n\n![Feed Anything, Remember Everything](https://raw.githubusercontent.com/fjwood69/mori/75c495f3f49e9ee53645bbe0de7aa11da43ad50d/docs/assets/figure-6-feed-anything.svg)\n\nNew team members start cold. `/ingest` bootstraps the memory store from\nexisting source material — applying the same distillation pipeline that\npowers the dream phase.\n\n```bash\n# Preview (zero cost, no LLM):\n/ingest --source ~/my-project --preview\n\n# Dry-run to validate extraction quality:\n/ingest --source ~/my-project --dry-run --focus decisions\n\n# Commit:\n/ingest --source ~/my-project --focus all --tier working\n```\n\n**Supported:** PDF, images/whiteboards (Kimi K2.6 vision), CC transcripts\n(`.jsonl`), git history (`--since 30d`), text and code.\n\n**Works with remote servers:** `/ingest` reads files on the client device and\nsends content over the wire — no shared filesystem needed. Works whether\nmori-advisor is running locally or on GCE.\n\n**Cost guard:** `--max-cost` (default $5.00) aborts before spending. Preview\nis always free. SHA256 dedup prevents re-ingesting the same content.\n\n### Strategic consultation (`/consult`)\n\n![Ask hard questions. Get grounded answers.](https://raw.githubusercontent.com/fjwood69/mori/75c495f3f49e9ee53645bbe0de7aa11da43ad50d/docs/assets/figure-7-strategic-consultation.svg)\n\nAsk a question mid-session and get strategic guidance grounded in your actual\nproject context — not generic advice. When a focus area is specified,\nrelevant team standards are automatically pulled from the memory store and\ninjected alongside your question. The advisor checks against your own baseline,\nnot a textbook.\n\n```bash\n# Architecture review with file context:\n/consult \"should we move auth to a separate service?\" --focus architecture\n\n# Security review against your team's own baseline:\n/consult \"review this handler\" --focus security --file src/auth.py\n\n# Chain tool output directly into the advisor:\n/consult \"review this\" --focus security --file src/auth.py --file snyk-report.json\n```\n\n**Works with remote servers:** `--file` reads files on the client device and injects content into the advisor prompt — no shared filesystem required. Works whether mori-advisor runs locally or on GCE.\n\n**Focus areas:** `general`, `architecture`, `security`, `performance`, `style`\n\n**Depth levels:** `quick` (fast scan), `balanced` (default), `deep` (thorough)\n\n**Standards-aware:** set `MORI_STANDARDS_DIR` to a directory of `.md` files\nand Mori imports them as protected memories. `/consult --focus security`\ninjects your security baseline into the advisor call, so **`/consult` reviews\nagainst your rules, not a textbook**. (That's the advisor — a single, scoped\nreview request — reading your standards; it is *not* a claim that your coding\nagent obeys them mid-task. Surfaced standards inform; they don't bind.)\n\n### Inter-agent messaging (`/msg`)\n\n![The forest whispers](https://raw.githubusercontent.com/fjwood69/mori/2a74b681fd49c9b41aad57d69f02c0be0101f661/docs/assets/figure-8-the-forest-whispers-dark.svg)\n\nDelegate tasks, ask questions, and share decisions across your Claude Code\ninstances — without a shared session. Messages are typed, reply-threaded, and\npicked up at the next `/brief`. The `mori-msg` daemon receives messages\nserver-side: `decision` messages are written directly to the memory store\nwithout any human session on the receiving end.\n\n```bash\n# From your laptop, delegate a task to a workstation:\n/msg send workstation task \"Refactor auth middleware — extract rate limiting into its own module\"\n\n# The workstation picks it up at next /brief and acks:\n/msg ack a3f9c2b1 \"on it\"\n\n# Back on your laptop, check the reply:\n/msg inbox\n\n# The workstation marks it done when finished:\n/msg done a3f9c2b1\n```\n\n**Message types:** `task`, `decision`, `question`, `reply`, `ack`, `done`, `broadcast`\n\nRequires the `mori-msg` daemon running alongside `mori-advisor` (included in\nthe default pod stack). See [docs/reference/msg.md](docs/reference/msg.md) for full reference.\n\n### Web dashboard\n\nNot everyone who needs the shared memory runs a Claude Code session. Mori serves a\nbuilt-in **memory browser** at its own root URL — just open the server in a browser:\n\n```\nhttp://\u003cyour-mori-host\u003e:8968/\n```\n\nEnter any valid API key (the same `MORI_API_KEYS` your clients use) and you can search,\nbrowse, and click any card to unfurl its full body and provenance (origin clients, tier,\nretrieval count, freshness). The page is served **same-origin**, so it talks to the very\nmori instance it loaded from — no base URL to configure, no separate server to run. It's a\nsingle dependency-free file (vanilla JS, no build step, no CDN), backed by a small read\nREST API:\n\n| Route | Returns |\n|-------|---------|\n| `GET /api/memories?query=\u0026type=\u0026tag=\u0026client=\u0026since=\u0026limit=` | Ranked full-text (or recency) list — lean shape, no body |\n| `GET /api/memories/{name}` | One memory in full — body + provenance (lazy-loaded on unfurl) |\n| `GET /api/events?session_id=\u0026client=\u0026since=\u0026limit=` | Session event log, newest first |\n\nThe dashboard and its routes are **read-only** and API-key gated (`X-Api-Key`); write\nactions (delete, trusted-dreamer review) are deferred until the read surface is validated.\nThe page is also available standalone (`dashboard/index.html`) if you'd rather host it\nelsewhere and point it at a mori instance — set `MORI_CORS_ORIGINS` for that cross-origin\ncase (it's unnecessary for the built-in same-origin serving).\n\n### Architecture\n\n![Mori Architecture](https://raw.githubusercontent.com/fjwood69/mori/75c495f3f49e9ee53645bbe0de7aa11da43ad50d/docs/assets/figure-4-architecture.svg)\n\n---\n\n## Configuration\n\n**Configuration reference** → [docs/reference/configuration.md](docs/reference/configuration.md)\n**Recommended models** → [docs/reference/models.md](docs/reference/models.md)\n**For teams** → [docs/for-teams.md](docs/for-teams.md)\n**Team configuration reference** → [docs/reference/team-configuration.md](docs/reference/team-configuration.md)\n\nKey environment variables:\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `MORI_PROVIDER_MODE` | `bifrost` | `direct` or `bifrost` |\n| `MORI_API_KEY` | — | Provider key (required in `direct` mode) |\n| `MORI_BASE_URL` | — | OpenAI-compatible base URL |\n| `MORI_MODEL` | `moonshotai/kimi-k2.6` | Advisor + consult model |\n| `MORI_DREAM_MODEL` | falls back to `MORI_MODEL` | Dream + ingest distillation model |\n| `MORI_FAST_MODEL` | `deepseek/deepseek-v4-flash` | Contradiction scan + freshness checks |\n| `MORI_API_KEYS` | — | Named client API keys: `name:secret,name:secret,...` — see [Authentication](docs/reference/configuration.md#authentication) |\n| `MORI_BRIEF_SCOPE` | `safe` | `safe` = provenance-routed brief (cross-project origin-bound canon withheld; explicit `scope:global` only); `all` = legacy, no scoping |\n| `MORI_TRUSTED_DREAMERS` | — | Comma-separated trusted hostnames |\n| `MORI_DREAM_INTERVAL` | `60` | Dream cron interval (minutes) |\n| `MORI_STANDARDS_DIR` | — | Path to team standards `.md` files |\n| `MORI_MSG_HEADLESS_ENABLED` | `false` | Spawn headless Claude for incoming tasks |\n| `MORI_MSG_HEADLESS_TRUSTED` | — | Comma-separated hostnames allowed to trigger headless CC |\n\n**Authentication:** Set `MORI_API_KEYS` to give each client a named key. Without it the server starts in open mode (fine for private Tailscale networks; always set keys for shared or internet-accessible deployments). Generate secrets with `python3 -c \"import secrets; print(secrets.token_hex(32))\"`. Full details: [docs/reference/configuration.md → Authentication](docs/reference/configuration.md#authentication).\n\n---\n\n## Building\n\n```bash\ngit clone https://github.com/fjwood69/mori.git\ncd mori\npodman build -t localhost/mori-advisor:latest .\n# Or: docker build -t mori-advisor:latest .\n```\n\n## License\n\n[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)\n\nAGPL-3.0 — see [LICENSE](LICENSE). Commercial licences available — see [COMMERCIAL.md](COMMERCIAL.md).\nContributions require a one-time CLA — see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n---\n\n[![Support me on Ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/moriapp)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffjwood69%2Fmori","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffjwood69%2Fmori","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffjwood69%2Fmori/lists"}