Documentation
Everything you need to install, use, and configure memo: private, keyboard-first notes that run in any terminal, multiplexer, or SSH session, with AI that never leaves your machine.
Installation#
macOS / Linux
Windows (PowerShell)
Prefer a manual install? Grab a prebuilt binary. For the latest pre-release, append -s -- --pre to the curl command, or set $env:MEMO_INSTALL_PRE = '1' before running the PowerShell one.
Requirements#
| Platform | AI backend |
|---|---|
| macOS Apple Silicon | MLX default, Ollama optional |
| macOS Intel | Ollama |
| Linux x86_64 / arm64 | Ollama |
| Windows x86_64 | Ollama |
For Linux dictation support (optional, memo installs and runs fine without it; only voice capture is unavailable), install ALSA:
Quick start#
Open a new terminal and run:
Press n for a new note, type your rough thought, then Ctrl+R to refine it with AI. Tab flips between your original and the refined version. Esc saves and takes you back to the list.
Keyboard reference#
Ctrl+C / Ctrl+Q quit immediately from anywhere, any screen, any modal, with no confirmation prompt (notes are already saved). q / Esc on the list view ask first.
List view
| Key | Action |
|---|---|
| n | New note |
| Ctrl+F | New folder |
| m | Move note to a folder |
| Enter / o | Open note or enter folder |
| / | Search |
| ↑ ↓ ← → | Move selection |
| x | Delete note or folder |
| Ctrl+E | Export to .md |
| d | Toggle drawer |
| Ctrl+H | Help |
| q / Esc | Quit |
Editor
| Key | Action |
|---|---|
| Ctrl+R | Refine note with AI |
| Ctrl+P | Refine with a custom one-off prompt |
| Ctrl+M | Insert math symbol (∑ picker) |
| / | Commands (to-do, comment, link, change title, refine, ...) — at start of a line |
| Ctrl+O | Commands — from anywhere in the line |
| Ctrl+L | Toggle to-do [ ] / [x] |
| Tab | Switch original/refined view |
| Ctrl+T | Rename note |
| Ctrl+S | Save |
| Ctrl+E | Export to .md |
| Ctrl+H | Help |
| F5 | Dictation |
| Esc | Save & back to list |
Notes autosave after you stop typing, when you switch views, and when you leave the editor.
Dictation#
Press F5 in the editor:
- Hold F5 for push-to-talk: records while held, inserts on release
- Double-press F5 for continuous listening: each phrase is appended as you speak
- Double-press again, or leave the editor, to stop
Dictation runs locally using whisper.cpp. The first use downloads the speech model to ~/.local/share/memo/models/.
On macOS, F5 may be reserved for system dictation. Disable the macOS shortcut (System Settings → Keyboard → Dictation), enable standard function keys, or change dictation_key in the config. Hold-to-talk is crispest in terminals with the Kitty keyboard protocol (Ghostty, kitty, WezTerm, iTerm2); elsewhere a key-repeat heuristic is used.
Local AI setup#
memo talks to a local OpenAI-compatible server: the installer sets one up for you. Both backends speak the same API, so refinement works the same either way.
| Backend | Best for | Default port |
|---|---|---|
| MLX | Apple Silicon Macs | 8080 |
| Ollama | macOS Intel, Linux, Windows, or Apple Silicon | 11434 |
MLX on Apple Silicon
The installer can install mlx-lm for you. Default model: mlx-community/Qwen2.5-0.5B-Instruct-4bit. Run manually if needed:
Ollama
Install Ollama, then pull a model:
Set this in ~/.config/memo/config.toml:
With auto_start_server = true, memo starts ollama serve when needed. If Ollama is already running, memo leaves it alone.
Config file#
Config lives at ~/.config/memo/config.toml and is auto-created on first launch. Edit values, then relaunch memo.
Colors accept names (e.g. "yellow", "darkgray"), "#rrggbb" hex, a 0–255 palette index, or "none"/"transparent" for the terminal default. All options below are shown with their defaults.
Model & server#
"mlx"Which local backend to auto-start: "mlx" (Apple MLX) or "ollama". Both speak the same OpenAI-compatible API; this only selects the server memo launches (see auto_start_server).
"http://localhost:8080/v1"OpenAI-compatible base URL of your local model server. MLX: http://localhost:8080/v1. Ollama: http://localhost:11434/v1.
"mlx-community/Qwen2.5-0.5B-Instruct-4bit"Model name the server should use. MLX: an mlx-community repo. Ollama: a pulled model tag, e.g. qwen2.5:0.5b (run ollama pull qwen2.5:0.5b first).
""API key. Usually empty for a local MLX or Ollama server.
""Where notes are stored. Leave empty to use the platform default (~/.local/share/memo/notes). Supports a leading ~ for your home directory.
0.3Sampling temperature used when refining a note.
2048Maximum tokens the model may generate for a refinement.
120How long (in seconds) to wait for the model to respond.
["<|eot_id|>", "<|end_of_text|>", …]Stop sequences. Bigger instruct models sometimes keep generating past the end of their answer and leak chat-template markers. These sequences stop generation and are stripped from the output so they never reach your notes.
trueWhen true, memo starts the server selected by provider for you on launch and shuts it down when you quit. If a server is already listening on that port, memo leaves it alone, so for Ollama you can keep this on even when the Ollama app is already running.
falseWhen false, the server starts at launch and stays resident until you quit, so the model is always ready. Set to true to instead start it lazily on your first refine (Ctrl+R) and shut it back down once it has been idle, keeping the model out of memory until you actually use refinement. Only applies when auto_start_server = true.
120On-demand mode only: how long to keep the server running after your last refine before shutting it down. 0 stops it immediately after each refine; a larger value keeps the model warm so repeated refines don't pay the reload cost.
"" · MLX onlyWhere to launch the server from. Point at your local mlx-lm checkout if you run from source; leave empty to launch from the current directory.
"" · MLX onlyVirtualenv to run the server with. Either an absolute path / ~/path, or a name relative to mlx_repo (e.g. .venv). Empty uses python3 from PATH.
trueShow the keyboard-shortcuts hint bar along the bottom of the screen.
Dictation options#
dictation_key must stay a top-level key: keep it above the [theme] line in your config, or TOML treats it as part of [theme] and silently ignores it.
"F5"The key that drives dictation in the editor: hold for push-to-talk, double-press to toggle continuous live listening. A function key like "F5" / "f6", or a combo like "ctrl+k" / "ctrl+space".
"base.en"Which whisper.cpp model to use. The matching ggml-<model>.bin is downloaded on first use into ~/.local/share/memo/models/. Options: tiny.en | base.en | small.en | medium.en | large-v3 (drop .en for multilingual). Bigger = more accurate but slower and larger.
""Explicit path to a GGML model file. Leave empty to use the managed cache above. Supports a leading ~.
"en"Spoken-language hint. Use a code like "en", or "auto" to let whisper detect it.
700Live listening: how much trailing silence (milliseconds) ends a phrase and triggers its transcription.
Command palette options#
Like dictation_key, both keys below must stay top-level: keep them above the [theme] line in your config, or TOML treats them as part of [theme] and silently ignores them.
"ctrl+o"Opens the command palette in the editor from anywhere in the line. Typing / at the start of a line opens the same palette. Same syntax as dictation_key: a function key like "F6", or a combo like "ctrl+space".
"ctrl+l"Toggles [ ] / [x] on the current to-do line.
Refine prompt#
The single prompt used when you press Ctrl+R. The default instructs the model to fix grammar and phrasing, preserve meaning and voice exactly, organize for readability with Markdown structure, and output only the finished note. Customize it to change how refinement behaves: make it translate, summarize, or match your house style.
Theme & colors#
UI colors and spacing live in the [theme] section. Colors accept names, "#rrggbb" hex, a 0–255 palette index, or "none"/"transparent" to use the terminal's default color.
| Key | Default | What it colors |
|---|---|---|
accent | "yellow" | Selection highlight, search focus, accents |
border | "#313244" | Default (unselected) borders |
refined | "#313244" | Refined-view accents and the ✦ marker |
title_fg | "yellow" | Editor title-bar text |
title_bg | "none" | Editor title-bar background |
footer_fg | "#313244" | Footer hint-bar text |
footer_bg | "none" | Footer hint-bar background |
status | "green" | Transient status messages |
padding | 2 | Inner padding (cells) for the editor body and tiles |
divider | "#313244" | Line separating the note header from content |
rounded_tiles | true | Rounded corners on note tiles in the list view |
meta | "#585b70" | Created/modified timestamps on tiles and in the editor |
File locations#
| Path | Purpose |
|---|---|
~/.config/memo/config.toml | User config (auto-created on first launch) |
~/.config/memo/mlx-server.log | MLX / Ollama server stdout/stderr |
~/.config/memo/mlx-server.pid | PID of the managed server process |
~/.local/share/memo/notes/ | Note files (<id>.md, <id>.refined.md) and folders.json |
~/.local/share/memo/models/ | whisper.cpp GGML model files (e.g. ggml-base.en.bin) |
Notes are plain Markdown with YAML frontmatter: portable without the app. Saves are atomic (write to a temp file, then rename), so a crash mid-write can't corrupt a note. Refined versions are stored as sidecar files next to the original.
Command line#
Build from source#
Requires, on every platform (whisper-rs compiles whisper.cpp at build time):
- Rust
- CMake
- C/C++ compiler
Issues and pull requests are welcome; for larger changes, please open an issue first so the approach can be discussed.