Documentation & Reference Manual

MD-Memo Comprehensive Guide

A zero-latency Markdown scratchpad engineered for instant capture.
From first-time setup to advanced JSON-RPC IPC and autonomous CLI agent orchestration.

01 Getting Started: Core Philosophy

In one line: MD-Memo does not compete with Notion or Obsidian. It is the zero-friction buffer in front of them: capture ideas, error logs and scribbles with no start-up wait, then move them into your knowledge base when you need to.
Three Core Principles
  1. Zero Save Anxiety: Notes autosave automatically after a 1.5-second idle pause.
  2. Instant Summon: Wake the app from your system tray in milliseconds via Ctrl+Alt+M.
  3. Zero Typo Friction: Autonomous IME Shield prevents accidental full-width characters inside code blocks and URLs.

AI features are organized around three verbs, Write, Run and Delegate, and each has exactly one entry point.

WriteCtrl + L: ask the AI about the selected text, and the answer appears below it (a few seconds)
RunCtrl + E: replace text with a command's output (nearly instant)
DelegateCtrl + Enter on a line: the AI, an agent or a command does it, and the result lands below (an agent takes minutes)

Eight keys to learn first (on macOS, read Ctrl as Cmd)

CtrlL
Ask AI
Ask about the selected text; the answer appears below it
CtrlJ
Quick Actions
Up to 3 suggested next steps
CtrlE
Command Bar
Pipe the selected text through a command, or let the AI write it (Tab)
CtrlEnter
Auto selector
On a line: the AI, an agent or a command does it, and the result lands below
CtrlShiftP
Command palette
Search and run features from the keyboard
CtrlShiftF
Scraps search
Full-text search across past notes
CtrlShiftV
Special paste
Paste web pages and Word content as Markdown
CtrlShiftU
Mobile Drop
Send photos and text from your phone

For the name of each part of the window, see A Tour of the Window. If you are not sure which feature to use, see Which one do I use?

A Tour of the Window

In one line: The window has four parts: tabs, toolbar, editor and status bar. A note is just Markdown text.
The MD-Memo main window: tab bar and toolbar at the top, an editor with line numbers in the middle, and the status bar at the bottom
The main window: three tabs, toolbar, editor and status bar
  1. Tab bar Your open notes. A dot marks unsaved changes, and + opens a new note
  2. Toolbar On the right: open file, open folder, save, find, search scraps, Ask AI, Mobile Drop, voice input, split / preview, settings and help
  3. Editor Line numbers on the left. The text is plain Markdown
  4. Status bar (left) Caret line and column, and the character count
  5. Related-note pills Notes from the opened folder that match what you are writing. Click one to open it
  6. Status bar (right) Git sync, Action, Predict, Autosave and encoding badges

To focus, use Zen mode (Shift + F11; macOS: Ctrl + Cmd + Z). The toolbar, tabs and status bar hide, and only the note stays. The window size does not change, so this is not full screen (add F11, which maximizes, if you want that). Press Esc or Shift + F11 again to leave.

Zen mode: the toolbar, tabs and status bar are hidden and only the note is shown
Zen mode: the toolbar, tabs and status bar are hidden and only the note is shown

Each status bar item is explained in the next section, Reading the Status Bar.

Reading the Status Bar

In one line: The strip at the bottom of the window. It shows the caret position and character count, plus related-note pills, Git sync and the on/off state of several features.
The status bar enlarged, with numbers on the caret position, character count, related-note pills, Git sync, Action, Predict, Autosave and encoding
The status bar, enlarged 2x. In the Japanese UI, an unnumbered IME badge (Japanese input conversion) also sits between Git sync and Action
  1. Caret position Line and column
  2. Character count Characters in the whole note
  3. Related-note pills Up to two
  4. Git sync State of the scraps folder. Click to sync
  5. Action Quick Actions: On / Manual / Off. Click to switch
  6. Predict Ghost text on or off. Click to toggle
  7. Autosave On or off. Click to toggle
  8. Encoding Click to switch between UTF-8 and Shift_JIS
Position Shows
Left Caret line and column, character count, selection length (only while text is selected)
Center Related-note pills, the LLM / processing indicator, messages
Right Running-task badge (click to open the task panel, Alt + T), Git sync (click to sync), IME, Action (click to cycle On → Manual → Off), Predict (ghost text), Autosave, encoding (click to toggle)

To make related-note pills appear

  1. Open a folderPress Ctrl + Shift + O and choose your notes folder. MD-Memo remembers it after a restart
  2. Keep writingStop typing and wait about 1.2 seconds
  3. Pills appearUp to two notes close to what you are writing are shown
  4. Click to openThe note opens in a new tab. Point at a pill to see its title, path and first line

If no folder is open, or no note is close enough, no pills appear.

Limits and details (scan range and scoring)
  • Opening a folder shows "Loaded workspace: N notes found".
  • Only .md, .markdown and .txt files are scanned, up to 3 folder levels deep.
  • Folders that start with ., plus node_modules, vendor, appdata, $recycle.bin, system volume information and windows, are skipped.
  • The scan stops at 300 notes, 1500 files or 2.5 seconds, whichever comes first. In a very large folder, later notes may not be considered, and you are not told.
  • For each note, MD-Memo keeps the first heading (or the file name) as the title and the first line as the snippet.
  • 1.2 seconds after you stop typing, it takes keywords (2 or more characters, up to 8) from the current line and the 250 characters before the caret.
  • It scores every other note and shows the top 2 as pills.
Where the keyword matchedScore
Title3
Snippet (first line)1.5
Path1

Installation & Launch

In one line: A single binary with no installer. Run one command and you are ready. Windows x64 macOS 10.15 or later
Windows (winget)
winget install youshinh.md-memo
  • Needs the Microsoft Edge WebView2 Runtime (included with Windows 11)
  • MD-Memo cannot start without the runtime
macOS (Homebrew)
brew install --cask youshinh/tap/md-memo
  • macOS 10.15 or later
  • The first launch needs the step in "macOS First Launch" below
macOS First Launch

Releases are ad-hoc signed and not notarized by Apple, so Gatekeeper blocks MD-Memo.app the first time. Right-click (Control-click) the app in Finder and choose Open, or run xattr -dr com.apple.quarantine "MD-Memo.app" once.

Limits and details (other ways to get it, update check)
  • Install from a zip: Download a zip from the Releases page and unpack it into any folder.
  • Universal binary: Starting with the next release, the macOS build is a universal binary and supports both Apple Silicon and Intel Macs.
  • No Mac to test on? Every push to the repository builds MD-Memo.app on GitHub's hosted macOS runners. Open the Actions tab (or trigger the CI workflow by hand with Run workflow), open the latest CI run, and download md-memo-macos-<commit-sha> from Artifacts. It is ad-hoc signed the same way, so the same first-launch step applies.
  • Update check: Shortly after launch, MD-Memo asks GitHub whether a newer release exists (a single request to api.github.com; no note content is sent). If there is one, a small badge appears on the Help (?) button.

System Tray & Instant Summon (Ctrl+Alt+M)

In one line: Closing the window does not quit MD-Memo, and a hotkey brings it back instantly. Ctrl + Alt + M
Windows Ctrl + Alt + M
  • The close button (✕) does not quit. MD-Memo stays in the system tray
  • Garbage collection trims memory use to only 5–15 MB
  • To quit completely, use the tray icon
macOS Option + Cmd + M
  • There is no menu-bar icon. Closing the window leaves MD-Memo in the Dock (memory is trimmed the same way)
  • Click the Dock icon, or press the hotkey, to bring it back
  • To quit, press Cmd+Q

Press the hotkey from any app. The window jumps to the front and the cursor returns to where you left it.

The hotkey only summons

Pressing it again does not hide the window. To send MD-Memo back to the background, close the window.

Autonomous IME Shield (IME Guardian)

In one line: Type code or URLs with a Japanese IME on, and full-width letters no longer sneak in.

Typing inline code (`...`), code blocks (```) or URLs with the IME on can leave full-width letters such as cat or find, and the command then fails. IME Guardian removes that annoyance.

  • Lexical scope protection: Inside code blocks, it steers you to half-width alphanumeric mode automatically (only 11 µs of input delay).
  • Romaji auto-repair in direct input: If you type "konnitiha" while in half-width direct input mode, it is converted to hiragana for you.

Daily Scraps Model

In one line: You do not need to think of file names. A scrap file is created for each day automatically.

MD-Memo creates a daily scrap file (scraps/YYYY-MM-DD.md) for you, for quick journaling and terminal pipe captures.

With Ctrl+Shift+F (described below), you can search years of daily scraps in milliseconds.

02 Capabilities Guide

In one line: Features are organized around three verbs, Write, Run and Delegate, each with one entry point. If you are not sure what to do, press Ctrl + J for Quick Actions.

Which one do I use?

What you want Entry point What it does
Write
Fix or draft the text in front of you
Ask AI
Ctrl + L
(macOS: Cmd + L)
The built-in LLM answers about your selection (or the current line) in seconds, and the answer appears right below it.
Run
Execute a command
Command Bar
Ctrl + E
(macOS: Cmd + E)
Pipes your selection through a shell command and replaces it with the output. As fast as the command itself. Press Tab in the bar and the AI writes the command for you.
Delegate
Hand off a whole investigation or implementation
Auto selector
Ctrl + Enter on a line
(macOS: Cmd + Enter)
or type {{ instruction }}
MD-Memo decides whether the line goes to the built-in AI, an agent or a command, and the result lands below it. An external agent CLI (Claude Code, Codex, Hermes, Antigravity, …) works in the background for minutes. See Auto Selector.
Not sure what to do Ctrl + J
(macOS: Cmd + J)
Suggests up to three next steps for what you are writing (Quick Actions). Each card maps to Write, Run, or Delegate.

Telling the three verbs apart

Write Ctrl + L
  • Acts on the text right in front of you
  • Select it, then press Ctrl + L; the answer appears below
  • Returns in a few seconds
Run Ctrl + E
  • Use it when you want a command's output
  • No need to wait for an AI
  • Returns almost instantly
Delegate Ctrl + Enter
  • Write a line, or {{ ... }}, and press Ctrl + Enter
  • Research or implementation you would rather not do by hand
  • Can take a few minutes
  • You can keep editing the note while it runs

Write · Ask AI (Ctrl+L)

In one line: Type an instruction about the selected text (or the current line), and the answer appears right below it. Your own text is never replaced. Ctrl + L LLM setup needed
The Ask AI bar opened with Ctrl+L: a small bar under the selected line with an instruction typed in and a chip that reads Selection: 58 chars
Ctrl + L: the ask bar opens under the selected line, with an instruction typed in
  1. Selected text The instruction applies to it. With nothing selected, the AI reads the current line, and on a blank line the whole note
  2. Ask bar Type what to do with the text
  3. Target chip What the AI will read: Selection (with its length), Current line or Whole note
  4. Run button Enter also runs it, and Esc closes the bar. The answer is inserted below the text
  1. Select text, or put the caret on a lineSelect the part you want to translate or summarize. With no selection, the AI reads the current line
  2. Press Ctrl + L and write an instructionThe ask bar opens right under the caret, with no dialog and no context switch
  3. Press Enter to runThe answer appears below your text. To cancel it, use the task panel (Alt + T)

Example instructions

  • "Explain what causes this error and how to fix it"
  • "Translate this into natural Japanese"
  • "Summarize this into meeting-note bullets"

Ctrl + Enter opens this bar too. On an ordinary sentence, it asks for an instruction and saves it below the sentence as [[ @llm ... ]], with the answer under it. See Delegate · Auto Selector.

Common instructions live in the command palette (Ctrl + Shift + P). Pick one and the ask bar opens with a ready-made instruction:

  • UNIX Pipe: Polish & Refactor: tightens the selection into concise, logical prose.
  • UNIX Pipe: Convert to Bullet Points: extracts the key points as structured Markdown bullets.
  • UNIX Pipe: Extract Action Items: pulls TODOs out of the text as a - [ ] checklist.
Limits and details
  • What the AI reads: the selection; with no selection, the current line; on a blank line, the whole note. The chip on the bar tells you which one applies. In an empty note it says "No target text (free question)" and only your instruction is sent.
  • Where the answer goes: below the last line of that text, with one blank line before and one after. The selection or line itself is never replaced. On a blank line, the answer takes that line.
  • If the LLM is not set up: the bar does not open. A message says "LLM is not configured (Settings -> AI Models)" and the note is untouched. That is the case when the model or the URL is empty, or when a cloud service such as Gemini or OpenAI has no API key (local servers such as Ollama need no key).
  • While it works: a placeholder such as [AI Generating: first 20 characters of your instruction...] sits in the note, and the answer replaces it when it arrives.
  • If it fails: one line, [LLM error: ...], is left instead (the message is shortened to one line).
  • Cancel: the task panel (Alt + T) lists the request. Cancel it there and the placeholder disappears, so the note is back as it was. The request itself is not stopped; an answer that arrives later is discarded.
  • Japanese input: pressing Enter to confirm an IME conversion does not send the instruction. Press Enter once more to run it.
  • Other ways in: the toolbar AI button, the right-click item "Ask AI..." and the palette item "Ask AI" open the same bar. It uses the built-in text LLM (Settings → AI Models).
  • Answer fences: if the model wraps its entire answer in a single ```markdown / ```md fence, MD-Memo removes that fence before inserting. A real code answer (```python and the like), or an answer that merely contains fenced blocks among other text, is inserted exactly as returned.
  • Old shortcut: if you had saved Ctrl + K for this bar, MD-Memo moves it to Ctrl + L once and shows a notice; the separate prompt dialog was merged into this bar.

Write · Ghost Text (Predictive Completion)

In one line: The passive form of Write. Pause while typing and the next words appear in dim text. You never have to summon it. Tab to accept LLM setup needed
A grey ghost-text suggestion after the caret while a new checklist item is being written
A grey suggestion for the rest of a new checklist item
  1. Caret What you have typed so far
  2. Ghost text The grey prediction. Press Tab (or →) to accept it, and Ctrl + → to accept one word
Tab
Accept all
Types the whole suggestion
Ctrl
Accept one word
macOS: Option + →
Any key
Ignore and keep going
Keep typing and it fades away quietly
Limits and details
  • Suggestions come from a local LLM (Ollama / Gemma 4) or a cloud API. The setting is "Inline Autocomplete (Ghost Text)" in Settings → AI Models.
  • The default wait before a suggestion appears is 500 ms. The settings screen allows 200–2000 ms, but the effective minimum is 300 ms.
  • Click the "Predict" badge in the status bar to switch it on or off.

