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

$ curl -fsSL https://blackstardesigns.github.io/memo/install.sh | sh

Windows (PowerShell)

$ powershell -c "irm https://blackstardesigns.github.io/memo/install.ps1 | iex"

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#

PlatformAI backend
macOS Apple SiliconMLX default, Ollama optional
macOS IntelOllama
Linux x86_64 / arm64Ollama
Windows x86_64Ollama

For Linux dictation support (optional, memo installs and runs fine without it; only voice capture is unavailable), install ALSA:

$ sudo apt-get install libasound2t64 # Ubuntu 24.04+ $ sudo apt-get install libasound2 # older Debian / Ubuntu $ sudo dnf install alsa-lib # Fedora / RHEL $ sudo pacman -S alsa-lib # Arch

Quick start#

Open a new terminal and run:

$ memo

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

KeyAction
nNew note
Ctrl+FNew folder
mMove note to a folder
Enter / oOpen note or enter folder
/Search
↑ ↓ ← →Move selection
xDelete note or folder
Ctrl+EExport to .md
dToggle drawer
Ctrl+HHelp
q / EscQuit

Editor

KeyAction
Ctrl+RRefine note with AI
Ctrl+PRefine with a custom one-off prompt
Ctrl+MInsert math symbol (∑ picker)
/Commands (to-do, comment, link, change title, refine, ...) — at start of a line
Ctrl+OCommands — from anywhere in the line
Ctrl+LToggle to-do [ ] / [x]
TabSwitch original/refined view
Ctrl+TRename note
Ctrl+SSave
Ctrl+EExport to .md
Ctrl+HHelp
F5Dictation
EscSave & 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.

BackendBest forDefault port
MLXApple Silicon Macs8080
OllamamacOS Intel, Linux, Windows, or Apple Silicon11434

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:

$ mlx_lm.server --model mlx-community/Qwen2.5-0.5B-Instruct-4bit --port 8080

Ollama

Install Ollama, then pull a model:

$ ollama pull qwen2.5:0.5b

Set this in ~/.config/memo/config.toml:

provider = "ollama" base_url = "http://localhost:11434/v1" model = "qwen2.5:0.5b"

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.

$ memo config --edit # open it in your editor $ memo config --path # print its path

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#

providerdefault: "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).

base_urldefault: "http://localhost:8080/v1"

OpenAI-compatible base URL of your local model server. MLX: http://localhost:8080/v1. Ollama: http://localhost:11434/v1.

modeldefault: "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_keydefault: ""

API key. Usually empty for a local MLX or Ollama server.

data_dirdefault: ""

Where notes are stored. Leave empty to use the platform default (~/.local/share/memo/notes). Supports a leading ~ for your home directory.

temperaturedefault: 0.3

Sampling temperature used when refining a note.

max_tokensdefault: 2048

Maximum tokens the model may generate for a refinement.

request_timeout_secsdefault: 120

How long (in seconds) to wait for the model to respond.

stopdefault: ["<|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.

auto_start_serverdefault: true

When 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.

server_on_demanddefault: false

When 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.

server_idle_timeout_secsdefault: 120

On-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_repodefault: "" · MLX only

Where 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.

venvdefault: "" · MLX only

Virtualenv 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.

show_shortcutsdefault: true

Show 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.

dictation_keydefault: "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".

dictation_modeldefault: "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.

dictation_model_pathdefault: ""

Explicit path to a GGML model file. Leave empty to use the managed cache above. Supports a leading ~.

dictation_languagedefault: "en"

Spoken-language hint. Use a code like "en", or "auto" to let whisper detect it.

dictation_silence_msdefault: 700

Live 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.

palette_keydefault: "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".

checkbox_keydefault: "ctrl+l"

Toggles [ ] / [x] on the current to-do line.

Refine prompt#

refine_promptmulti-line string

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.

refine_prompt = """ You are an editor that polishes rough notes. Improve the writing without changing what it says. ... """

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.

KeyDefaultWhat 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
padding2Inner padding (cells) for the editor body and tiles
divider"#313244"Line separating the note header from content
rounded_tilestrueRounded corners on note tiles in the list view
meta"#585b70"Created/modified timestamps on tiles and in the editor
[theme] accent = "#ffaf00" # go full memo-orange border = "#313244" status = "green" padding = 2

File locations#

PathPurpose
~/.config/memo/config.tomlUser config (auto-created on first launch)
~/.config/memo/mlx-server.logMLX / Ollama server stdout/stderr
~/.config/memo/mlx-server.pidPID 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#

$ memo # launch the app $ memo config --edit # open config in your editor $ memo config --path # print the config path $ memo --help # full command-line reference $ man memo # manual page (installed by install.sh)

Build from source#

$ git clone https://github.com/blackstardesigns/memo.git $ cd memo $ cargo run

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.