README
¶
Mora indexes your Gmail (one or several accounts), Google Calendar, iMessage, Apple Calendar, and local files into a vault of Markdown files and a SQLite index on your machine, then serves it over MCP to Claude Code, Codex, or any other MCP client. Point several agents at the same vault and they all answer from your history, with citations.
It runs entirely on your machine: no server, no signup, no telemetry. iMessage and Apple Calendar need macOS; Gmail, Calendar, files, notes, and local Ollama embeddings also run on Linux and Windows.
What it looks like
$ mora think "what did we decide with Sam about pricing?"
Evidence (3):
[mem_20260610_204655_f3049131] Pricing call with Sam: agreed to $29 one-time
for the pilot; revisit a subscription tier once we cross 10 seats. He wants the
invoice before Friday.
...
Gaps: none detected.
think returns cited evidence plus the gaps it found: stale results, thin coverage, a name the vault has never seen. There's no API key and no model to host; your agent does the reasoning and calls search_memory, think, and brief over MCP.
Install
macOS / Linux
curl -fsSL https://raw.githubusercontent.com/pyranthus-hq/mora/main/install.sh | sh
The script downloads the release binary for your platform, verifies it against the release checksums.txt before extracting, clears the macOS Gatekeeper quarantine (binaries are ad-hoc signed, not notarized — it prints exactly what it does to Gatekeeper and why), and runs mora init (your vault lives at ~/vault/mora). The checksums file is cosign-signed on each release if you want to verify the stronger chain by hand. Update in place later with mora upgrade (source builds report dev and cannot self-update). Prefer to build it yourself? go install github.com/pyranthus-hq/mora/cmd/mora@latest (Go 1.25+, pure Go, no CGO).
Windows
Run this from PowerShell:
iwr https://raw.githubusercontent.com/pyranthus-hq/mora/main/install.ps1 -OutFile $env:TEMP\install-mora.ps1; powershell -ExecutionPolicy Bypass -File $env:TEMP\install-mora.ps1
The Windows installer downloads mora_<version>_windows_amd64.zip, verifies it against the release checksums.txt, installs mora.exe to %LOCALAPPDATA%\Mora\bin\mora.exe, and adds that directory to your User PATH. The v1 Windows binary is unsigned, so SmartScreen may show Windows protected your PC. After the checksum passes, choose More info > Run anyway or run Unblock-File "$env:LOCALAPPDATA\Mora\bin\mora.exe".
Windows supports Gmail, Google Calendar, filesystem folders, notes, and local Ollama embeddings. iMessage, Apple Calendar, and Address Book are macOS-only. mora schedule install <job> uses Windows Task Scheduler and creates tasks named Mora\<job>; see the Windows guide.
Uninstall
macOS / Linux:
curl -fsSL https://raw.githubusercontent.com/pyranthus-hq/mora/main/uninstall.sh | sh
Windows:
iwr https://raw.githubusercontent.com/pyranthus-hq/mora/main/uninstall.ps1 -OutFile $env:TEMP\uninstall-mora.ps1; powershell -ExecutionPolicy Bypass -File $env:TEMP\uninstall-mora.ps1
Removes the mora binary and de-registers the MCP server from Claude Code / Codex on macOS/Linux. On Windows it removes %LOCALAPPDATA%\Mora, the User PATH entry, and scheduled tasks under \Mora\. Your vault is preserved by default; re-run with --purge / MORA_PURGE=1 on macOS/Linux or -Purge on Windows to also delete Mora data paths.
How Mora is laid out
Mora keeps your data in four places. Only the first is precious:
| Path | Holds | If lost |
|---|---|---|
vault_dir (~/vault/mora) |
your memories, as Markdown | back this up (mora sync git mirrors it to a private repo) |
data_dir (~/.local/share/mora) |
the search index | rebuilt with mora index rebuild |
state_dir (~/.local/state/mora) |
connector sync watermarks | rebuilt on the next sync |
config_dir (~/.config/mora) |
settings + OAuth tokens | re-create with mora init / re-auth |
Run mora config to see the resolved paths. Mora will refuse to rebuild the index from a vault that suddenly looks empty or unfamiliar (it could mean your vault_dir moved). It tells you how to fix it, or pass --force to override.
Then connect your sources:
mora connect google # OAuth login, then backfill Gmail + Calendar (read-only; ~90 days, --since-days to widen)
mora connect google --account work # add a second mailbox (gmail-work / calendar-work sources)
mora connect imessage # macOS; walks you through Full Disk Access
mora schedule install ingest-hourly # background sync (launchd, Task Scheduler, or a Linux cron line)
First Google sign-in: Mora's shared Google app is still going through Google's review, so you'll see a "Google hasn't verified this app" screen. Click Advanced → Go to Mora to continue; the access stays read-only and on-device. Prefer your own keys? Set
MORA_GOOGLE_CREDENTIALS=/path/to/client.jsonto use your own Google OAuth client instead (optional). See Connect Google.
Wire Mora into your agents (registers the local MCP server):
claude mcp add mora -s user -- mora mcp serve # Claude Code
codex mcp add mora -- mora mcp serve # Codex
Any other MCP client (Gemini CLI, Cursor, custom hosts) takes the same stdio server as JSON:
{
"mcpServers": {
"mora": { "command": "mora", "args": ["mcp", "serve"] }
}
}
Drop that into the client's MCP config (examples/mcp.json has a copy). Per-connector setup and options are in the guide.
No MCP? Use the shell
Every MCP tool is also a CLI command, so any agent with shell access can use Mora without registering the server. Paste this into the agent's instructions file (AGENTS.md, CLAUDE.md, Cursor rules) to teach it to both recall from and capture to your vault:
## Memory: mora (local)
You have `mora`, a local memory over my Gmail, calendars, iMessage, and files.
RECALL — before answering anything about people, past decisions, projects, or
commitments, query mora first and answer from what it returns:
mora think "<question>" --json # cited evidence + an explicit gap check
mora search "<query>" --json # search the vault
mora graph "<person>" # one person across email, texts, and calendar
mora brief # what changed and what matters lately
Cite every claim with its [stable_id]. If the evidence is insufficient, say so
plainly rather than guessing, and surface any gaps mora reports. Never invent a
memory it did not return.
CAPTURE — when I tell you a durable fact, decision, preference, or commitment
worth recalling later, save it back without being asked:
mora write --type <fact|decision|insight|task> --title "<title>" --text "<body>"
Capture the signal, not chit-chat: things a future session would want surfaced.
Do not store secrets I mention in passing unless I ask you to.
The CLI siblings of every tool (mora search, mora write, mora think, ...) are in the guide.
Agent skills (optional)
A small plugin of agent-side recipes that pair with the MCP server; they teach an agent to resolve people, shared history, and calendar context from the vault before reaching for the web:
/plugin marketplace add pyranthus-hq/mora
/plugin install mora@mora
First skill: /mora:dining-concierge, for outing recommendations grounded in who's coming and where you've actually been. Skills are plain Markdown (plugins/mora); other agents can copy them into their own skills directory.
Why a local corpus
Mora keeps a persistent local corpus, so you can ask "what did I commit to, and to whom" across months and have the same context whichever assistant you use. It indexes iMessage (which has no cloud API) and handles several mail accounts at once, then serves all of it to whatever agent you use. Cloud connectors fetch from Google's APIs per query and keep nothing between calls.
| Mora | Cloud connectors | MCP Gmail servers | |
|---|---|---|---|
| Data lives | Your disk (Markdown + SQLite) | Vendor cloud | Nowhere (live fetch) |
| iMessage | Yes (local chat.db, read-only) |
No | No |
| Multiple mailboxes in one view | Yes | No | Per server |
| One person across email + texts + calendar | Yes | No | No |
| Shared by every agent (Claude, Codex, etc.) | Yes | Tied to the vendor | Per client |
| Works offline / greppable | Yes | No | No |
| Cost | $0, no Mora account | Subscription | Free |
What you get
- Plain files you own. Every email thread, text conversation, and calendar event is one Markdown file. Open them in Obsidian,
grepthem, or back them up like any folder. The SQLite index is disposable: delete it andmora index rebuildrebuilds it from the files. - Documents and PDFs. Point Mora at a folder and it indexes your notes, text files, Word documents, and text-based PDFs, including a PDF someone texts you. Add a files source.
- One view of each person.
mora graph "Sam"pulls someone together across email, texts, and calendar (including mail from different accounts) into shared threads, meetings, and the people they appear with, every line cited. Identity matching is deterministic: it merges the same mailbox written different ways (Gmail dot and +tag variants) and links different addresses only by a shared trusted name with a corroborating address. How the graph works. - Keyword and semantic search. Keyword search (BM25) is built in. Run
mora config embedder ollamato add local semantic search through Ollama. How retrieval works. - A daily brief.
mora briefshows new and updated threads, upcoming events, and stale open tasks, ranked by a per-person salience score. Filter it to one person withmora brief --entity "Riya", or build a cited prep pack for your next meeting withmora prep. - Off-device backup.
mora sync gitpushes the vault to any private git remote you control: GitHub, GitLab, self-hosted, or a bare repo on a USB stick. It pushes vault files only; your tokens and the index stay on your machine. Restore withgit cloneandmora index rebuild. Details. - Encrypted sharing (opt-in).
mora sharepublishes one scope of your authored notes to a dedicated private git remote — or a user-owned S3/R2 bucket — age-encrypted per recipient, with a mandatory preview of exactly what leaves. A subscriber searches your notes as a read-only, attributed corpus beside their own vault — never merged into it. Details. - Shared across agents, or used from your shell. 12 MCP tools let any MCP client search memory, read the brief, prep for a meeting (
meeting_prep), and write facts back (write_memory).mora mcp serveruns as a local stdio process, so several agents share the same vault, and every search result reports how fresh each source is. Every tool is also a plain CLI command (mora search,mora write,mora think), so the vault is just as usable from a terminal. Wiring guide.
Privacy
- Read-only at the source. Google scopes are
gmail.readonlyandcalendar.readonly; iMessage and Apple Calendar are opened read-only. Mora never sends, changes, or deletes anything in your accounts. Itswrite_memoryanddelete_memorytools only touch the local vault. - Everything on your disk. The vault, index, and OAuth tokens (
~/.config/mora/tokens/, mode 0600) live on your machine. There is no analytics endpoint. The only log is a local usage log of tool name, timing, result counts, and scope. It does not record your query text by default (opt in withmora usage queries on); turn the log off entirely withmora usage offorDO_NOT_TRACK=1. - Plaintext at rest. Your vault is unencrypted Markdown on disk. That is what makes it greppable and portable, but it also means anything that can read your home directory can read your memories. Protect it with full-disk encryption (FileVault on macOS), and use git-remote-gcrypt for an encrypted off-device backup. Tokens are mode 0600; vault files inherit your filesystem permissions.
- Bring your own Google keys (optional). Mora's shared Google app is still in Google's verification queue, so you hit an "unverified app" screen and a ~100-user cap. Point Mora at your own OAuth client with
MORA_GOOGLE_CREDENTIALS=/path/to/client.jsonto sidestep both. Connect Google. - Zero egress by default. No server, no hosting. Mora reaches the network only to sync your sources, fetch updates during
mora upgrade, and push or pull the opt-in egress paths (vault backup over git, age-encryptedmora shareover git or a user-owned S3/R2 bucket); the optional Ollama embedder is loopback-only.mora doctorwarns if the vault is a git repo, and git-remote-gcrypt gives you an encrypted remote.
Docs
The guide covers connectors, MCP wiring, daily use, retrieval, and the cloud comparison. Windows setup covers PowerShell install, SmartScreen, Windows connectors, and Task Scheduler. docs/architecture/ is the contributor spec: 14 subsystem docs with diagrams and file:line citations.
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
mora
command
|
|
|
internal
|
|
|
applecal
Package applecal is the macOS Apple Calendar connector: a read-only reader of the local Calendar store (Calendar.sqlitedb in the calendar group container), one memory per event.
|
Package applecal is the macOS Apple Calendar connector: a read-only reader of the local Calendar store (Calendar.sqlitedb in the calendar group container), one memory per event. |
|
google
Package google ingests Gmail and Calendar data into Mora-renderable memories.
|
Package google ingests Gmail and Calendar data into Mora-renderable memories. |
|
imessage
Package imessage ingests local iMessage conversations into Mora-renderable memories.
|
Package imessage ingests local iMessage conversations into Mora-renderable memories. |
|
memory
Package memory holds the connector-agnostic memory model, identity helpers, resumable ingest loop, and sync-status state shared by all connectors.
|
Package memory holds the connector-agnostic memory model, identity helpers, resumable ingest loop, and sync-status state shared by all connectors. |