Write · Proofreading & Typo Correction (Alt+C)

In one line: Select text and press the key. You write no instruction, and it fixes only typos and awkward phrasing. Alt + C LLM setup needed
  1. Select textPick the part you want to polish, such as meeting notes or a report
  2. Press Alt + CmacOS: Cmd + Shift + C. No prompt is needed

It polishes the text instead of rewriting your meaning, so it suits the final pass on meeting notes and reports. You can turn it on or off with "Enable AI typo & error correction (Alt+C)" in Settings → General.

Write · Paste Image OCR (Ctrl+V)

In one line: Copy an image and paste it. The text, tables and code inside it become Markdown. Ctrl + V API key needed
  1. Copy an imagePut a screenshot or a diagram on the clipboard
  2. Press Ctrl + V in MD-MemoGemini Vision OCR starts
  3. Markdown is pastedThe text, tables and code in the image arrive as structured Markdown
Limits and details (required settings)
  • In Settings → AI Models → Image OCR (Vision), set an image model such as Gemini and its API key.
  • The switch "Automatically transcribe pasted images (Ctrl+V) using Gemini OCR" must be on (it is on by default).
  • It works only when the clipboard holds an image and nothing else. If there is also text, the text is pasted.
  • A local vision model (Ollama or LM Studio) can do OCR without an API key.
  • To paste the image as an image, without OCR, use special paste (Ctrl + Shift + V), which saves it to assets.

Write · Smart Paste (Ctrl+V / Ctrl+Shift+V)

In one line: Paste web pages, Word and Excel content as Markdown with Ctrl + Shift + V. Use Ctrl + V to paste without formatting. Special paste needs no API key
The result of copying an HTML table and pressing Ctrl+Shift+V: a Markdown table, with a conversion toast in the status bar
An HTML table copied and pasted with Ctrl + Shift + V
  1. Pasted table The HTML table was converted to a Markdown table
  2. Toast The status bar says "Pasted as Markdown"
Ctrl + V Plain paste
  • Text: Pasted as plain text, with the source formatting stripped
  • If the clipboard has both text and an image, as Excel and Word do for cells and paragraphs, the text is pasted and the image is ignored
  • Image only: The Image OCR vision model transcribes it to Markdown / Mermaid
  • OCR needs "Automatically transcribe pasted images (Ctrl+V) using Gemini OCR" switched on and an API key (Settings → AI Models → Image OCR (Vision))
Ctrl + Shift + V Special paste
  • HTML: HTML from web pages, Word and Google Docs is converted to Markdown and pasted
  • HTML wins over an image on the same clipboard, so cells copied from Excel or a table from Word become a Markdown table
  • Image only: Saved as ./assets/YYYY-MM-DD-HHmmss.png, and ![image](./assets/...) is inserted at the caret. It is not sent for OCR
  • Text only: Same result as Ctrl + V
Limits and details

What is converted (a built-in converter with no external dependency)

  • Headings (h1 to h6), paragraphs, line breaks and horizontal rules
  • Bold, italic, strikethrough, inline code, and fenced code blocks with a language
  • Nested blockquotes, nested lists that keep their start number, and task-list checkboxes
  • Links (with title) and images
  • GFM tables with column alignment (a literal | inside a cell is escaped)
  • The wrapper markup that Google Docs adds around copied content

Removed for safety: the contents of <script>, <style>, <iframe> and <svg>, javascript: and data: links, and data: images.

Saved image name: The extension follows the real image type (.png, .jpg, .gif or .webp). A name collision appends -2, -3, and so on.

Where ./assets/ lives: next to the note if it has been saved; otherwise the current workspace folder; and if there is no workspace either, the app data folder. In that last case the inserted link is an absolute file:/// link instead of a relative one.

If no HTML is available: If the paste event itself carries no HTML (some apps offer only plain text), Ctrl + Shift + V falls back to the async clipboard API. The embedded browser may then show its own one-time permission prompt. If that still yields nothing, plain text is pasted.

Toast: "Pasted as Markdown" for a converted paste, or "Image saved to assets" when an image-only clipboard was saved to ./assets/.

Ctrl + Shift + V is a fixed key and cannot be changed in Settings → Shortcuts. It used to open Preview to the Side; that command is now on Ctrl + Alt + V (macOS: Cmd + Option + V).

Write · Voice Input (Ctrl+Shift+R)

In one line: Press the key and speak. The transcript is inserted at the caret. Ctrl + Shift + R Gemini API key needed
The recording marker inserted at the caret while voice input is recording
While recording: a marker is inserted at the caret
  1. Recording marker It is replaced by the transcript when recording ends (Esc discards the recording). The marker text is Japanese in both UI languages
  1. Start recordingCtrl + Shift + R (macOS: Cmd + Shift + R). A ⦅音声入力中... [id:xxxx]⦆ marker is inserted at the caret. You can keep typing or click elsewhere while it records
  2. StopClick the Stop button at the bottom left of the window, press Ctrl + Shift + R again, or stay silent for 5 seconds (1–30 seconds in settings) and it stops by itself. Esc discards it: the marker disappears and nothing is sent
  3. Wait for the resultThe marker changes to ⦅文字起こし中... [id:xxxx]⦆ and is replaced by the text when it is done
The recording indicator: a red dot with the elapsed time, the Stop button and the hint "ESC to discard"
While recording: this indicator appears at the bottom left of the window
  1. Recording mark The red dot and the time since recording started
  2. Stop button Click it to stop recording and start the transcription (the same as pressing the shortcut again)
  3. ESC to discard Press Esc to throw the recording away

Four ways to start recording

CtrlShiftR
Shortcut
Change it in Settings → Shortcuts under "Voice Input" (clear it to disable the key)
Toolbar
Microphone button
To the right of Mobile Drop. It looks pressed while recording
Right-click
"Voice input"
An item in the right-click menu
CtrlShiftP
Command palette
Choose "Voice Input"

If transcription fails

The recording is not lost. The audio is kept in the app data folder under voice_cache, and the marker changes to this:

⦅文字起こし失敗: [再試行(id:xxxx)] [音声保存] [破棄]⦆
The marker left when transcription failed, with retry, keep audio and discard actions side by side
The marker left after a failure. Click inside the brackets to choose
  1. [再試行] Retry: send the saved audio for transcription again
  2. [音声保存] Keep audio: move it to the note's ./assets/ and insert an [audio](...) link
  3. [破棄] Discard: delete the saved audio and remove the marker

This recovery also works after you restart the app (the saved audio and the marker's id survive a restart).

Settings (Settings → AI Models, "Voice input" group, right below the Image OCR (Vision) settings)

Setting Default Description
Voice model gemini-3.5-transcribe Suggestions: gemini-3.5-transcribe, gemini-2.5-flash, gemini-flash-lite-latest.
API style Auto Auto / Interactions API / generateContent. Auto uses the Interactions API when the model name contains "transcribe", and generateContent otherwise.
Language codes Empty Comma-separated BCP-47 codes (for example ja-JP, en-US). Empty means auto-detect, which also handles mixed languages.
Mode Smart Smart removes fillers and formats the text for reading. Verbatim transcribes word for word.
Custom vocabulary Empty One term per line (names, jargon). Up to 1000 terms, but about 100 works best.
Silence timeout (s) 5 1–30. Recording stops by itself after this many seconds of silence.
Transcription prompt Built-in instruction Used only by generateContent-style models.
API key / Base URL Empty Empty means the Image OCR (Vision) settings are used. There is no separate input field for them.
Messages and errors

Each message is shown in the status bar for 6 to 9 seconds.

Message Meaning and what to do
Preparing the microphone... Shown right after you press the key.
Waiting for microphone permission. ... Shown when there is no answer after 5 seconds. The first time, WebView2 shows its own permission prompt: choose Allow. MD-Memo never grants microphone access silently.
Microphone access is blocked. ... In Windows Settings → Privacy & security → Microphone, let desktop apps access your microphone.
No microphone was found No microphone is connected.
The microphone cannot be opened. ... Another app may be using the microphone.
Could not use the microphone A general message for anything not covered above.
Voice input works in the editor view Shown when you press the key in the rendered preview view. Go back to the editor view.
Limits and details (model, privacy, requirements)
  • Model: The default is gemini-3.5-transcribe (it used to be gemini-2.5-flash). Gemini models only: there is no offline or non-Gemini option.
  • How it is called: Google's Gemini 3.5 Transcribe is called through the Interactions API (POST {base}/v1beta/interactions, header x-goog-api-key). Older models such as gemini-2.5-flash run through generateContent with a prompt.
  • The live model cannot be used: gemini-3.5-transcribe-live is the streaming (Live API) variant and cannot be used for recorded audio. Choosing it shows an error that says so.
  • Privacy: MD-Memo always sends store: false, so Google does not keep the recording or the transcript.
  • Keys: If the API key and Base URL are empty, the Image OCR (Vision) settings are used. The config file also has voice.apiKey / voice.baseUrl keys, but the settings screen has no field for them.
  • Japanese IME: The shortcut works even while the IME is on.
  • Microphone permission: The permission prompt comes from the embedded browser (WebView2), not from the OS, and only the first time you record.
  • macOS: A microphone usage description is built in, but behavior on macOS has not been fully verified yet.

Run · Command Bar (Ctrl+E)

In one line: Pipe the selected text through a local UNIX command and replace it with the command's standard output. Ctrl + E No key needed
The command bar opened with Ctrl+E in CLI mode, with sort -u typed in
Ctrl + E: the bar in CLI mode with a command (sort -u) typed in
  1. Mode badge It says "CLI". Click it, or press Tab, to switch to AI mode. The mode you pick is remembered
  2. Command field Type a shell command, or pick one from the drop-down list: your recent commands and ready-made ones such as sort -u, jq . and git status
  3. Run (Enter) Sends the selection (or the whole note if nothing is selected) to the command, and its output comes back
  1. Select textIf you select nothing, the whole note is used
  2. Press Ctrl + E to open the barIt opens in the mode you used last (CLI mode the first time). If the badge says "AI CLI", press Tab
  3. Type a command and press EnterThe selected text is replaced by the command's output. Esc closes the bar
One bar, two modes

Ctrl + E opens one command bar in the mode you used last. Press Tab, or click the badge at the left edge of the bar (CLI / AI CLI), to switch modes at any time. Rule of thumb: if you can write the command yourself, use CLI mode; if you can't, use AI mode.

The two keys that open one specific mode, "Command Bar: CLI mode" and "Command Bar: AI mode", have no default key. You can assign them in Settings → Shortcuts (group "Command Bar").

Example commands (type them yourself)

  • jq .: pretty-print and indent JSON
  • sort -u: drop duplicate lines and sort alphabetically
  • tr a-z A-Z: convert to uppercase
  • duckdb -box: run SQL inline and print a table
Limits and details
  • What happens to the result: It is set by "Open CLI execution results in a new tab" under Settings → Agent, in the "Commands (Run)" section. When it is on (the default), the selected text is replaced by the output and the result also opens in a new tab. When it is off, no new tab opens, and with no selection the whole note is replaced by the output.
  • Empty output: If a command succeeds but prints nothing, the result tab shows "(no output)".
  • Working directory: Commands run in MD-Memo's own working directory.
  • The drop-down list: Your recent commands come first, then your own command snippets from agents.yaml, then the fixed filters (sort, sort -u, jq ., tr, wc -l, duckdb -box and more), then the built-in command snippets for your OS: Current date and time, Git status, Git diff summary, Git recent commits, List large files and List files. A snippet whose body has a placeholder such as ${selection} or $0 is left out. The same snippets can be inserted as [[ $ ... ]] tasks (see Auto Selector).

Run · Command Bar: AI Mode (Ctrl+E, then Tab)

In one line: Describe what you want in plain language and the AI writes the shell command. It is the AI mode of the same command bar. Ctrl + E, then Tab LLM setup needed
The command bar in AI mode (Ctrl+E, then Tab), with the AI CLI badge and a plain-language request typed in
Ctrl + E, then Tab: AI mode with a plain-language request typed in
  1. Mode badge It says "AI CLI". Click it, or press Tab, to go back to plain CLI mode
  2. Request field Instead of writing a command, describe what you want in plain words
  3. Generate (Enter) The AI writes the command into the field so you can check it. Press Enter again to run it
  1. Press Ctrl + E, then TabThe badge at the left edge must say AI CLI (if it already does, skip Tab). The bar opens in this mode next time
  2. Describe what you want to doFor example: "find files modified in the last 24 hours" or "kill whatever is using port 8080"
  3. Press Enter to generateThe AI writes the matching shell command and puts it in the bar
  4. Read it, then press Enter to runAlways read the command before you run it
Safety check before running

Every generated command goes through a safety check before it runs. Commands that could destroy your system are refused, and risky ones show a warning.

Delegate · Auto Selector (Ctrl+Enter)

In one line: Write a line and press Ctrl + Enter. MD-Memo decides, by fixed rules on your PC, whether the line is for the built-in AI, an agent or a command, and puts the result below the line. LLM setup needed Agent CLI needed separately

Four keys, four jobs (on macOS, read Ctrl as Cmd)

CtrlL
Ask
Ask AI: the answer appears below the selected text
CtrlE
Pipe (Run)
Command Bar: replace the text with a command's output
CtrlEnter
Delegate, do what I mean
Auto selector: does what the line asks for
CtrlJ
Suggest
Quick Actions: up to three next steps
Write a lineA request, a command, or {{ @agent ... }}
Ctrl + EnterMD-Memo decides where the line goes
The result lands belowYour line stays; the result sits under it
A note after Ctrl+Enter on a request line: the line now reads [[ @llm Translate the checklist above into Japanese ]], and the translated checklist sits below it between two HTML comment lines
Ctrl + Enter on a request line: it became [[ @llm ... ]] and the answer arrived below it
  1. Your instruction The line was rewritten as [[ @llm ... ]] and stays in the note
  2. Opening comment line Marks where the result starts (md-memo:res and a short id)
  3. The answer It sits between the two comment lines
  4. Closing comment line Marks where the result ends

How to use it

  1. Write one lineA request such as "Translate the checklist above into Japanese", or a command such as git status
  2. Press Ctrl + EnterWith the caret on that line. macOS: Cmd + Enter
  3. Let it workAn AI request runs at once. For an agent or a command, the line is rewritten and waits: press Ctrl + Enter again to run it, or Ctrl + Z to undo the rewrite
  4. Read the result below the lineIt sits in a block between two comment lines. Press Ctrl + Enter on the instruction line again to run it again; the block is replaced

An agent or a command waits for a second press. The line is rewritten, and a message tells you how to go on. An agent task is written for your default agent (Settings → Agent), or for the agent you name with @.

A note where Ctrl+Enter rewrote the line Run the tests and fix the failures into {{ @claude-code ... }}, with a Run button next to it and a message in the status bar
A request that fits an agent: the line became {{ @claude-code ... }} and stopped
  1. Rewritten line The request became an agent task. It has not run yet
  2. Run button The same as pressing Ctrl + Enter again
  3. Message Says how to go on: Ctrl + Enter again to run it, Ctrl + Z to undo the rewrite

Both behaviors have a switch in Settings → Agent, in the "Auto selector (Ctrl+Enter)" group. See Agent & CLI Tab.

An ordinary sentence opens the ask bar. When the line is not clearly a request, MD-Memo asks what to do with it. What you type is saved below the line as [[ @llm ... ]] and runs.

The ask bar opened by Ctrl+Enter on an ordinary sentence: an instruction is typed, the chip says Current line, and the hint says the instruction is saved in the note as [[ @llm ... ]]
Ctrl + Enter on an ordinary sentence: the ask bar opens for that line
  1. The line An ordinary sentence, not a request. The bar is about this line
  2. Ask bar Write what the AI should do with the line
  3. Target chip What the AI will read: the current line, or your selection
  4. Hint The instruction is saved in the note as [[ @llm ... ]]

Two ways a result comes back

Classic {{ ... }}
  • The result replaces the slot
  • Every hand-written {{ ... }}, [? ], 【? 】, [! !], [>> ] and {{ @skill ... }}
  • Undo it with Esc or Ctrl + Z (see Delegate · Agents)
New notations
  • [[ @llm ... ]], [[ $ ... ]] and {{ @agent ... }}
  • Your instruction stays, and the result goes below it
  • Run it again and the old result is replaced
Notations and the result block
You writeIt goes toThe result
[[ @llm instruction ]]The built-in text LLM (Settings → AI Models)Below the line
[[ $ command ]]A shell command, with no input. It passes the same safety check as the command barBelow the line, in a code block
{{ @agent instruction }}An agent from agents.yaml. agent is its key or an alias, not case-sensitiveBelow the line
A classic {{ ... }}As before: the profiles and {{ @skill ... }}Replaces the slot
  • What counts as a notation: A [[ ... ]] is a task only when it starts with @llm or $, so wiki links such as [[Note name]] are left alone. A {{ @name ... }} is an agent task when name is an agent's key or alias. Otherwise it is a skill, as before.
  • One line per task: The whole notation must fit on one line. It may follow a list or quote mark, as in - [[ @llm ... ]] or > {{ @claude ... }}, and a rewrite keeps that mark. Notations inside code blocks or inline code are ignored.
  • Agent tasks: The instruction reaches the agent as you wrote it. The standing instruction of the {{ }} notation (code blocks only) is not added. If nothing follows the name and that agent takes an instruction, the task ends with an error line (its text is Japanese in both UI languages).

What the result looks like

[[ @llm Translate this into English ]]
<!-- md-memo:res a1b2 -->
The translated text
<!-- /md-memo:res -->
  • Result block: Two HTML comment lines with the answer between them. The short id (a1b2, usually 4 characters) is unique in the note. A run never changes your instruction line. The answer is trimmed, and no blank line is added inside. Nothing inside a result block is ever run, even if the answer contains a {{ }}.
  • While it runs: A one-line marker, <!-- md-memo:run a1b2 -->, sits under the line, and the status bar shows the running-task badge.
  • Where you see the comment lines: The editor shows them, and MD-Memo's own preview hides them (a viewer that passes HTML through does not display them either). You may delete them by hand. If you delete the marker while a task runs, the answer is added at the end of the note.
  • Run again: Press Ctrl + Enter on the instruction line. The old result block (or a marker left behind by a crash) is replaced, so results do not pile up. While a task is running you get "This slot is already running."
  • Cancel: Press Cancel on the task in the task panel (Alt + T), which also lists AI and command tasks. The marker disappears and the note is as it was. An AI request cannot be stopped at the provider, so MD-Memo forgets it and drops a late answer. A command or an agent is stopped. If you cancel a re-run, the old result does not come back.
  • If it fails: The block holds one line, [LLM error: ...] or [agent name error: ...]. A command's block holds its output, its error output and an exit code N line.
  • What the AI receives: Only your instruction. A task recorded through the ask bar sends the instruction and the text it was about. Its opening comment then reads ctx=above n=1 (n is the number of lines of that text), for example <!-- md-memo:res a1b2 ctx=above n=1 -->. On a re-run the same text is sent again: up to n non-blank lines directly above the instruction (looking past other task lines and result blocks; at most 80 lines or 8000 characters). A task you wrote by hand, made from a snippet or made by rewriting a line carries no such mark, so only what is inside its brackets is sent.
How it decides, and when something is not set up

The check runs on your PC with fixed rules. It uses no network and calls no model. Each time you press the key, it reads one line, or your selection.

What Ctrl + Enter does, in this order

  1. While a Japanese IME is converting text, the key is left alone. A held-down key runs only once.
  2. The caret is inside a result block: nothing runs. The status bar shows "This is a result block. Write your instruction outside of it."
  3. A task in the new notations is under the caret (with a selection: under the start of the selection, else the first one inside it): only that task runs. Several lines never run at once.
  4. The caret is inside a classic {{ }} slot: it runs, and its result replaces it, as before.
  5. The Auto selector is off, the line is blank, or the line holds a slot that the caret is not inside: the older rule applies. The next slot after the caret runs, and if there is none, the first slot in the note (with no slot at all, the status bar says so). Inside a fenced code block nothing happens.
  6. Otherwise the target is your selection, or the current line. If the selection covers only part of a line or several lines, or the line is not clearly a request, the ask bar opens.
  7. If the whole line looks like a request, MD-Memo decides where it goes:
The line is judged to beWhat happens
An instruction for the AIIf the LLM is set up, the line becomes [[ @llm ... ]] and runs at once.
A job for an agentThe line becomes {{ @agent ... }} and waits. Press Ctrl + Enter again to run it.
A commandThe line becomes [[ $ ... ]] and waits. Press Ctrl + Enter again; the safety check runs first.

With "Confirm before an auto-detected agent or command runs" switched off, an agent or a command runs right after the rewrite. An AI instruction always runs at once.

What counts as an instruction

  • A request: a request phrase (Japanese endings such as ...してください, or English such as "please" and "can you"), a question with a question word or a question mark, or an English command word such as translate, summarize, fix, write or explain.
  • Not a request (the ask bar opens): ordinary statements, headings, URLs, code, table rows, and a line longer than 240 characters.
  • Where it goes: the AI for wording jobs (translate, summarize, proofread, rephrase, bullet points, tables, ideas, explanations). An agent for code and project jobs (implement, refactor, run the tests, commit, pull request, build, research, fix a bug, read an error log). A command for a line that starts with a known command such as git status, or a pipe such as git log | head. If nothing fits, the AI (a text-only answer is the safe side).
  • You can say it yourself: a line that starts with @llm, @agent (a key or an alias) or $ goes where you said.
  • Risky commands are never guessed: a line such as rm -rf build (delete, move, copy, sudo and the like) opens the ask bar. To run one, write [[ $ ... ]] yourself; the safety check then decides.

It can be wrong. The rules are fixed, so a polite request to a person, such as "Please share the materials in advance.", also looks like a request to the AI. When the check is not sure, it opens the ask bar and leaves your note alone until you send an instruction. A wrong guess for an agent or a command is easy to undo, because the line is rewritten first and waits (Ctrl + Z).

When something is not set up

SituationWhat happens
The LLM is not set up (the model or the URL is empty, or a cloud service such as Gemini has no API key)The status bar shows "LLM is not configured (Settings -> AI Models)". Your note is not touched: no rewrite and no marker. Local servers such as Ollama need no key.
The agent is not found (agents.yaml or PATH)The line is rewritten anyway, and a second message warns that the agent was not found. Running it ends with an error line in the result block.
The command is dangerousThe same safety check as the command bar refuses it ("Security Block: reason"). A warning-level command asks you to confirm. If it is refused or you cancel, nothing runs and no result is written.
A command is slowIt is stopped after 30 seconds. If no answer arrives within 40 seconds, the task fails with "No answer from the command (timed out)".
The note changed before the answer could be writtenThe status bar shows "The note changed in the meantime. Press the key again." If you close the note while a task runs, the answer is dropped.

Ready-made tasks (snippets)

Insert a ready-made task instead of typing one. The picture shows the command palette route. Typing {{ lists the same snippets after the notations, and a short word such as ;sum plus Tab inserts one at once.

The Task snippets list opened from the command palette, with number keys, kind tags such as LLM and AGENT, names and one-line previews
Command palette, "Insert task snippet": the list of ready-made tasks
  1. Header The keys: Up and Down move, Enter, Tab or 1-9 insert, Esc closes
  2. A snippet Its number key, a kind tag, its name and a one-line preview. The first nine can be inserted with the keys 1-9
  3. Kind tags LLM (the built-in AI, the answer lands below), AGENT (an agent), CMD (a command) and TEXT (plain text)
  4. The list scrolls The command and text snippets follow, then your own snippets from agents.yaml
Snippets, your own snippets and aliases

Three ways in

  • Type {{: The quick selector (the popup under the caret) lists the notations first, then the snippets, with a kind tag, a name and a one-line preview. The first nine rows have a number key. Enter, Tab or a number inserts one in place of the {{, and Esc closes it. Typing [[ opens nothing, so wiki links are not disturbed. The header of this popup is Japanese in every UI language.
  • Command palette: Choose "Insert task snippet". It lists only the snippets, at the caret.
  • A short word and Tab: At the start of a line or after a space, type an exact short word such as ;sum and press Tab. Any other Tab works as before. Nothing is expanded inside code.

Inserting never runs anything. The caret lands where your text goes; press Ctrl + Enter to run the task.

Built-in snippets

KindShort word and name
LLM
becomes [[ @llm ... ]]
;sum Summarize, ;en Translate to English, ;ja Translate to Japanese, ;proof Proofread, ;rephrase Rephrase, ;bullets Bullet points, ;table Make a table, ;ideas Brainstorm ideas
AGENT
becomes {{ @agent ... }}
;research Research, ;impl Implement, ;test Run tests, ;review Review, ;refactor Refactor
CMD
becomes [[ $ ... ]]
;date Current date and time, ;gst Git status, ;gdiff Git diff summary, ;glog Git recent commits, ;grep Search for a word, ;rg Search for a word (ripgrep), ;wc Count lines (file), ;uniq Unique sorted lines (file), ;jq Pretty-print JSON (jq), ;big List large files, ;ls List files
TEXT
inserted as it is
;llm LLM task (blank), ;agent Agent task (blank), ;cmd Command task (blank)
  • One version per OS: A command that differs between systems is listed only in the version for yours: PowerShell on Windows, sh on macOS and Linux.
  • Placeholders: ${selection} (the selected text), ${line} (the current line), ${date} (today, YYYY-MM-DD), ${agent} (your default agent) and $0 (where the caret lands). Write $$0 or $${ for a literal $0 or ${.
  • The selection: ${selection} is filled when you insert from the command palette with text selected. Otherwise it is empty.
  • Safe by design: A substituted value becomes one line and cannot break a [[ ]] or {{ }}. In a command, quotes, $, ;, | and other shell characters are removed from it. ${selection} and ${line} are cut at 2000 characters in a task and 300 in a command.

Your own snippets and aliases (in agents.yaml, see Customizing it in agents.yaml)

agents:
  my-agent:
    command: "my-cli"
    args: ["--prompt", "{instruction}"]
    aliases: ["mine", "m"]   # {{ @mine ... }} and {{ @m ... }} call my-agent

snippets:
  - id: "weekly"
    label: "Weekly review"
    kind: "llm"
    trigger: "/weekly"
    body: "Summarize this as a weekly review in 3 points: ${selection}"
  • Aliases: aliases gives an agent extra names for {{ @name ... }}. Names are not case-sensitive, and a key wins over another agent's alias. Built in: claude and cc for claude-code, and antigravity and gemini for agy (hermes and codex have none). If your file defines claude-code or agy without an aliases line, these defaults still work, unless another agent already uses the name. A list you write is used as it is.
  • Snippet fields: id, label, kind (llm, agent, command or text) and body. Optional: trigger, os (win, unix or any; for commands) and agent (the agent for a kind: agent snippet; the default agent if left out).
  • Replace or add: A snippet with the id of a built-in one replaces it, and a new id adds one. A snippet with an unknown kind or an empty body is ignored.
  • Trigger: No spaces, 2 to 30 characters. Capitals become lower case and full-width letters become half-width, and the word must match exactly. Built-in words start with ;, and /weekly works as well.
  • When it applies: The {{ list, the palette list and short-word expansion read aliases and snippets when MD-Memo starts, so restart it after you edit them. Running {{ @alias ... }} and the command bar's drop-down list use the new file without a restart (the agent is looked up when the task runs, and the bar reads the file each time it opens).
  • Command bar: Command snippets that need no placeholder, in the version for your OS, are also offered in the drop-down list of the command bar.

Delegate · Hand work to an agent ({{ }})

In one line: Write {{ instruction }} in a note and press Ctrl + Enter. An external agent CLI works in the background, and the whole {{ }} is replaced by the result. Name an agent, as in {{ @claude instruction }}, and the result goes below your line instead. Agent CLI needed separately

This notation is called a slot. To let MD-Memo choose the AI, an agent or a command for a plain line, see Delegate · Auto Selector.

A slot while it runs: the {{ }} block is replaced by a running placeholder and the status bar shows a task badge
A slot while it runs: {{ }} becomes a "running" placeholder and the status bar shows a task badge
  1. Running placeholder It stands in for the slot while the agent works, and the result replaces it (its text is Japanese in both UI languages)
  2. Task badge The number of running agent tasks. Click it, or press Alt + T, to open the task panel
Write (Ask AI)
  • Answers in seconds
  • The answer goes in below your text
Delegate (agent)
  • Spends minutes on web research or file work
  • You can keep editing the note the whole time
Learn {{ }} and nothing else

The other notations below are all variations on it. When in doubt, write plain language inside {{ }} and it will work.

How to run one

  1. Type {{A quick selector opens just below the caret and lists the notations you can use, then ready-made task snippets
  2. Choose a notationMove with and confirm with Tab or Enter. 19 picks an entry at once. Esc closes it
  3. Write the instruction{{ code: }} is inserted, and the caret lands where the instruction goes
  4. Press Ctrl + Enter to runmacOS: Cmd + Enter. You can also click the small Run button (it carries a play icon)
{{ code: write a Go function that loads this project's config file }}

[? What is Go's release cadence in 2025, and what is the current stable version? ]
Limits and details (the run key and input correction)
  • Which one runs: A slot or task under the caret runs. On a plain line, the Auto selector takes over (it is on by default). When the Auto selector is off, or the line is blank, Ctrl + Enter uses the older rule: it runs the next slot after the caret, and if there is none, the first slot in the note. Inside a code block it does nothing.
  • When none is found: The status bar shows "No slot found to run (place the cursor inside a {{ }}-style block)." for a few seconds. This appears only when the older rule applies and the note has no slot at all. Your note is not changed.
  • If it is already running: The status bar shows "This slot is already running."
  • Run button: A small button with a play icon. It appears next to a complete block that is not running yet, while the caret is inside it (hover text: "Run this slot (Ctrl+Enter)"; on macOS, Cmd+Enter). It also appears at the right end of a task line ([[ @llm ... ]], [[ $ ... ]], {{ @agent ... }}) that is not running. Clicking it does the same as pressing Ctrl + Enter.
  • Quick selector: It also disappears on its own as soon as you keep typing normal words.
  • Japanese input: If a Japanese IME turns your brackets into full-width characters ({{, 【?), they are converted back to half-width automatically.
  • No accidental runs: Delimiters inside fenced code blocks, inline code, Markdown links and bare URLs are never treated as slots, so a {{ }} in a code sample does not fire.

The default notations

Notation Profile Default agent What it is for
{{ ... }} code claude-code Code generation. Returns a runnable code block with no preamble.
[? ... ] research claude-code Research. Searches the web and answers concisely with figures and primary-source URLs.
【? ... 】 writing hermes Writing. Stays fully local — no outbound calls — and reshapes the text into clear bullets.
[! ... !] adversarial claude-code Adversarial review. Names three risks, vulnerabilities, or bottlenecks instead of agreeing with you.
[>> ... ] deep-research-and-code (recipe) default agent Multi-step run: research → risk critique → implementation, in order.
  • Each notation carries its own agent and its own standing instruction (system instruction), so the same sentence comes back in a different shape depending on which one you use.
  • Any slot can start with a role name (for example {{ research: something to look up }}). This name becomes the label for that task in the task panel.
  • If your project has skills/<name>/SKILL.md, writing {{ @skill-name: instruction }} passes that file's contents to the agent as extra instructions. If it cannot be found, the slot is replaced by an error. A name that is an agent's key or alias is an agent call instead (next item).
  • Naming an agent: {{ @claude-code instruction }} hands the instruction to that agent directly. The name is a key under agents in agents.yaml, or one of its aliases (not case-sensitive). By default claude and cc mean claude-code, and antigravity and gemini mean agy. Unlike the notations above, your line stays and the result goes below it, and the notation's standing instruction (code blocks only) is not applied. Details: Auto Selector.

While it runs, and the task panel (Alt+T)

The moment a slot starts, it turns into {{ ⟳ 実行中... }} in place. A task in the new notations keeps its line and gets a one-line marker below it instead. The agent runs in the background, so you can edit elsewhere in the note, or start several slots at once.

The task panel opened with Alt+T, with two running agent tasks
Alt + T: the task panel with two running agent tasks (some texts, such as the elapsed seconds and the clear button, are Japanese even in the English UI)
  1. Task badge In the status bar. Click it, or press Alt + T, to open the panel
  2. Panel title The number of active tasks. The clear button empties the history
  3. A running task Agent name, instruction, elapsed time and a Cancel button
  4. Live output The agent's latest output (Hover Peek), updated while it runs
  • Task panel: Press Alt + T (macOS: Option + T), or click the running-task indicator in the status bar. It lists the running tasks and a short history, including AI requests (Ask AI and the Auto selector) and commands.
  • Progress (Hover Peek): Each task card shows the agent's latest output line, refreshed every second, so you can tell whether it is stuck or moving.
  • Cancel: The card's Cancel button ends the process, and the slot goes back to your original instruction. For a task in the new notations, the marker line under it disappears.
  • Timeout: 180 seconds by default. After that the slot is replaced by a timeout message. You can set 10–600 seconds under Settings → Agent, in the "Agents (Delegate)" section. But if an agents.yaml already exists (even one created by "Open agents.yaml"), the file's value wins.

Results are merged only after you have stopped typing for about half a second, so an agent finishing mid-sentence never moves your caret out from under you.

Getting the result, and undoing it

The editor right after an agent result was inserted, with a 3 px amber line on its left edge
Ghost Diff: the left edge of the editor about 0.3 seconds after a result was inserted
  1. Amber line on the left edge It shows that an agent result just changed the note. It disappears after the time you set
  2. Inserted text The agent's result, in place of the slot. Press Esc within the highlight time to restore the original slot
  • Ghost Diff (the left-edge line): Right after a result is inserted, a 3 px amber line appears on the left edge of the editor. It spans the full height of the editor, so it does not mark only the changed lines.
  • How long it shows: Set it with "Change highlight duration (ms) (Ghost Diff)" under Settings → Agent (default 4000 ms, 1000–10000). The line disappears when the time is up.
  • Undo: During that time (the set time plus 1 second), press Esc and that slot alone reverts to your original instruction. Ctrl + Z undoes the last slot run the same way.
  • Inline slots stay inline: If the slot had other text on its line, line breaks are removed from the result so it stays on one line.
  • Results written below a line: Ghost Diff and the Esc revert belong to slots that are replaced by their result. A result written below a task line has no amber line.

Approval gates in recipes

A recipe such as [>> ... ] runs several steps in order. To put a human check before a risky step, set requires_approval_step on the recipe. The run pauses after that step, and a line like this is inserted into the note (the inserted text is Japanese in both UI languages):

- [ ] 次のステップ(実装コードを生成する)を実行する // approve
  1. Review what you have so farChange [ ] to [x]
  2. Press Ctrl + EnterThe run continues. If you leave the box unchecked, it stays stopped there

Agent CLIs are installed separately

MD-Memo does not bundle any agent. Install the commands you intend to use — claude, codex, ollama, agy — and make sure they are on your PATH.

Caution: the built-in agy agent does not ask first

The built-in agy (Antigravity) agent starts with --dangerously-skip-permissions, so a slot using it edits files and runs commands without asking. Settings → Agent warns you when the selected agent is set up this way. To be asked first, override agy in agents.yaml (below) and remove that flag from its args.

Limits and details (error display, working directory and .env)

When a command cannot be found, the slot is replaced by an error like the one below (the inserted text is Japanese in both UI languages). Fix the cause, put the caret back in that slot and press Ctrl + Enter to run it again.

{{ ⚠ エラー: エージェント起動失敗: ... (再試行: Ctrl+Enter) }}
  • Working directory: The project root, found by walking up from the note until a folder that contains .md-memo/, agents.yaml (or agents.yml / agents.json), AGENTS.md, skills/ or .git/. If none is found, it is the note's own folder.
  • .env: If the project root has a .env file, its variables are passed to the agent as environment variables (only that file is read).
  • Tasks with a result below: The error is one line inside the result block, such as [claude-code error: ...]. Fix the cause and press Ctrl + Enter on the task line to run it again.

Customizing it in agents.yaml

Every notation, agent, alias, recipe and snippet can be changed or added in agents.yaml.

  1. Click "Open agents.yaml"It is in Settings → Agent, in the "Agents (Delegate)" section. If the file does not exist, a commented template is created and opened
  2. Edit notations, agents, aliases, recipes and snippetsSave the file as UTF-8 without a BOM
  3. It takes effect on the next slot runIf the file has a syntax error, MD-Memo silently falls back to the defaults. If you changed notations (slot_profiles / recipes), aliases or snippets, restart MD-Memo so the {{ list, the palette list and short-word expansion see them (running a {{ @alias }} task and the command bar list already use the new file)

The first file found, from the top, is used (.yaml, .yml, .md and .json are all accepted):

  1. <scraps folder>/.md-memo/agents.yaml (per-project settings)
  2. %APPDATA%\md-memo\agents.yaml (macOS: ~/Library/Application Support/md-memo/agents.yaml)
Example and writing rules
version: 2
default_agent: claude-code
timeout_seconds: 180
hover_peek_enabled: true
ghost_diff_duration_ms: 4000

# 1. The CLIs to call. {instruction} becomes your prompt, {file} the note's absolute path.
agents:
  claude-code:
    command: "claude"
    args: ["--file", "{file}", "--prompt", "{instruction}"]
    description: "Claude Code"
  my-agent:
    command: "my-cli"
    args: ["--prompt", "{instruction}"]
    description: "Our in-house agent"
    aliases: ["mine"]   # {{ @mine ... }} calls my-agent

# 2. Notation-to-agent mapping. Only what you list here stays active.
slot_profiles:
  - trigger_open: "{{"
    trigger_close: "}}"
    name: "code"
    agent: "claude-code"
    system_instruction: "Skip any preamble and output only a runnable code block."

  - trigger_open: "<<"
    trigger_close: ">>"
    name: "review"
    agent: "my-agent"
    system_instruction: "Review the changes and report your findings as bullet points."

# 3. Recipes run several steps in sequence.
recipes:
  - trigger_open: "[>>"
    trigger_close: "]"
    name: "deep-research-and-code"
    description: "Research -> risk critique -> implementation"
    steps:
      - "Research the current official specification and best practices"
      - "Point out migration risks and breaking changes"
      - "Generate the implementation based on the above"
    requires_approval_step: 2
    self_refine: true
  • Placeholders: {instruction} is replaced by what you wrote in the slot, {file} by the current note's absolute path. If you never mention {instruction}, it is appended as the final argument.
  • Choosing delimiters: pick trigger_open / trigger_close pairs that do not collide with ordinary Markdown syntax (#, *, -, and so on).
  • How overriding works: writing slot_profiles or recipes replaces the defaults, so copy over any of the four built-in notations you still want. agents behaves differently: built-in agents you don't override are kept.
  • self_refine: set it to true and the recipe's first step runs a draft → self-critique → revise loop (up to two passes) before moving on.
  • aliases and snippets: aliases gives an agent extra names for {{ @name ... }}, and snippets adds your own ready-made tasks. Both are described under Auto Selector.
  • Save the file as UTF-8 without a BOM.

Suggest · Quick Actions (Ctrl+J)

In one line: The "I don't know what to do next" button. MD-Memo reads what you are writing and proposes up to three next steps as cards. Ctrl + J Works with built-in rules
The Quick Actions panel opened with Ctrl+J, with three suggestions: delegate to an agent, run a command, and write text
Ctrl + J: the Quick Actions panel with three suggestions (Delegate, Run, Write)
  1. Panel header Key hints: Ctrl+1..3 runs a suggestion at once, Ctrl+Tab moves the highlight, Enter confirms and Esc closes
  2. Delegate Hands the work to an agent that runs in the background
  3. Run Executes a command and inserts its output
  4. Write The built-in AI writes text and inserts it

The cards are chosen to be unlike each other in kind. Picking one takes you straight to that verb's entry point.

Delegate
  • Inserts a {{ … }} or [? … ] slot and hands it to an agent
Run
  • Runs a shell command such as git status
Write
  • Has the AI draft text
  • Appears only when an external inference model is configured

With the built-in local rules (the default), you get Delegate and Run cards, typically in the order Delegate, Run, Delegate.

Ctrl1–3
Run a card directly
macOS: Cmd + 1–3. Alt + 1–3 also work
CtrlTab
Move the selection
Ctrl + Shift + Tab goes back. It is the Ctrl key on macOS too
Enter
Run the selected card
Press it after moving the selection with Ctrl + Tab
Esc
Close
Closes the panel
Safety check before running

Cards that run a shell command always go through a safety check first. If it finds a destructive command such as rm, dd or mkfs, a write into a protected system directory, or a fork bomb, the card is not run and the reason is shown. It guards against known dangerous patterns, so read the command yourself before you accept it.

Limits and details (panel behavior, auto-suggest, badge)
  • Hint line: While the panel is open it shows "Ctrl+1..3 Run now / Ctrl+Tab Move → Enter Confirm / Esc Close".
  • A bare Enter: If you press Enter without first moving the selection with Ctrl + Tab, it is just a newline. No card runs, and the panel closes.
  • It stays out of your typing: Bare digits, a bare Tab and Ctrl + Enter (the Auto selector's key, which also runs slots) are never taken by the panel.
  • Auto-suggest: Besides Ctrl + J, the panel can appear on its own after a typing pause (on by default). To stop that, choose "Manual trigger only (suppress auto-popup, press Ctrl+J)" under Settings → Agent, in the "Suggestions (Quick Actions)" section. The delay before it appears is set there too.
  • Changing the key: The shortcut itself can be reassigned under Settings → Shortcuts.
  • Status bar badge: The "Action" badge shows the current mode, and each click cycles On → Manual → Off → On. It reads "Action: ON", "Action: Ctrl+J" (your configured key; Cmd+J on macOS) or "Action: OFF". It mirrors the two checkboxes under Settings → Agent → Suggestions (Quick Actions). While it is Off, Ctrl + J does nothing.
  • Commands with no output: If a Run card (an sh card) command succeeds but prints nothing, > (出力なし) is inserted so you can tell it ran. This applies to Quick Actions only (the command bar shows "(no output)" in its result tab). The inserted text is Japanese in both the English and Japanese builds.
  • Working directory: Run-card commands run in MD-Memo's own working directory. For example, git status -s returns the state of the folder where MD-Memo was started.
Limits and details (data that is sent)
  • By default, suggestions come from the built-in local rules only. Nothing from your note leaves your machine.
  • Data is sent only if you enter an API key (it goes to OpenRouter's fixed endpoint) or change the Base URL to something other than the OpenRouter default (it goes to <Base URL>/predict). Then an external inference model (such as Jev) is queried.
  • What is sent is an excerpt around the caret: up to 1,500 characters before it and 500 after (about 2,000 in total).
  • The Base URL and Model Name fields come pre-filled with https://openrouter.ai/api/v1 and jev-latest, but while the API key is empty, nothing is sent.
  • The safety check is the AST guardrail. The glossary explains these internal names.

Editor & Split Mode (Ctrl+\)

In one line: Split the fast monospace Markdown editor into two panes: write on the left and watch the preview on the right. Ctrl + \ No setup needed
Split view: Markdown on the left, and a live preview with a rendered Mermaid diagram on the right
Split view: Markdown on the left, and a live preview with a rendered Mermaid diagram on the right
  1. Editor The Markdown source
  2. Preview header The note name and the pane buttons
  3. Mermaid diagram Drawn from the code block in the note
  4. Scroll sync Toggles whether both panes scroll together
  5. Divider Drag to resize the panes, double-click to reset to 50:50
  1. Switch to two panesClick the split icon in the header, or press Ctrl + \ (macOS: Cmd + \)
  2. Make the right pane a previewThe preview icon on the right pane shows the live HTML rendering
  3. Scrolling stays in syncScroll one pane and the other follows

To open only the preview to the side, use Ctrl + Alt + V (macOS: Cmd + Option + V).

Live Mermaid Diagrams & Image Rendering

In one line: A diagram written in a ```mermaid block is drawn right in the preview. You can also export it as a high-resolution PNG image.
Drawn in the preview No setup needed
  • Flowcharts, sequence diagrams and Gantt charts written in ```mermaid are supported
  • They are rendered as diagrams in real time in the preview
Diagram to image Gemini key needed
  • Right-click a diagram and choose "Render Image..."
  • It works with Gemini (Nano Banana 2 Lite) and exports a high-resolution PNG image
Limits and details (image settings)
  • Choose the model, aspect ratio and resolution under "Image Generation (Mermaid & Infographics)" in Settings → AI Models.
  • If the Gemini API key field is empty, the Vision key is used, then the Text key, in that order.
  • The image is saved as assets/diagram_<number>.png, and ![Generated Diagram](assets/diagram_...png) is inserted. Save the note first to get a relative link.

Parallel Daily Scrap Search (Ctrl+Shift+F)

In one line: Find a word across tens of thousands of lines of past daily scraps in under 150 ms, then click a result to jump straight to that line. Ctrl + Shift + F No setup needed
The scraps search opened with Ctrl+Shift+F, showing the query API and its results
Ctrl + Shift + F: the results for "API"
  1. Search box Searches every daily scrap as you type
  2. File name and line number Where the match is
  3. Matching line Shown with the line before and after it. Enter or a click opens the file at that line
  1. Open the search modalCtrl + Shift + F (macOS: Cmd + Shift + F)
  2. Type a wordIt searches across all past daily scraps
  3. Click a result lineYou jump straight to that line
Limits and details

It uses all available CPU cores (runtime.NumCPU()) to run a multithreaded, case-insensitive substring search (plain text, not a regular expression) across your historical scraps.

Mobile Drop · Send from your phone (Ctrl+Shift+U)

In one line: Scan a QR code with your phone and send photos, voice notes, text or URLs, or a small text file to the note on your PC. No app and no account needed. Ctrl + Shift + U
PhoneScan the QR code
PhonePick photos, a voice note or text, and send
PCAppended to the end of the note, with one heading per item
The Mobile Drop dialog on the PC: a QR code, the pairing address, the selection shared with the phone, and the countdown
The dialog on the PC: QR code, address, the selection shared with the phone, and the time left (the QR code and address are demo values)
  1. QR code Scan it with the phone camera (phone and PC on the same Wi-Fi / LAN)
  2. Address The one-time address behind the QR code
  3. Sharing with phone The text selected in the editor is shown on the phone (the "Text from PC" card)
  4. Countdown Time until the idle timeout. When it runs out, the dialog closes and the address stops working (activity on the phone extends it)
  5. Switch to an outside connection An optional switch to a Cloudflare tunnel, for mobile data or another Wi-Fi
  1. Open the dialogClick the phone icon in the toolbar, press Ctrl + Shift + U (macOS: Cmd + Shift + U), or choose Mobile Drop in the Command Palette
  2. Scan the QR code with the phone cameraThe phone must be on the same Wi-Fi (the same LAN) as the PC. The address is also shown as text under the code, so you can type it in
  3. Fill the send trayAdd photos or files (up to 10 items, 60 MB total), a voice note and text, in any combination
  4. Press "Send all"There is only one button. An upload progress indicator shows while it sends
  5. It is appended to the noteThe dialog closes and the content is appended to the end of the active note. Each item gets its own heading: ## Mobile Drop [14:20:05] — <filename>

The page that opens on the phone

The top of the Mobile Drop page on the phone: the Text from PC card, a send tray with two items, and buttons to take a photo, choose files and record voice
The top of the page on the phone (every label shows Japanese and English together)
  1. Text from PC The text selected on the PC. Tap the button below it to copy it on the phone
  2. Send tray Everything you have added so far (a photo and a note file here). ✕ removes an item
  3. Take a photo Takes a photo with the phone camera
  4. Choose files Pick photos or text files from the phone (several at once)
  5. Record voice Opens the phone's own recorder. The recording is added to the tray and transcribed on the PC
The bottom of the Mobile Drop page on the phone: the text or URL box and the Send all button
The same page scrolled to the bottom
  1. Text or URL box Paste a note or a link to send it as text
  2. Send all Sends the tray and the text to the active note on the PC in one go (one submission per session)
On the phone What ends up in the note
Photos / files Photos are transcribed to Markdown by the vision model. .md and .txt are added as they are; .html, .js, .json, .py and other code or config files are wrapped in a fenced code block. Shift_JIS text files are converted automatically.
Voice note Transcribed the same way as Voice Input and added as text.
Text or URL The text exactly as typed or pasted. A lone URL becomes a Markdown link.

Where photos and voice notes go

API set up
  • Photos: The same vision model as Ctrl + V image OCR (Settings → AI Models → Image OCR (Vision)) transcribes them to Markdown. The photo itself is not saved
  • Voice notes: Transcribed the same way as Voice Input (the same Gemini model) and added as text
  • A local (Ollama or LM Studio) vision model does OCR even without a key
Not set up, or it fails
  • Whether the key is missing, the model is not supported, the transcript is empty, or there is an HTTP error or a timeout, the photo or voice note is not lost
  • It is saved to ./assets/ just like an image pasted with Ctrl + Shift + V, and the note gets a link plus a one-line reason
  • A toast tells you how many items were handled this way
Limits and details (the lines added when an item is saved, and where)

When an item is saved, one of these lines goes into the note, depending on the situation. These inserted lines are Japanese in both UI languages.

Situation Photo Voice note
Nothing is configured ![name](./assets/...) and > 画像OCRをスキップし、画像として保存しました: <error> (設定 → AIモデル → 画像解析) [name](./assets/...) and > 文字起こしをスキップし、音声として保存しました: <error> (設定 → AIモデル → 音声入力)
Any other failure > 画像OCRに失敗したため、画像として保存しました: <error> > 文字起こしに失敗したため、音声として保存しました: <error>
  • Where it is saved: ./assets/YYYY-MM-DD-HHmmss.<extension>, next to the note. If there is no saved note, the workspace folder; if that is missing too, the app data folder (then the link is a file:// link). A name collision appends -2, -3.
  • If saving fails too: Only when saving to assets fails as well, [Mobile Drop: <filename> の処理に失敗しました: <error>] is appended after that item's heading. The remaining items arrive normally.
Limits and details (what you can send, and size limits)
  • Up to 10 photos or files, 60 MB in total.
  • Per-item limits: an image 20 MB, an audio file 25 MB, a text file 2 MB. Any other binary file is refused.
Limits and details (the phone page and "Text from PC")
  • Page layout: From top to bottom: the "Text from PC" card, the "Send tray" (each added item shows its name, size and a to remove it), camera / file picker (several files) / voice recording, and the text box. There is only one send button.
  • "Text from PC": The text selected on the PC (or the clipboard text, if nothing was selected when the dialog opened) is shown with a one-tap copy button. It refreshes every 2 seconds and shows up to 64 KB.
  • On the PC: The dialog shows it as "Sharing with phone: ...", truncated to 80 characters.

Choose a connection

Same Wi-Fi (LAN) Default
  • The phone and the PC must be on the same network
  • Nothing leaves that network
  • For voice notes, the phone's own recorder app opens
  • Location is neither requested nor attached
Via Cloudflare (mobile data, another Wi-Fi)
  • Press "Connect from outside via Cloudflare (mobile data / other Wi-Fi)" in the dialog
  • It opens an account-free Cloudflare Quick Tunnel, and the QR code switches to a temporary https://…trycloudflare.com address
  • For voice notes, you can record right in the page (HTTPS)
  • Location can optionally be attached, once
  • The transferred data passes through Cloudflare's servers
Limits and details (the Cloudflare tunnel)
  • It needs cloudflared. MD-Memo never downloads or installs it for you.
  • If it is missing, the dialog shows the install command (Windows: winget install --id Cloudflare.cloudflared -e, macOS: brew install cloudflared) with a Copy button. Run it, then press the button again.
  • While the tunnel is up, the transferred data passes through Cloudflare's servers.
  • About the 90 seconds: The tunnel's 90 seconds is an idle timeout. Activity on the phone re-arms it. It is not a fixed "valid for 90 seconds after it is issued" limit.
Limits and details (safety and limits)
  • It exists only while the dialog is open. Opening it starts a small server on the PC. It stops after one submission, after 60 seconds without activity, or when you close or cancel the dialog. Opening the page on the phone, and any work on the phone (adding a file, recording, typing), all count as activity and reset that timer. So even a large batch does not trip the 60-second idle timeout.
  • One submission per QR code. To send more, open the dialog again. The one-time token is checked before the request body is even read.
  • Only someone with the code can send. The address contains a random one-time token, and a request without it is refused before anything is read.
  • Photos and cloud models. If your vision model is a cloud service such as Gemini, photos are sent to that provider, exactly as when you paste an image with Ctrl + V. Even with no API key, the photo is not lost: it is saved as an image (see "Not set up, or it fails" above).
  • Location is opt-in and tunnel-only. Only when connected through the Cloudflare tunnel (HTTPS), the phone may attach its location once, as a single one-time attempt. Only the first item's heading carries it: ## Mobile Drop [14:20:05] — <filename> (34.693, 135.502). Over plain LAN HTTP, location is never requested or attached.
Limits and details (how sending survives interruptions)

On a plain LAN connection, recording a voice note opens the phone's own recorder app. To keep the session alive meanwhile, the phone page works as follows.

  • Just before handing over to the camera, the file picker or the recorder app, it asks the PC to keep the session open up to 120 seconds longer. The PC session normally ends after 60 seconds without activity, and the server caps such a request at 180 seconds.
  • When you come back to the page, it pings the PC.
  • A picked file is copied into memory right away, because recorder apps may still be writing to it or may revoke access.
  • While files are being read, the Send button waits.
  • If sending fails, the page checks whether the PC session is still alive. If it is, the page resends once automatically, and if that fails too it shows "network error - please try again".
  • If the PC session has ended, it shows "the connection to the PC is gone (closed or timed out) - reopen Mobile Drop on the PC and scan the QR code again".
  • Recording directly in the page, without opening a recorder app, needs the HTTPS Cloudflare tunnel.
If the page will not open on the phone
  • Check that both devices are on the same Wi-Fi. Guest networks and some routers stop devices from talking to each other ("AP isolation"). A VPN on the PC or the phone can also get in the way.
  • On Windows you may see a firewall prompt for MD-Memo the first time. Allow it on private networks.
  • The QR code uses the address of the network adapter that carries your default route (virtual adapters such as WSL or Docker are skipped). If your phone is not on that network, use the Cloudflare connection above.

The toolbar icon can be hidden or moved under Settings → General → Toolbar & right-click menu. The shortcut and the Command Palette entry work either way.

Command Palette (Ctrl+Shift+P)

In one line: Search and run MD-Memo's commands and the notes in the folder you opened, using only the keyboard. Ctrl + Shift + P No setup needed
The command palette opened with Ctrl+Shift+P, listing New Note, Open File, Open Notes Folder, Ask AI and the Command Bar entries
Ctrl + Shift + P: the command palette
  1. Input field Type to filter commands and notes
  2. Highlighted command Press Enter to run it
  3. Description and shortcut Each command shows a one-line description and its assigned key
  1. Open the paletteCtrl + Shift + P (macOS: Cmd + Shift + P)
  2. Type to filterType part of a command name or a note title (substring match)
  3. Choose and runA command runs, and a note opens
Limits and details
  • It searches the commands and the notes in the workspace folder you have opened.
  • The AI and command entries are "Ask AI", "Command Bar" (opens in the mode you used last), "Command Bar: Run a Command" and "Command Bar: AI Writes the Command". The last two have no key by default.
  • "Insert task snippet" opens the list of ready-made LLM, agent and command tasks at the caret. Insert one, then press Ctrl + Enter to run it (see Auto Selector).
  • Matching is a plain substring match, not a fuzzy search.
  • Settings are not searchable. Open the settings screen with Ctrl + , (macOS: Cmd + ,).

03 Settings Reference

In one line: The settings screen has five tabs: General, AI Models, Agent, Sync and Shortcuts. Open it with the slider icon in the header, or with "Settings..." in the right-click menu.
The General tab of the settings screen
Settings: the General tab (theme, window and editor behavior)
  1. Theme The accent color scheme
  2. Language The interface language: English or Japanese
  3. Startup and window Restore tabs and unsaved notes, start in split view, stay in the tray
  4. Editor and typing Autosave, IME Guardian, AI proofreading, cursor light
  5. Toolbar and right-click menu Choose the items shown and their order (see the steps below)

1. General Tab

Setting Default Description
Accent Color Theme Dark Olive Choose between Dark Olive, VS Code Blue, Forest Teal, and Charcoal Monochrome.
Language English / Japanese Switch the UI language.
Restore Open Tabs Enabled Restores unsaved buffers and previous tabs upon application launch.
2-Pane Split by Default Disabled Always launches in split view when checked.
Resident in Tray Enabled (Windows) On Windows, the close button keeps MD-Memo in the tray instead of quitting, and Ctrl+Alt+M brings it back in milliseconds. macOS has no tray: closing the window always keeps MD-Memo in the Dock, and this checkbox is disabled there with the hint "Not available on this platform yet; this setting currently has no effect."
Autosave on 1.5s Pause Enabled Silently saves existing files upon a 1.5-second typing pause.
IME Guardian Enabled only if the system language is Japanese (Disabled by default on macOS) Protects code blocks against IME full-width character leakage. On macOS the OS input source cannot be switched automatically yet, so it starts off there and Settings shows a hint saying so.
Enable AI typo & error correction (Alt+C) Enabled Turns the Alt + C proofreading command on or off.
Subtle cursor light on idle Enabled Shows a soft glow around the caret when typing stops.
Toolbar & right-click menu Everything shown Show, hide and reorder the toolbar icons and right-click menu items. See "Adjusting the toolbar and right-click menu" below for the steps.

Adjusting the toolbar and right-click menu

  1. Open the sectionIn Settings → General, open "Toolbar & right-click menu" ("Choose the items shown and their order")
  2. Choose what to showTick the toolbar icons and right-click items you want. Use the arrows to reorder them within their group
  3. Changes apply at once"Cancel" undoes them. "Reset to default" restores the original layout
The General tab of the settings screen with the Toolbar and right-click menu section opened
The Toolbar & right-click menu section opened
  1. Section title Choose the items shown and their order
  2. Checkboxes Tick to show, clear to hide (only the Settings icon always stays)
  3. Up and down arrows Move an item within its group
The right-click menu opened on a selected line
The menu you get by right-clicking a selected line
  1. Editing commands Undo, redo, cut, copy, paste, select all
  2. Navigation Find, replace, go to line, command palette, open folder
  3. AI and command bar Ask AI, proofread, Command Bar, voice input
  4. View Preview and open to the side. Which items are shown can be changed in Settings
  • The Settings icon can be reordered but not hidden (it always stays, so you can get back to the settings screen).
  • Items you hide can still be used with their shortcuts and from the command palette.

The Export... and Import... buttons at the bottom of the Settings dialog carry your settings, agent definitions and skills to another PC in one package (.mdmemopack). Details: 6. Export and Import Settings (Packages).

2. AI Models Tab

In one line: From a fully offline local LLM to the latest cloud APIs, you can choose a model for each feature.
The AI Models tab of the settings screen, scrolled to the Voice input group
Settings: the AI Models tab (scrolled to the Voice input group)
  1. Voice model The model used for transcription
  2. API style "Auto" picks the API from the model name, or you can force one
  3. Language codes Comma-separated. Empty means auto-detect
  4. Mode Smart tidies the text, and Verbatim keeps every word
  5. Custom vocabulary Names and jargon, one per line
  6. Silence timeout How many seconds of silence stop the recording automatically
  • Feature → Which model setting it uses: the card at the top of the tab, showing which setting each feature reads. For example, Write (Ask AI) and Chat use the Text LLM, Ghost Text and Image OCR have their own settings, and Suggestions (Quick Actions) are configured on the Agent tab.
  • Local AI (Ollama): a status badge with Start and Stop buttons for Ollama, plus Install Gemma 4, which installs Ollama if it is missing and pulls the gemma4:e2b model.
  • Text LLM & AI CLI (Chat, Writing & CLI Agent): Base URL, model name, API key, and System Prompt. The protocol is detected from the URL and shown beneath it: Ollama, Gemini-compatible, or OpenAI-compatible.
  • Inline Autocomplete (Ghost Text): its own URL, model, and key, plus the suggestion delay (default 500 ms; the settings screen allows 200–2000, but the effective minimum is 300 ms) and the maximum prediction tokens (default 30, range 10–100).
  • Image OCR (Vision): the vision model and key, such as Gemini Flash Lite or Qwen 2.5 VL, plus a toggle "Automatically transcribe pasted images (Ctrl+V) using Gemini OCR" (on by default).
  • Image Generation (Mermaid & Infographics): the model, aspect ratio, and resolution used by "Render Image...". If its Gemini API key is blank, it inherits the Vision key and then the Text key, in that order.
  • Voice input: Right below the Image OCR (Vision) settings. For how to use it, see Voice Input. The settings are listed in the table below.

Voice input settings

Setting Config file key Default Description
Voice model voice.model gemini-3.5-transcribe Suggestions: gemini-3.5-transcribe, gemini-2.5-flash, gemini-flash-lite-latest. gemini-3.5-transcribe-live (the streaming variant) cannot be used for recorded audio, and choosing it causes an error.
API style voice.apiStyle Auto (auto) Auto / Interactions API / generateContent. Auto uses the Interactions API when the model name contains "transcribe", and generateContent otherwise.
Language codes voice.languageCodes Empty Comma-separated BCP-47 codes (for example ja-JP, en-US). Empty means auto-detect, which also handles mixed languages. Used only with the Interactions API.
Mode voice.mode Smart (smart) Smart removes fillers and formats the text for reading. Verbatim (verbatim) transcribes word for word. Used only with the Interactions API.
Custom vocabulary voice.customVocabulary Empty One term per line (names, jargon). Up to 1000 terms, but about 100 works best. Used only with the Interactions API.
Silence timeout (s) voice.silence_timeout_sec 5 1–30. Recording stops by itself after this many seconds of silence.
Transcription prompt voice.prompt Built-in instruction Used only by generateContent-style models.
API key / Base URL voice.apiKey / voice.baseUrl Empty If empty, the Image OCR (Vision) key and Base URL are used. The settings screen has no separate fields for them, so a separate key is possible only by writing it in the config file directly.

3. Agent & CLI Tab

In one line: Following the three verbs, this tab has four groups: "Commands (Run)", "Agents (Delegate)", "Auto selector (Ctrl+Enter)" and "Suggestions (Quick Actions)".
The Agent tab of the settings screen, with command, agent and suggestion settings
Settings: the Agent tab (scrolled to the Agents (Delegate) settings)
  1. Open agents.yaml Opens the file that defines agents and notations
  2. Agent The default agent, with a badge that shows whether its command is installed
  3. Agent timeout Seconds before a run is cut off
  4. Change highlight duration (Ghost Diff) In milliseconds
  5. Live output preview (Hover Peek) Shows the agent's latest output in the task panel

Commands (Run): settings for the command bar.

  • CLI Model Name: the model that writes commands in the Command Bar's AI mode (Ctrl+E, then Tab). Leave it blank to inherit the AI Models tab.
  • Open CLI execution results in a new tab: When on (the default), the command's output replaces the selection and the result also opens in a new tab. When off, no new tab opens, and with no selection the whole note is replaced by the output.
  • Max Stdin Pipe Size (MB): Changing this has no effect. The limit for cat log | md-memo is fixed at 10 MB, to keep a huge file from spiking memory.

Agents (Delegate): settings for the agents your slots call.

  • Open agents.yaml: opens the file that defines notations, agents (with their aliases), recipes and your own snippets. A commented template is generated if none exists yet; it explains @name, aliases and snippets.
  • Agent: the default agent used when a notation does not name one. The Auto selector also uses it when a line looks like a job for an agent. The list is built from the agents.yaml currently loaded.
  • Agent timeout (seconds): how long a run may take before it is cut off (default 180 s, range 10–600 s). If an agents.yaml already exists (even one created by "Open agents.yaml"), the file's value wins and this field is not used.
  • Ghost Diff highlight time: how long the amber line shows on the left edge of the editor right after a result lands (default 4000 ms, range 1000–10000). You can undo with Esc during that time and for 1 second after it. The settings screen labels it "Change highlight duration (ms) (Ghost Diff)".
  • Hover Peek: shows the agent's latest output line in the task panel.

Auto selector (Ctrl+Enter): settings for the Auto selector. This group sits between "Agents (Delegate)" and "Suggestions (Quick Actions)".

The Agent tab of the settings screen scrolled to the Auto selector (Ctrl+Enter) group, with its two checkboxes
Settings: the Agent tab, scrolled to the Auto selector group
  1. Auto selector group Between Agents (Delegate) and Suggestions (Quick Actions)
  2. Let Ctrl+Enter decide On by default. When off, Ctrl+Enter only runs {{ }} slots, as before
  3. Confirm before an auto-detected agent or command runs On by default. The line is rewritten first, and a second Ctrl+Enter runs it
  • Let Ctrl+Enter decide: ask the AI, hand over to an agent, or run a command: on by default (config key autoSelector.enabled). When off, Ctrl+Enter only runs {{ }} slots, as before. A task you wrote yourself ([[ @llm ... ]], [[ $ ... ]], {{ @agent ... }}) still runs with Ctrl+Enter; only the guessing stops.
  • Confirm before an auto-detected agent or command runs: on by default (autoSelector.agentConfirm). The line is rewritten first; press Ctrl+Enter again to run it (Ctrl+Z undoes the rewrite). When off, an agent or a command runs right after the rewrite. An AI instruction always runs at once.
  • Both settings travel with the "Agent & Quick Actions" section of a settings package. A config that has no such group gets the defaults (both on).

Suggestions (Quick Actions): settings for Quick Actions (Ctrl+J).

  • Suggest actions automatically while typing: whether cards appear on their own after a pause.
  • Manual trigger only (suppress auto-popup, press Ctrl+J): turn off automatic suggestions and show cards only when you press Ctrl+J.
  • Quick Actions delay (seconds): how long a pause has to be before cards appear.
  • API Base URL / Model Name / API Key: the endpoint used to generate candidates. Leave the API Key empty and the Base URL at its default (https://openrouter.ai/api/v1, model jev-latest) to use the built-in local inference; nothing is sent until you enter a key or change the URL.

4. Sync Tab (Git & Scraps)

In one line: Set the folder where daily scraps are saved, and background auto-sync to GitHub.
The Sync tab of the settings screen, with the scraps folder and Git settings
Settings: the Sync tab (scraps folder and Git)
  1. Daily scraps folder The folder where scraps are saved
  2. Background Git sync Switch it on or off
  3. Git remote URL The URL of the scraps repository
  4. Link / Init Connects the folder to the remote
  5. Repository status badge Shows the current Git state
  • Daily Scraps Folder: Path where cat file | md-memo and daily notes reside. Use Browse... to pick it. Can point directly to an Obsidian vault or a Dropbox folder.
  • Enable background Git sync: Runs git pull --rebase on launch, then runs git add/commit/push in the background once you stop editing. It works when the scraps folder is a Git repository. A remote is not required, but without one the push fails.
  • Git Auto-Push Debounce (seconds): How long to wait after the last edit before pushing (default 30, range 5–3600).
  • Remote Branch: The branch to sync with (default main).
  • Git Remote URL, Test Connection, and Link / Init: Enter the URL of an empty GitHub repository (https://github.com/user/scraps.git), click Test Connection to check access, then click Link / Init. It runs git init if needed, sets origin, makes an initial commit, and pushes with push -u.
Caution: everything in the scraps folder gets committed

Git sync runs git add ., commit and push in the scraps folder. An .env or .md-memo/agents.yaml kept there is committed too, so do not keep secrets in that folder.

5. Shortcut Cheatsheet

In one line: You can reassign most keys in Settings → Shortcuts. Click a row's key button and press the new combination.
Action Windows macOS
Global Summon (bring to front; it does not hide the window) Ctrl + Alt + M Option + Cmd + M
High-Speed Scrap Search Ctrl + Shift + F Cmd + Shift + F
Command Palette Ctrl + Shift + P Cmd + Shift + P
Ask AI Ctrl + L Cmd + L
AI Proofreading & Correction Alt + C Cmd + Shift + C
Suggest Quick Actions Ctrl + J Cmd + J
Command Bar (opens in the mode you used last) Ctrl + E Cmd + E
Mobile Drop (send from your phone via QR) Ctrl + Shift + U Cmd + Shift + U
Auto selector / run a slot (fixed key) Ctrl + Enter Cmd + Enter
Toggle Task Panel Alt + T Option + T
Split Editor Right Ctrl + \ Cmd + \
Preview to the Side Ctrl + Alt + V Cmd + Option + V
Special Paste (rich HTML → Markdown) Ctrl + Shift + V Cmd + Shift + V
Voice Input Ctrl + Shift + R Cmd + Shift + R
Open Link Ctrl + Click Cmd + Click
Reveal Link (Explorer / Finder) Alt + Click Option + Click
Zen Mode Shift + F11 Ctrl + Cmd + Z
Accept Ghost Text (Word) Ctrl + → Option + →
Insert Date / Time F5 Cmd + Shift + I

The keys "Command Bar: CLI mode" and "Command Bar: AI mode" have no default key, and you can assign them here. Ctrl + K is not used by default either, so it is free to assign.

Reassigning a shortcut (Settings → Shortcuts)

  1. AssignClick the key button for a row, then press the combination you want. While it records, the hint reads "Press keys to set · Backspace to clear · Esc to cancel"
  2. If it is already usedA confirmation appears: "Already assigned to "<action>". Overwrite?" Choose "OK" (Enter) to move it (the other action becomes "Not Set"). "Cancel" or Esc changes nothing
  3. To leave it unassignedWhile recording, press Backspace (or Delete) and the action becomes "Not Set" and does nothing. Esc cancels the recording. "Reset to Defaults" restores every default key

When checking for duplicates, Ctrl and Cmd are treated as the same key.

The Shortcuts tab of the settings screen, with the Ask AI row waiting for a new key
Settings: the Shortcuts tab. One row is waiting for a new key
  1. Hint line Press the new keys. Backspace clears and Esc cancels
  2. Row being recorded The button shows "Press key..." until you press a key combination
  3. Reset to Defaults Puts every key back to its default
The overwrite confirmation dialog: Already assigned to "Suggest Quick Actions". Overwrite?
The overwrite confirmation when the recorded key is already assigned
  1. Confirmation message It names the action that already uses the key, here "Suggest Quick Actions", and asks whether to overwrite it
  2. OK / Cancel "OK" (Enter) overwrites, and "Cancel" (Esc) keeps the current assignment
  3. The action being reassigned Here, Ask AI. This row's button was in the recording state

Reserved keys that cannot be assigned

The app uses the combinations below itself. If you try to assign one, you get the message "<combo>" is reserved by the app and can't be assigned.

Platform Keys that cannot be assigned
Windows / Linux Ctrl + Tab Ctrl + , F11 Ctrl + Shift + V (special paste) Ctrl + Alt + V (preview to the side) Alt + T (task panel) Ctrl + → (accept a ghost-text word) Ctrl + Enter (also with Shift or Alt added; the Auto selector and slots) Ctrl + C Ctrl + V Ctrl + X Ctrl + A Ctrl + Z Ctrl + Shift + Z (redo) Ctrl + Y
macOS Ctrl + Tab Cmd + , Cmd + Q Cmd + H Cmd + Option + H Cmd + M Cmd + Z Cmd + Shift + Z Cmd + X Cmd + C Cmd + V Cmd + A Cmd + Tab Cmd + Space Cmd + Shift + V Cmd + Option + V Option + T Cmd + → Cmd + Enter (also with Shift or Option added)

Other fixed keys that are not in the settings list

  • Ctrl + Enter: The Auto selector's key (see Auto Selector). It runs the task or slot under the caret, or does what the current line asks for. Variants with Shift or Alt added are treated the same way. That is why the default for "Insert Line Below" is Shift + Enter (Shift + Alt + Enter for "Insert Line Above").
  • Ctrl + Click / Alt + Click: Open a link / show the link's location.
  • Esc: Discards a voice recording.
  • Special paste (Ctrl + Shift + V) is fixed and cannot be changed. The voice input key can be changed.

On macOS, use the corresponding keys from the table above.

6. Export and Import Settings (Packages)

In one line: Put your settings, agent definitions and skills into one .mdmemopack file and carry it to another PC. Use Export... and Import... at the bottom of the Settings dialog. API keys are left out at first

Export (Settings → Export...)

The top of the Export package dialog: a format list and one checkbox per settings section, with Sync marked this PC only
The top of "Export package": choose the format and the settings sections
  1. Format A package (.mdmemopack), or a plain JSON file with the settings only
  2. Settings Tick one box per section; All and None (top right) switch them all at once
  3. Sync Marked "this PC only" and unticked at first, because the scrap folder path and similar values differ from PC to PC
The same dialog scrolled to the bottom: the two agent definition files, project skills grouped by folder, the unticked Include API keys option and the Export button
The same dialog scrolled to the bottom: agent definitions, skills and options
  1. Agent definitions The app-wide and the project agents file, with their paths; ticked at first
  2. Skills Only the skills of the current project, grouped by folder; none are ticked at first
  3. Include API keys Off at first; if you turn it on, anyone who gets the file can use your keys
  4. Export Asks where to save the package
  1. Click "Export..."At the bottom left of the Settings dialog; "Export package" opens
  2. Choose what goes inTick settings sections, agent definitions and skills; Sync and the skills start unticked
  3. Leave "Include API keys" offSo the file you hand over carries no keys; turn it on only to move to your own other PC
  4. Click "Export"Pick where to save; md-memo-YYYYMMDD.mdmemopack is written and a summary is shown

Import (Settings → Import...)

The top of the Import package dialog: the package file name and date, the note that API keys are not included, and the settings sections
The contents of the chosen package (top part): choose what to import
  1. The package File name, creation date and the MD-Memo version that wrote it
  2. API key notice "API keys are not included" means your current keys stay as they are; a package with keys shows a warning instead
  3. Settings Only the sections the package holds; tick what you want to apply
The same dialog scrolled to the bottom: will-overwrite badges on an agents file and on skills, the warning about skills and the backup note
The same dialog scrolled to the bottom: look for the "will overwrite" badges
  1. Will overwrite Something with the same name already exists and will be replaced (it is backed up first)
  2. Skills warning Skills are instructions an agent will follow; import only skills from sources you trust
  3. Backup note Agent definitions and skills that would be overwritten are backed up first
  4. Import Applies only what is ticked
  1. Click "Import..." and pick the fileA .mdmemopack; an older settings JSON file works too
  2. Check the contentsItems marked "will overwrite" replace what you have; if the package's API key fields are empty, your current keys are kept
  3. Tick what to importUntick agent definitions and skills from anyone you do not trust
  4. Click "Import"Settings apply at once (some need a restart); agent definitions and skills are used from the next agent run
Included
  • Settings: General, AI Models, Agent & Quick Actions, Shortcuts, Sync, Other (chosen per section; the Auto selector settings are part of Agent & Quick Actions)
  • Agent definitions: the app-wide and the project agents.yaml
  • Skills: those in the current project's skills, .claude/skills, .gemini/skills and .codex/skills
Not included
  • API keys: only when you tick "Include API keys"
  • .env files: the project's .env is never packaged
  • Global skills: skills in your home folder cannot be chosen
  • Your notes: a package holds only settings, agent definitions and skills
Limits and details (secrets, backups, size limits, what "project" means)

API keys and other secrets

  • With "Include API keys" off, the value of every setting whose name contains apikey, api_key, api-key, token, secret, password or passwd is emptied. A Git remote URL loses its user:password@ part.
  • In agent definitions, values of the same kind under env: are emptied (comments and layout are kept). If that cannot be done safely, the file is included unchanged and a notice says it may still contain secrets; check before you share it.
  • The number of emptied values is shown on the export result screen.

After you import

  • Settings are merged into the running app and saved on the spot; theme, language, toolbar and shortcuts switch at once. Sections you did not tick stay as they are.
  • Agent definitions and skills are written by MD-Memo itself. A package cannot be imported by editing config.json by hand, because the running app owns that file.
  • Targets: the app-wide agent definitions go to %APPDATA%\md-memo\agents.yaml (macOS: ~/Library/Application Support/md-memo/agents.yaml), the project's to <project>/.md-memo/agents.yaml, skills to <project>/<folder>/<name>. An agents file that does not parse is skipped with a reason.
  • Whatever would be overwritten is first copied to %APPDATA%\md-memo\pack_backups\<date-time>\ (macOS: ~/Library/Application Support/md-memo/pack_backups/). That folder is outside the project, so skill folders stay clean. The result screen shows the location.
  • An older settings JSON (one file with all settings) can be imported too; it covers settings only and may contain API keys. Choosing "JSON (settings only)" as the export format writes the same kind of file.
  • Some settings take effect after you restart MD-Memo; the result screen says so.

What "project" means

Starting from the folder of the open note (for an unsaved note: the opened folder, else the scraps folder), MD-Memo walks up to the first folder that contains .md-memo, agents.yaml, AGENTS.md, skills or .git. The home folder is never treated as a project (so global skills are never carried away). If no project is found, project items show "needs a project" and cannot be ticked.

Limits and safety

  • A package can be up to 50 MB and 3000 files; one file up to 10 MB, 100 MB in total after unpacking. Settings are limited to 2 MB and one agents file to 1 MB. A skill over the limits is left out of the export with a notice.
  • Not packaged from skill folders: .env and .env.* files (templates such as .env.example are included), .git, node_modules and __pycache__ folders, and symbolic links.
  • Refused on import: unsafe paths (.., absolute paths, drive letters and the like), encrypted or damaged files, and packages from a newer version. Files not listed in the manifest are ignored.
  • Skills are instructions an agent will follow, and agent definitions contain commands MD-Memo will run. Import only from sources you trust.

04 Power User & Hackers Manual

In one line: MD-Memo is a hackable tool for engineers. Over local TCP IPC (JSON-RPC 2.0) and CLI subcommands, you can control it fully from shell scripts and other editors.

UNIX Terminal Pipe

In one line: Pipe a terminal's output into | md-memo and it is appended to the end of today's scrap. No setup needed

It reaches the running instance in milliseconds and is appended to the end of today's scrap (scraps/YYYY-MM-DD.md) with a timestamp and the command name. The window comes to the front automatically.

# Pipe a command's output straight into your notes
cat build.log | md-memo

# Record a curl result directly in your notes
curl -s https://api.github.com/zen | md-memo

The pipe input limit is fixed at 10 MB.

JSON-RPC 2.0 API Specification

In one line: From any language, open a TCP socket to 127.0.0.1 and send newline-delimited JSON-RPC 2.0 requests to control MD-Memo.
  1. Read the connection detailsStartup writes ipc-session.json (Windows: %AppData%\md-memo\, macOS: ~/Library/Application Support/md-memo/). It holds {pid, port, token, started_at}
  2. Open the socketPort 49152 is preferred, but if it is busy a random free port is used instead. Always read the port from this file
  3. Send requestsSend newline-delimited JSON-RPC 2.0 requests
Method Params Description
buffer.get {"tab_id": "..."} Retrieve the content, hash (first 16 hex characters of the SHA-256), generation index, and line count. Omit tab_id for the active tab. Only buffer.get, buffer.get_selection and buffer.replace_selection accept tab_id.
buffer.set {"content": "...", "expected_hash": "...", "expected_generation": 12} Replace the whole buffer. Supports optimistic locking (a conflict error if expected_hash or expected_generation does not match the current value) and preserves the undo history. It always acts on the active tab of the primary pane, and tab_id is ignored.
buffer.append {"content": "\n- [ ] New Task"} Append text to the end of the current buffer. Always acts on the active tab of the primary pane.
buffer.replace {"start_line": 1, "start_col": 1, "end_line": 2, "end_col": 1, "content": "...", "expected_hash": "..."} Replace only the given line and column range. Add expected_hash to detect conflicts (expected_generation is accepted but not checked here). Always acts on the active tab of the primary pane.
buffer.get_selection {"tab_id": "..."} Get the selected text and its start and end positions (UTF-16 offsets). If nothing is selected, it returns error -32003 (no active selection).
buffer.replace_selection {"content": "...", "tab_id": "..."} Replace the selection (as a single undo step). The selection is read again to check it, so if it changed after you read it you get conflict error -32001, and if nothing is selected you get -32003.
tab.list {} List all open tabs and which one is active.
tab.switch {"tab_id": "tab_123"} Switch focus to the given tab.
ui.toggle_split {} Toggle 2-pane split mode.
ui.activate {} Bring window to the foreground.
ui.eval {"expression": "document.title"} Run an arbitrary JavaScript expression inside the app's WebView and return the result.
Caution: local access is not authenticated

The token in the session file is optional: a request is rejected only if it sends a wrong token (in an auth field). The server listens on 127.0.0.1 only, but any program on your computer can call these methods, including ui.eval, which runs JavaScript inside the app. Treat the port as open to every local program.

Headless CLI Commands

In one line: Control MD-Memo from the command line: read and write notes, switch tabs, and check a command's safety, all from shell scripts.
Needs a running MD-Memo
  • buffer: get, set, append, replace, replace-selection
  • tab: list, switch <id>
  • ui: activate, toggle-split, eval <expr>
Runs standalone
  • jev (such as verify)
  • agent (prune)
  • When output is redirected or piped, it is JSON unless you pass --text. To save plain text, use md-memo buffer get --text > note.md.
  • --json works on every buffer subcommand.
  • --tab <id> is honored only by buffer get, buffer get --selection and buffer replace-selection. set, append and replace always act on the active tab of the primary pane.
# 1. Print the current buffer (plain text in a terminal; JSON if redirected)
md-memo buffer get

# 2. Print it as JSON with metadata (hash, generation, length, line count, ...)
md-memo buffer get --json

# 3. Replace the buffer with text from the terminal stream
echo "# Updated note" | md-memo buffer set

# 4. Replace it only if it has not changed since you read it (optimistic lock)
echo "Safe update" | md-memo buffer set --expected-hash a1b2c3d4e5f60718

# 5. Append to the end of the buffer
echo "- [ ] New task" | md-memo buffer append

# 6. Replace one range (line:column, both 1-based)
echo "replacement" | md-memo buffer replace --start 2:1 --end 2:10

# 7. Print only the current selection; exits 1 with "no active selection" on stderr if none
md-memo buffer get --selection
md-memo buffer get --selection --json
#   -> {"text": "...", "start": 12, "end": 48}
md-memo buffer get --selection --tab tab_2

# 8. Replace the selection with piped text, as one undo step
#    (refuses with a conflict error if the selection changed since it was read)
cat formatted.txt | md-memo buffer replace-selection

# 9. Check a shell command against the AST guardrail (exit code 0 = safe)
md-memo jev verify "git status && npm test"
# [SAFE] Command passed AST validation: git status && npm test

# 10. A blocked command exits with code 1; --json prints the verdict as JSON
md-memo jev verify --json "rm -rf /"
# {
#   "isSafe": false,
#   "reason": "破壊的コマンド \"rm\" は安全基準により実行を拒否されました (Destructive command blocked)",
#   "command": "rm -rf /",
#   "rule": "destructive",
#   "subject": "rm"
# }

# 11. Choose how strictly the guard judges: strict (default, for one-click paths
#     nobody reviews), reviewed (a person confirms before running), or unattended (hooks)
md-memo jev verify --mode strict "sudo rm -rf /"
# -> blocked (exit code 1), in every mode
md-memo jev verify --mode reviewed "git status"
# -> safe (exit code 0)

# 12. Prune a Markdown file down to what is relevant to a query
md-memo agent prune --query "login bug" --file notes.md
Limits and details (jev verify exit codes and modes)
  • jev verify [--mode strict|reviewed|unattended] <cmd> runs the same deterministic, always-on AST analysis that the GUI's run gate uses. It runs entirely locally, and nothing leaves your machine.
  • Exit codes: 0 safe, 1 blocked, 2 warning (not known to be destructive, but the guard cannot vouch for it).
  • Modes: The mode does not change the rules, only how seriously a finding is weighed, because who is watching differs. strict (the default) is for one-click paths where nobody reviews the command before it runs, reviewed assumes a person confirms before running, and unattended is for hooks.
  • A command such as sudo rm -rf / is reported as blocked in every mode.

Let an AI agent configure MD-Memo

In one line: An AI agent such as Claude Code can set up API keys, models, agents.yaml and environment variables for you. Just paste one of the requests below. Agent CLI needed separately
YouQuit MD-Memo and back up the files
Ask the agentHand over a request from below
Edit the config filesEdit, then validate the syntax
Restart MD-MemoYou start it as usual
Check each featureTest each feature and report

Which file, who edits it, and when it takes effect

File Where When it takes effect Who edits it
config.json
App settings (keys, models, shortcuts and more)
Windows: %APPDATA%\md-memo\
macOS: ~/Library/Application Support/md-memo/
When you restart MD-Memo. It is read at startup, and the whole file is rewritten every time you save in the settings screen The agent, only while MD-Memo is fully closed
agents.yaml
Agent, alias, notation and snippet definitions
Per project: <scraps folder>/.md-memo/agents.yaml
or the app's settings folder
On the next slot run. If it has a syntax error, MD-Memo silently falls back to the defaults The agent, or you (even while MD-Memo is running)
Project .env
For agent CLI keys
The project root (see Delegate: agents) Every time a slot runs. It is the only env file read when an agent runs The agent
Environment variables The OS user environment variables For processes started after you set them (see the fold-out below) The agent (when you ask for it in the request)

To move a working setup to another PC, do not ask the agent to copy files; use a settings package (Export and Import Settings) instead.

  1. Quit MD-Memo completely and back up the filesOn Windows, quit from the tray icon (closing with ✕ leaves it in the tray). On macOS, press Cmd+Q. The backup will contain API keys, so keep it inside the settings folder
  2. Give the agent a request from belowTell it to read skills/md-memo/SKILL.md first (see the link below)
  3. The agent edits and validatesAsk it to check the JSON and YAML syntax too
  4. Start MD-MemoStart it as usual, from the Start menu, Finder or the tray
  5. The agent checks each featureAsk it to report what it could and could not confirm

Request 1: Set up Gemini in one go (image OCR, voice input, Mermaid image rendering)

Please set up MD-Memo for Gemini (image OCR, voice input, and Mermaid image rendering).
First read skills/md-memo/SKILL.md and skills/md-memo/references/setup-guide.md.
Before you edit config.json, ask me to quit MD-Memo (tray → Quit) and make a backup. Then put the Gemini key I give you only in vision.apiKey (voice and image inherit it).
For voice, set voice.model to gemini-3.5-transcribe, apiStyle to auto, and languageCodes to ["ja-JP"] (replace it with your language, or leave it empty to auto-detect). For images, set image.model to gemini-3.1-flash-lite-image.
Also check the environment and prerequisites these features need (network, microphone permission, general.pasteImageOcr and so on), and set up anything that is missing.
If something needs to be installed or an OS privacy setting needs to change, show me the command and get my permission before you run it.
Never print or commit the key.
After the restart, check each feature with a checklist, and report what you could and could not confirm.

Request 2: Add or change an agent, and put its API key in the project's .env

Please add <agent name> to MD-Memo's agents.yaml (the global one directly in the settings folder, or .md-memo/agents.yaml in the scraps folder).
First read skills/md-memo/SKILL.md and skills/md-memo/references/setup-guide.md.
Make a backup, and keep every existing agent and notation (slot_profiles / recipes).
Check the flags with <command> --help, and do not add any flag that skips permission prompts.
Put that agent's API key in the .env at the project root (KEY=value format, UTF-8 without a BOM). Do not print the key.
If Git sync is enabled for the scraps folder, add .env to .gitignore first.
Validate the YAML. If you changed notations (slot_profiles / recipes), tell me that MD-Memo must be restarted.

Request 3: Check every feature's prerequisites and set the missing environment variables and settings

Please check the prerequisites of each MD-Memo feature, and set any missing environment variables and settings.
First read skills/md-memo/SKILL.md and skills/md-memo/references/setup-guide.md. Then, one feature at a time, check every feature in the table in section (e) of setup-guide.md, "Per-feature prerequisites and verification": whether what it needs (installs, keys, environment variables, settings) is in place.
Set whatever is missing in the right place: config.json after MD-Memo is quit (backup required), agent definitions in agents.yaml, agent CLI keys in the project's .env, and everything else as OS environment variables.
MD-Memo's own LLM keys go only in config.json (environment variables such as GEMINI_API_KEY are not read by MD-Memo).
If something needs to be installed, or an OS privacy or firewall setting needs to change, show me the command and get my permission before you run it.
Never print or commit keys.
At the end, report each feature in a table as "confirmed / not confirmed / not checked".
Prerequisites per feature and how to check them (table)

The agent reads this table from section (e) of skills/md-memo/references/setup-guide.md. You can also use it to check by hand.

Feature What must exist Config key / variable How to check
Text LLM
(Ctrl+L, Alt+C, presets)
Local: Ollama and ollama pull qwen2.5:latest (or "Install Gemma 4" in Settings → AI Models). Cloud: a Gemini or OpenAI-compatible key text.baseUrl, text.model, text.apiKey (Ollama needs no key) Local: curl http://127.0.0.1:11434/api/tags returns 200 and lists the model. In the app: select a sentence, press Ctrl + L, type "translate to English" and press Enter. The translation appears below the sentence
Ghost text Same as above (a small model is recommended) autocomplete.* Type 2 or more characters and pause for 0.5 seconds: a dim suggestion appears. The status bar says "Predict: ON", and Tab accepts it
Ollama auto start and stop MD-Memo starts Ollama when a request to 127.0.0.1:11434 fails on /api/tags. If you move text and autocomplete off 11434 and save the settings, it stops Ollama (this ends all of that user's Ollama processes) None ollama list (on some installs, running the ollama command alone starts the Ollama app)
Image OCR
(Ctrl+V image, Mobile Drop photos)
A Gemini key, or a local vision model (ollama pull qwen2.5-vl:latest, and vision.baseUrl set to http://localhost:11434) vision.*, general.pasteImageOcr: true Copy only an image and press Ctrl + V. It becomes Markdown
Voice input A Gemini key (voice.apiKey, else vision.apiKey), the model gemini-3.5-transcribe, and microphone permission voice.* (no environment variable needed) Ctrl + Shift + R shows the marker. Speak, then press it again or stay quiet for a while, and it becomes text
Microphone permission WebView2 asks for permission at the first recording. On Windows, allow desktop apps in Settings → Privacy & security → Microphone. On macOS, allow it in System Settings → Microphone (macOS behavior is not yet verified) None If you see "Could not use the microphone", permission was denied or the OS blocks it. Do not delete %LOCALAPPDATA%\md-memo\webview without the user's consent
Clipboard permission The Ctrl + Shift + V fallback and Mobile Drop's "Text from PC" read the async clipboard. WebView2 may ask the first time None Copy rich HTML and press Ctrl + Shift + V. It becomes Markdown and a toast appears
Mermaid to image A Gemini key and a network connection image.apiKey (else vision.apiKey, text.apiKey), image.model, image.aspectRatio, image.resolution Put the caret in a ```mermaid block and choose "Diagram: Generate Image with Gemini" in the command palette. You get an image link (save the note first)
Mermaid from text Text LLM text.* Select text and choose "Diagram: Convert Selection to Mermaid" in the command palette
Command Bar (Ctrl+E) The tools you pipe through must be on PATH (jq, sort, tr, duckdb and so on) None Select some lines and press Ctrl + E (if the badge says "AI CLI", press Tab), type sort -u and press Enter. The command runs in the app's working directory
Command Bar AI mode (Ctrl+E, then Tab) Text LLM (or cli.*) cli.model and others Type "list files here" and press Enter: a command lands in the bar. Read it, then press Enter to run it
Slot agents Install and log in to every CLI you use (claude, codex, ollama, agy and so on). The GUI app must be able to see PATH Keys go in <project root>/.env, or in the CLI's own login Settings → Agent shows whether the selected agent is available (a PATH lookup, cached for 30 seconds). Write {{ say hello }} and press Ctrl + Enter: the result lands. The error エージェント起動失敗 (inserted in Japanese in both UI languages) means the command is not on the GUI's PATH
Auto selector
(Ctrl+Enter)
For AI tasks: the text LLM (as above). For agent tasks: an installed agent CLI (see Slot agents). Command tasks need only the command itself on PATH autoSelector.enabled, autoSelector.agentConfirm (both true by default; a config without them gets the defaults) Write a line such as "Translate the checklist above into Japanese" and press Ctrl + Enter: the line becomes [[ @llm ... ]] and the answer lands below it, in a block. Settings → Agent shows the two boxes in the "Auto selector (Ctrl+Enter)" group
Quick Actions Not needed for the local rules (an external engine is optional) action.* Press Ctrl + J in a note with text: up to 3 cards appear. An sh card runs in the app's working directory
Git sync git on PATH. An empty remote repository. Credentials that work without prompts (a credential manager or an SSH key; prompts are disabled) scraps.scrapDir, scraps.gitSyncEnabled, scraps.gitRemoteUrl, scraps.gitRemoteBranch git -C <scrapDir> remote -v, git -C <scrapDir> ls-remote --heads origin. In the app: Settings → Sync, "Test Connection", then "Link / Init". Add .env to .gitignore first
Mobile Drop (same LAN) Phone and PC on the same LAN (no AP isolation or VPN in the way). If asked, allow MD-Memo through the Windows firewall on private networks None Ctrl + Shift + U shows a QR code and http://<LAN IP>:<port>/?token=.... Photos need vision.*, and voice needs voice.*
Mobile Drop (over the internet) Install cloudflared yourself (Windows: winget install --id Cloudflare.cloudflared -e, macOS: brew install cloudflared). MD-Memo looks for it when you press the button, so no restart is needed None cloudflared --version. Press the tunnel button in the dialog: an https://...trycloudflare.com/?token=... address appears within 15 seconds. Data passes through Cloudflare, so do it only when the user asks
Global summon key None shortcuts.globalSummon Press it from another app. If it clashes with another app at startup, no error is shown. If you change it in the settings screen and the OS refuses, it reverts and a toast appears
Windows prerequisite Microsoft Edge WebView2 Runtime (MD-Memo cannot start without it) None Start the app
macOS prerequisite macOS 10.15 or later. For a build without Apple signing, the first launch needs right-click → Open, or xattr -dr com.apple.quarantine "MD-Memo.app" None By design there is no tray. Use the Dock icon and the hotkey to bring the window back
About environment variables (what is read and what is not)
  • Variables MD-Memo itself reads: TYPESAFE_API_KEY (else JEV_API_KEY), OPENROUTER_API_KEY (CLI only), JEV_MODEL, JEV_API_URL, and PATH and similar.
  • Variables it does not read: GEMINI_API_KEY, GOOGLE_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, OLLAMA_HOST. MD-Memo's own LLM features read their keys and URLs only from config.json. These variables help only the external agent CLIs that read them.
  • GUI apps do not inherit them: An app started from the Start menu or Finder does not inherit shell-profile variables. On macOS, MD-Memo repairs only PATH. For other variables, use the project's .env.
  • Saving on Windows: Save a user environment variable with setx NAME "value", fully quit MD-Memo from the tray, and start it again.
  • A good split: agent keys in <project root>/.env, MD-Memo's own keys in config.json, and OS environment variables only for additions to PATH and the Jev-related ones.
What the agent must never do
  • Show, log, paste into chat or commit API keys, config.json (and its backups), .env or session.json. Keys are masked like "set (...last 4 characters)".
  • Start a second MD-Memo or force-kill the process. You quit it from the tray.
  • Edit config.json while MD-Memo is running. Do not delete a key to "reset" it; write an explicit default.
  • Read settings with md-memo ui eval, or call window.backend.*.
  • Point the scraps folder at a repository, your home folder or a drive root. Put .env in the scraps folder without git-ignoring it.
  • Add a flag that skips permission prompts (such as --dangerously-skip-permissions) to an agent definition, or register a CLI it has not checked with --help.
  • Start a Cloudflare tunnel, install cloudflared, change OS microphone, firewall or privacy settings, or run the ollama command without your request.
  • Say "it works" without going through the checks. Anything it could not confirm should be reported as "not confirmed".

The folder to point the agent at is skills/md-memo. When you make a request, tell it to read SKILL.md first. You can also copy the folder into your agent's skills folder.

External Editor Recipes

In one line: From Neovim, PowerShell, tmux and more, you can send text to MD-Memo with a one-line command.

Neovim / Vim Send Command:

" .vimrc / init.vim
command! MDMemoSend :w !md-memo

PowerShell Clipboard Append:

Get-Clipboard | md-memo buffer append

Dump a tmux pane into your scraps:

tmux capture-pane -p | md-memo

Glossary: internal names and what they refer to

Release notes, configuration files, and CLI subcommands still carry the names these features were built under. You never need them for day-to-day use, but here is what they mean when you run into them.

Term Which feature What it means
Jev Quick Actions An external judging / inference model provided by TypeSafe AI — it is not built into MD-Memo. It is used only when you enter an API key, or point the Base URL somewhere other than the OpenRouter default, under Settings → Agent → Suggestions (Quick Actions); otherwise MD-Memo uses its built-in local rules. The name also survives as a CLI subcommand, as in md-memo jev verify, but jev verify (the AST check) runs entirely locally.
Slot Delegate to an agent The {{ }}-style notation in your note, and the mechanism that calls an agent from it. slot_profiles in the config file is where those notations are defined.
Auto selector Delegate · Auto Selector What Ctrl + Enter does with a line that is not already a slot. It decides, by fixed rules on your PC, whether the line is for the built-in AI, an agent or a command. It uses no network and no model, and it does not use Jev. It is not the quick selector, the popup that opens when you type {{.
Result block Auto selector The answer written below a task line, between two HTML comment lines (<!-- md-memo:res id --> and <!-- /md-memo:res -->). While the task runs, a one-line md-memo:run marker stands in for it.
Snippet Auto selector A ready-made task or command that you insert from the {{ popup, from the command palette ("Insert task snippet") or with a short word and Tab. Your own snippets, under snippets in agents.yaml, join the built-in ones.
Alias Delegate to an agent An extra name for an agent, set with aliases in agents.yaml. {{ @cc ... }} calls claude-code because cc is one of its default aliases.
System 1 Quick Actions The name for the fast inference mode that answers without deliberating — borrowed from the intuitive half of human thinking. It is why suggestions do not keep you waiting.
3-Beam Quick Actions The approach of offering up to three candidates at once rather than committing to one. Those are the three cards you see.
MAP-Elites Quick Actions The algorithm that keeps the three cards from resembling each other by picking candidates of different character, such as a Run card next to a Delegate card. Which kinds appear depends on what you are writing and on whether an external model is configured.
AST guardrail Quick Actions / md-memo jev verify Parses a shell command as syntax before running it and refuses it on detecting a destructive command, a write into a protected system directory, and similar patterns. It covers known dangerous patterns, not every possible risk.
Ghost Diff Delegate to an agent The 3 px amber line shown on the left edge of the editor, for the time you set, right after an agent's result is merged into the note. It does not mark only the changed lines. Esc undoes the change while the line is showing and for one second after.
Hover Peek Task panel The latest output line from a running agent, shown so you can peek at its progress.