# magpie
> Spotlight-style search for everything you saved and forgot.
[简体中文](README.zh-CN.md) · **[Feature tour →](https://dfine.tech/magpie/)**
Magpies hoard shiny things and famously forget where they put them. So do we:
GitHub stars we never open again, files buried in project folders, screenshots
we can describe but cannot find, bookmarks and history lost in the browser,
that snippet we copied an hour ago, the app three menus deep. **magpie** is a
tiny desktop launcher that brings them all back. Press a hotkey, type what you
vaguely remember (or drop in an image), hit Enter.
▶ full-quality demo with sound · 60s · 2.4 MB

 GitHub stars with full-README search, sorted and dated |
 Bookmarks and browser history in one Web tab |
 Clipboard history: copy back, multi-select, delete |
 Drop in an image and similar files rank with percentages |
## Why magpie
**Privacy you can check for yourself.**
- **No full-disk scanning, ever.** magpie only indexes folders you explicitly
add, so it reads your working directories and nothing else. Scanning is
recursive within those folders, `.gitignore` rules are respected (even
outside git repos), hidden files are skipped, and symlinks are never
followed out of the folders you chose. Nested or duplicate folders are
rejected up front. *Add common places…* in settings lists where saved
things usually land on this computer (Downloads, the desktop, the
screenshots folder and, on Windows, the folders WeChat and QQ keep
received files in), each with its file count; only what you tick is added.
- **Everything stays on your machine.** The index is a single SQLite file in
your user profile. Embedding models run locally via ONNX; after the one-time
download the whole thing works offline. Bookmarks are read straight from
local browser files, with no browser APIs and no accounts. Nothing is sent
anywhere.
- **You can see exactly what is indexed** and remove any folder with one
click; its files, search index, and vectors are wiped together. Every
folder (and the star index) also has a rebuild-from-scratch button.
**Search that understands what you mean.**
- Hybrid retrieval: SQLite FTS5 (BM25) keyword search fused with local
semantic embeddings (`multilingual-e5-small`) via reciprocal rank fusion.
- Cross-language: query in Chinese, match English READMEs and code, and the
other way round (100+ languages).
- Long content is chunked (~1600 chars, overlapping) with one vector per
chunk, so a sentence 100 pages deep still surfaces; documents and READMEs
rank by their best chunk.
- Keyword hits show a highlighted context snippet with ellipsis.
- Millisecond-fast: vectors live in memory, a query embeds in ~5 ms, and
keyword search keeps working while models warm up.
**One launcher for everything you keep.**
- **Six things, one keystroke**: local files (full-text + by name), images
by content, GitHub stars, browser bookmarks and history, your clipboard,
and installed apps, all behind `Alt+Space`.
- **Over full-screen apps too** (macOS): the palette opens on whatever Space
you are in, a full-screen browser or terminal included. magpie lives in the
menu bar there, with no Dock icon or Cmd-Tab entry, like Spotlight.
- **Search inside your videos**: shots are detected and embedded, so a
dropped image or a description finds the exact scene, with its time range.
- **A real app launcher**: type an app name (prefix, substring, or acronym
like `vsc`) and `Enter` launches it from the Start Menu, `/Applications`,
or a Linux `.desktop` entry. Windows Store apps are there too (Notepad,
Calculator, Paint, Terminal, Settings); Windows' own ones answer to their
English and Chinese names whatever the system language. Chinese app names
match by pinyin too: `wx`, `weixin`, or `txhy` launch 微信 and 腾讯会议
without switching your input method.
- **Speaks your language**: the whole UI (tray menu included) is available in
English and 简体中文, following your OS by default and switchable in
settings.
- **Clipboard history that respects secrets**: opt-in, stored locally, and
clips a password manager marks confidential are never recorded (honored on
Windows and macOS). Passwords and access keys you copy yourself show with
the middle starred until you ask to see them, and MCP clients only ever get
the starred form. Cap it by count and age, multi-select and delete, and
`Shift+Enter` pastes straight into the app you came from. `Ctrl+P` pins a
clip: it sorts first and survives count/age pruning.
- **Copied images are history too**: screenshots and copied pictures join
the clipboard history with thumbnails, and SigLIP runs on your clips, so
you can find them later by *describing* them ("that error dialog").
- **Search the text inside your screenshots and your videos**: opt-in
OCR (PP-OCRv4, ~15 MB, Chinese + English) reads indexed images and each
video shot's frame, so subtitles, slides, and on-screen code become
searchable; a video hit jumps straight to the moment the text appears.
Pick PP-OCRv4 (15 MB) or the sharper PP-OCRv6 small (30 MB) in settings,
off by default. A separate sub-switch also reads scanned PDFs (pages with
no text layer), left to you because large scans take a while.
- **It learns your habits**: results you actually open float up over time
(frequency + recency, decaying). Those statistics stay on your machine and
never outweigh a better match.
- **Videos open at the scene**: when your default player is VLC / mpv /
PotPlayer / MPC, `Enter` on a shot starts playback at its time range.
- **Multi-monitor aware**: the palette summons on the display your cursor
is on.
- **Settings travel with you**: one-click export/import (everything except
the GitHub token).
- **A calculator lives in the query box**: `3*(5+2)^2`, `0xff + 1`,
`100 mb to gb`, `32 f to c`. The answer appears as the top row and `Enter`
copies it. Its siblings: `uuid`, `now` / `ts 1700000000`, `pwd 24` (CSPRNG
passwords), `b64` / `unb64` / `url` / `unurl`, and `#ff6600` shows a color
chip with rgb/hsl conversions.
- **Dates too**: `today + 30d`, `2026-10-01 - today`, `until 2026-10-01`,
`tomorrow + 3 months`. A lone `2026-10-01` tells you the weekday and how
far off it is.
- **Time zones, offline**: `tokyo time`, `time in new york`, `东京时间`, or
`3pm pst to beijing` and `9am to london` (from your local time). Daylight
saving is applied for the date; a bare `tokyo` stays a search.
- **System commands**: lock the screen, sleep, restart, shut down, empty the
trash, toggle dark mode, by name in either language (`lock`, `锁屏`,
`sp`). Restart, shut down and emptying the trash take a second `Enter`.
- **System settings, one step away**: `wifi`, `bluetooth`, `display`,
`sound`, `power`, `default apps`, `uninstall`, `printer` and a dozen more,
or the same in Chinese (`蓝牙`, `分辨率`, `卸载`), open that page of the
system settings. `uninstall` and `storage` are Windows only. On a Mac only
the panes that exist are offered; on Linux they need GNOME Settings.
- **A path opens where you typed it**: `D:\Projects`, `~/Downloads`,
`%APPDATA%` or `$HOME/.config` (quotes from a paste are fine) offer to open
the folder, or to show a file in its folder; `Enter` does it. Only a path
that exists takes over the box, so a half-typed one never gets in the way.
- **Volume**: `vol` shows the output volume, `vol 40` sets it, `vol +10` and
`vol -10` step it, `mute` and `unmute` (`静音`) do what they say. The row
shows before and after; `Enter` applies it.
- **End a process**: `kill chrome` lists running processes by name with
their memory; `Enter` twice ends the selected one. `top` (or `内存`) lists
what uses the most memory and `cpu` what uses the most CPU right now; each
row also shows the total for every process of the same name, so a browser's
twenty helpers do not hide behind small numbers. `port 3000` (or
`kill :3000`) lists what is listening on that port instead. magpie and the
system's own processes are never listed.
- **Text in a copied image**: `ocr` alone reads the text in the image on your
clipboard, a screenshot you just took for instance; `Enter` copies it. Uses
the OCR engine, so switch on *Image text (OCR)* in settings first.
- **Your local IP**: `ip` shows this machine's address on the local network,
real adapters before virtual ones (WSL, Docker). Read from the adapters, so
it works offline and sends nothing.
- **Newest downloads**: `dl` lists the newest files in your Downloads folder,
without indexing it; `Enter`, `Ctrl+K` and the rest work as on any file.
Downloads still in progress are left out.
- **Chinese capitals and pinyin**: `大写 1234.56` gives 壹仟贰佰叁拾肆元伍角陆分
for invoices and contracts. `py 重庆` gives *chóng qìng*, with tones; common
words read differently from their characters (银行, 长大) come out right,
other polyphonic characters get their most common reading.
- **Chinese calendar, offline**: `农历` (or `nl`) shows today as 农历丙午年八月十九,
with the zodiac year, festivals and where the solar terms stand. `农历 2026-10-1`
does the same for any day. The other way round, `农历 八月十五`, `农历 腊月廿三`
or `农历 中秋` gives the Gregorian date of the next one and how many days are
left; `节气` names the next solar term and `节气 清明` finds the next 清明.
Arabic numerals mean a Gregorian date, Chinese ones a lunar date. It covers
1900 to 2100 and needs no network. Public holidays and swapped workdays are
not included, since they are announced year by year.
- **Solar term reminders**: on the first day of each of the 24 solar terms,
after 9 am, a notification brings a couplet of classical verse for it, one
of five per term, a different one each year; all 120 were checked against
published texts. On Windows, clicking it opens the palette on that term.
All that day the couplet also takes turns with the tips under the empty
box. On by default when the interface is in Chinese; Settings → General
turns it on or off.
- **Width and escapes**: `半角` and `全角` convert letters, digits and symbols
(the marks of a Chinese sentence stay wide); `unicode` and `html` escape or
unescape. Alone they work on the clipboard.
- **QR codes both ways**: with an image on the clipboard, `qr` reads the code
in it; with text, it draws one.
- **Compare two copies**: `diff` shows how the last two texts you copied
differ, line by line. It needs the clipboard history.
- **Timers**: `timer 25m standup` starts a countdown and a notification comes
when it ends. `timer` alone lists the running ones; `Enter` stops them.
- **System at a glance, and chance**: `sys` shows CPU load, memory and free disk
space. `random 1 100`, `pick pizza tacos ramen`, `dice` and `coin`.
- **An action menu on every row**: `Ctrl+K` (`⌘K` on macOS) lists what the
selected result can do: open with the default app or show in its folder,
copy the path or the file, open a file's folder in a terminal or the file in
an installed editor (VS Code, Cursor, Trae, Zed, Sublime Text and a few more), move
a file to the Recycle Bin or Trash (a second `Enter` confirms), run an app as
administrator (Windows), copy a repo's clone command or a page as a Markdown
link, save an image from the clipboard history as a file, pin or delete a
clip, end a process.
- **Edit in your own app**: `Ctrl+E` (`⌘E` on macOS) on a file opens it in
the app you picked for its type in Settings → Local Files, Photoshop for
images say; a type with no app picked uses the system's own way to edit.
- **PDF to Markdown**: on a PDF, `Ctrl+K` offers *Copy as Markdown* and
*Save as Markdown…* (next to the PDF by default). Every page is converted
in order, headings, lists and tables included; scanned pages are read by
OCR when it is on, and marked when it is not.
- **Text verbs work on your clipboard**: `json` alone pretty-prints whatever
you just copied; `upper`, `lower`, `trim`, `slug`, `lines` (dedupe and
sort) and `count` (chars, words, lines) likewise. Give them an argument
instead (`slug Hello World`) and they work on that. `Enter` puts the result
back on the clipboard.
- **JSON, hashes, tokens, names, QR**: `json` keeps keys in their order,
`json min` squeezes it onto one line, `json sort` orders the keys, and JSON
that does not parse says where it breaks (escaped JSON from a log is
unwrapped first). `md5` / `sha1` / `sha256` hash the text. `jwt` decodes a
token's header and payload and says when it expires, all on your machine.
`snake` / `kebab` / `camel` / `pascal` / `title` restyle a name
(`snake MyMacCleaner` → `my_mac_cleaner`). `qr` draws a QR code; `Enter`
copies it as an image.
- **Narrow a file search inline**: `ext:pdf` or `.md`, `>10mb` / `<500kb`,
`7d` (modified this week; `2w`, `3m`, `1y`), `in:projects`. Filters mix
with words: `invoice ext:pdf 30d`.
- **Quick notes**: `note buy milk` appends one timestamped line to a markdown
file of your choosing (Settings → Notes file). `Enter` writes it and the
palette goes away.
- **Look up what you have selected**: `Ctrl+Alt+Space` (`Option+Shift+Space`
on macOS) copies the selection in whatever app you are in and summons
magpie with it as the query. Rebindable or removable in Settings. On
macOS the copy needs magpie allowed under System Settings → Privacy &
Security → Accessibility; without it magpie says so, with a button that
opens that page.
- **Recent opens on the empty box**: switch it on and each tab lists what you
last opened from it, so getting back to a file from a minute ago is two
keystrokes. The Local tab also lists files in your folders that are new or
changed this week, so a screenshot or download you just saved is there
even if you never opened it through magpie.
- **The empty box**: with nothing typed, the right of the search box shows
today's date and weekday (in Chinese with the Chinese calendar, its
festivals and solar terms); it has its own switch. On the local tab your
pinned folders head the list (Settings → Local Files: up to four, in your
order, not necessarily indexed; `Enter` opens one).
- **From long ago** (off by default; turn it on in Settings → General):
then a bookmark and a starred repo you kept long ago, different ones each
day: the Web tab shows the bookmark, Stars the repo, the local tab both.
One kept on this date in an earlier year comes first
("2 years ago today you bookmarked this"); otherwise one kept at least
half a year ago that you have not opened from magpie. The row says only
when you kept it. `Ctrl+K` → "Don't show this again" retires it.
- **Workspaces**: keep the files, pages, apps and repos you open together
under one name, "taxes" say. `Ctrl+K` on any result → "Add to workspace",
an existing one or a new one. Type the name and press `Enter`: everything
opens. What cannot (a deleted file, an uninstalled app) is named and the
rest still opens. Names match by pinyin too; `ws` or `gzxc` lists them all. A settings export carries them.
- **Script commands**: a script in the scripts folder (Settings → Script
commands) whose top comment names it becomes a command in the box. The
header is Raycast's script-command format (`@raycast.title`,
`@raycast.mode`, `@raycast.argument1`, …), so Raycast scripts work as they
are; `@magpie.keyword tr` adds a short trigger, and `tr hello` passes
`hello` as its argument. The interpreter comes from the shebang or the
extension (PowerShell, bash, Python, Node, …); it runs in the script's
folder for at most a minute, and a run that goes over is stopped with
whatever it started. Nothing runs until you press `Enter` on it.
- **Bang-style web shortcuts**: `gh magpie` searches GitHub, `g …` Google,
`bd …` Baidu. Prefixes are editable rules in settings (`prefix = URL
with {q}`).
- **Emoji and symbol lookup**: type `:` then a keyword (`:fire`, `:火`) and
click or `Enter` to copy. Symbols that are not emoji are there too, such as
`:arrow` →, `:乘` ×, `:rmb` ¥, `:cmd` ⌘; `:sym` lists them all.
- **Every row has a copy**: `Ctrl+C` copies what identifies the row, a
file's path, a repo's or page's URL, a clip's text. `Ctrl+Shift+C` puts a
file itself on the clipboard, ready to paste into chat or mail as an
attachment.
- **Stays current on its own**: signed, verified in-place auto-updates from
this version on, with no reinstalling. Checked at launch and every 24 h
while resident; a pending release shows a red dot on the tray icon, next
to the settings hint and on the About tab in settings, plus a tray menu
entry. Installing stays your call.
- **A preview pane, one keypress away**: `→` shows the selected result in
place: file text with your terms highlighted, full-size images, a video's
shot strip, README head for repos, complete clips. Confirm before you open.
A downloaded file also says where it came from (*Downloaded from
github.com*) when the browser recorded it; a click opens that page. A
bookmark or a page from history shows its site, the summary Firefox kept
for it, where you bookmarked it and when, and how often you visited, from
the earliest visit your browser still remembers to the latest; all of it
from your browsers' own files, nothing fetched.
- **Yours to arrange**: reorder the tabs and pick which one opens on launch.
- **It teaches itself**: the empty palette shows a one-line tip, a shortcut
or a hidden trick, fresh on every summon (off-switch in settings).
- **Works where the network doesn't**: one-click switch to `hf-mirror.com`
for the model download, with resumable transfers and live progress. If both
Hugging Face and the mirror are unreachable, the models fall back to
magpie's own GitHub release assets automatically (same as ffmpeg).
- **Cross-platform**: Windows, macOS (Apple Silicon), and Linux.
## Sources (`Tab` cycles them)
### Local Files
Add your everyday working folders; every file in them is findable by
name, and understood formats are searched in full text:
- ~80 plain-text and code formats, read whole (size cap configurable, up to
unlimited)
- PDF via [pdf-inspector](https://github.com/firecrawl/pdf-inspector)
(scanned pages are read when OCR and its "Scanned PDFs" switch are on;
otherwise such PDFs stay findable by name)
- Word / Excel / PowerPoint (docx, xlsx, pptx)
- ZIP archives by the names of the files inside, so a search for a file that
only lives in a zip finds the zip (password-protected ones too: zip keeps
names in the clear; Chinese names from Windows' own zipping are read right).
Its preview lists the files inside, with the one that matched in view
- Everything else (video, other archives, binaries) indexes by filename
- Scope pills (or `Shift+Tab`) narrow results: all / text / images / videos /
folders
- The folders scope finds a folder by its name when you remember where you
put something but not what it was called. It lists every folder that holds
indexed files (same-named ones told apart by their path) with how many
files are under it; Enter opens it in the file manager, and the preview
lists its newest files. Names match as app names do (prefix, word start,
initials, anywhere in the name, pinyin), and several words match when each
is in the name. Folders without any indexed file are not listed.
- Linked git worktrees are skipped when the checkout they belong to is
already indexed, so a project with six worktrees is not indexed six times.
A worktree that is the only copy is indexed as usual; there is an
off-switch in settings.
- Indexing is capped at 4 CPU threads per model (text, image and OCR
alike), so an embed pass never owns the machine. Settings offer 1, 2, 4,
8 or every core; a change applies right away.
- Changes inside indexed folders reach the index within seconds: a file
watcher reports them and only the touched paths are re-read. A full walk
every 30 minutes (adjustable, or off) reconciles anything the watcher
missed, and "Rescan now" runs it on demand.
- The image model loads only once something needs it: an image or a video
in an indexed folder, or an image in the clipboard history. Index only
text and it never takes memory at all.
Images are embedded with **SigLIP 2** and searchable by content:
- *Text → image*: type "sunset over the sea" in any language; matching photos
rank alongside other results, thumbnails included.
- *Image → image*: drag an image onto the palette, paste a screenshot, or
click the pick-image button, and magpie returns the most similar indexed
images with cosine-similarity percentages.
Videos get the same treatment, one level deeper: each video in your folders is
split into shots (histogram-based scene-change detection, a pure-Rust pass
over 2 fps frames), every shot's representative frames are SigLIP-embedded,
and both image and text queries can land *inside* a video: the result row
shows the matching shot's thumbnail and its exact time range (`3:24 – 3:42`).
The Local tab's videos scope searches them by filename and by scene
description in one list. Decoding uses ffmpeg: a system install is picked up
automatically, or a static build is fetched once from magpie's own releases
(reachable wherever you downloaded magpie from;
[GPL builds](https://ffmpeg.org/download.html) by gyan.dev / evermeet.cx /
johnvansickle.com, sources at ffmpeg.org). Toggleable in Settings. In the
preview pane a video shows its shots, or a single frame when the shot index
has not reached it yet (with an ffmpeg already on the machine; a preview
never starts the download). Files with nothing to render show their folder,
size and age instead.
The index is incremental: startup, manual refresh, and a 30-minute timer pick
up new, changed, and deleted files automatically.
### GitHub Stars
Paste a personal access token (no scopes needed) and magpie syncs your entire
star list: names, descriptions, topics, and full READMEs (chunk-embedded).
Unstars are detected, README fetches are ETag-incremental, and only changed
content re-embeds. Sort matches by relevance, starred date, or star count
(pills or `Shift+Tab`); every row shows last-push time so abandoned projects
are obvious. A token is checked with GitHub before it is saved; once
connected, Settings offers Change token and Disconnect, which removes the
token and the star index from your computer.
### Applications
Typing in the Local tab surfaces matching installed apps as top hits, each
with its own icon and an `App` badge, and `Enter` launches. Names match by prefix,
by the start of any word (`mac` → MyMacCleaner), by acronym (`vsc` → Visual
Studio Code, `mt` → MacTap: camelCase humps count as words), or by substring. Chinese names also match
by full pinyin or initials (`wx` / `weixin` → 微信, `wangyiyun` → 网易云音乐),
heteronyms included (`cq` and `zq` both find 重庆…), so you never switch input
methods to launch an app. Toggleable in settings. Apps come from the Start
Menu on Windows, `/Applications` on macOS, and `.desktop` entries on Linux.
Apps kept elsewhere, such as on an external drive, join the list when you add
their folder under Settings → Local Files → App folders: only the apps are listed
(bundles on macOS; shortcuts and programs on Windows, skipping uninstallers
and updaters; desktop entries and AppImages on Linux), not the files inside
them. An unplugged drive simply drops its apps until it is back.
On macOS, apps inside folders are found too (Utilities, a vendor's folder),
and an app also answers to its localized name: `活动监视器` or `huodong` finds
Activity Monitor, shown under its Chinese name when the interface is in
Chinese. The list refreshes when you summon the palette (at most once a
minute) and every 30 minutes in the background, so a newly installed or
moved app is found without a restart; icons are cached and re-read only for
apps that are new or updated.
Apps also answer to aliases: a built-in bilingual table bridges Chinese and
English product names (`lark` finds 飞书, `weixin` finds an app installed as
*WeChat*, whichever direction your system has), well-known short names come
built in (`ps` finds Adobe Photoshop 2026, `ae` After Effects, `ppt`
PowerPoint: the marks on Adobe's own icons), Linux picks up `.desktop`
`Keywords=`/`GenericName=` for free, and you can add your own rules in
Settings (`proxy = clash`, one per line). Aliases match like second names,
pinyin included.
### Web (bookmarks + history)
The Web tab searches browser bookmarks and history together; `Shift+Tab`
narrows to all / bookmarks / history. History covers page titles and URLs
(not just addresses) with a visit-count boost so pages you open often rank
higher; only the most-visited pages per profile are kept. Bookmarks and
history come from any Chromium-based browser (Chrome, Edge, Brave, Vivaldi,
Arc, Opera, Helium, ...) and any Firefox-based one (Firefox, LibreWolf, Zen,
Floorp, Waterfox, ...); forks are found by their on-disk profile layout, not
a fixed list. Safari isn't read. Read directly from local stores (all
profiles; new bookmarks and visits show up while the browser is still open),
searchable by title, URL, and folder path. When nothing matches the words
you typed, up to three pages close in meaning are shown, marked "maybe
related". A page kept in several browsers is one row with each browser's
icon. `Enter` opens the bookmark in your default browser.
### Quick web launcher
magpie also doubles as the fastest route to the web. Summon the palette from
inside any app, type a URL or whatever you want to look up, and hit
`Ctrl+Enter`: URL-looking input opens directly in your default browser,
anything else becomes a web search. No switching windows, no reaching for
the browser's address bar first.
### Clipboard History
Off by default. When you enable it in Settings, copied text is recorded to a
local database (not the system clipboard history) and searchable from the
Clipboard tab. This is the one source where an empty query is useful, listing
what you most recently copied. `Enter` copies an entry back; `Ctrl+Delete`
removes the selected entries; `Shift`+arrows multi-select (and `Enter` then
copies them joined). Text marked confidential by password managers is never
recorded. What you copy yourself is checked for secrets: keys with a known
shape (GitHub, OpenAI, AWS, Slack, JWTs, private keys, …) anywhere in a clip,
the value in `password = …` or `API_KEY: …`, and a clip that is one word
mixing three kinds of characters the way generated passwords do. These show
as head and tail with `****` in between; `Show` on the row (or `Ctrl+K` →
Show the full text) reveals one until the palette loses focus. Copying or
pasting always gives the full text, and the MCP server returns only the
starred form. Cap history by count (500 / 2000 / unlimited) and age (7 / 30 days
/ forever), or clear it entirely.
## Keyboard
| Key | Action |
|---|---|
| `Alt+Space` | summon / dismiss the palette (rebindable in settings) |
| `↑` `↓` / `PgUp` `PgDn` | move / page through results |
| `Enter` | context action: open a repo/bookmark/history page in the browser, reveal a file in Explorer/Finder, launch an app, or copy a clip. The box is empty on the next summon (`Esc` keeps what you typed) |
| `Ctrl+Enter` | hand the query to the browser: URL-looking input opens directly, anything else web-searches |
| `Ctrl+C` | copy what identifies the row: a path, a URL, a clip's text (`Ctrl+Shift+C`: the file itself) |
| `Ctrl+K` | the selected result's action menu (`↑↓` to pick, `Enter` to run, `Esc` to close) |
| `Ctrl+E` | edit the selected file in the app picked for its type |
| `Ctrl+Alt+Space` | in any app: look up the selected text (`Option+Shift+Space` on macOS; rebindable) |
| `Tab` | next source (Local / Stars / Web / Clipboard, order set in settings) |
| `Ctrl+1` … `Ctrl+9` | jump straight to that tab, in strip order (`Alt` instead, or off, in settings) |
| `Shift+Tab` | cycle the active source's mode: local scope (all/text/images/videos/folders), web scope (all/bookmarks/history), or star sort |
| `Shift+Enter` | paste the selected clip(s) into the previous app (Clipboard tab) |
| `Shift`+`↑` `↓` | extend a multi-selection (Clipboard tab) |
| `Ctrl+Delete` | delete the selected clips (Clipboard tab) |
| `→` / `←` | open / close the preview pane (`→` with the cursor at the end of the query) |
| `Alt+,` or `Ctrl+,` (`⌘,` on macOS) | toggle Settings ↔ search |
| `Esc` | close the action menu → clear image query → close settings → hide window |
| drop / paste / pick an image | search local images by similarity |
On macOS, `Cmd` works wherever the table says `Ctrl`.
The palette sits top-center, stays above every window, and can be dragged by
its tab strip. It hides when another window takes focus, on by default on
macOS; on Windows and Linux it stays until dismissed by default, so files can
be dragged in from other windows. Settings switch it either way. Tab order
and the tab that opens on launch are both configurable.
### From the command line, and on Wayland
Launching `magpie` again talks to the copy that is already running:
- `magpie --toggle` shows the palette, or hides it when it is showing
- `magpie --source clips` opens on a tab: `local`, `stars`, `web` or `clips`
- `magpie --query "invoice"` opens with that text in the box; it combines
with `--source`
Any of these can sit behind a key in a window manager, or in a script.
A Wayland desktop lets no app claim a key for itself, so there the summon key
is the desktop's to bind. On sway and Hyprland magpie binds it at start
through their IPC and floats its window; nothing is written to your config,
and a new shortcut in Settings is bound the same way. On niri, GNOME, KDE and
the rest, Settings → Summon shortcut shows the command to bind (on niri, the
lines to add to `config.kdl`).
## Settings (tray icon → Settings…)
GitHub token (with connection badge) · indexed folders (add / remove /
rebuild) · appearance (auto / light / dark / paper / paper dark) · UI language (auto / English /
中文) · launch at login · solar term reminders · hide on click-out · jump-to-tab keys (Ctrl/Cmd,
Alt or off) · pinyin app matching · app aliases · summon shortcut (recordable) ·
search-selection shortcut · notes file · recent opens on the empty box ·
model download source (huggingface.co or hf-mirror.com for networks where
HF is unreachable) · max file size (4/16/64 MB or unlimited) · video shot
search toggle · decode limits (threads / hardware decode) · indexing
threads (1 to every core) · file watcher · full rescan interval and
"Rescan now" · tab order and
default tab · clipboard history controls · model download status · one-click
in-place updates (signed, verified) · settings export/import · MCP server
for AI assistants (off by default) · open-log-folder (local activity log for
bug reports; queries never logged) · app version.
## AI assistants (MCP)
magpie can serve its index to Claude Code, Cursor and any other MCP client,
over HTTP on the loopback interface. Off by default. Switch it on in Settings
→ "MCP server for AI assistants", press "Copy Claude Code command" and paste
into a terminal:
```
claude mcp add --transport http magpie http://127.0.0.1:PORT/mcp --header "Authorization: Bearer TOKEN"
```
Other clients take the same URL with the same `Authorization` header; only
where the two go differs:
- Cursor (`.cursor/mcp.json`): `{ "mcpServers": { "magpie": { "url": "http://127.0.0.1:PORT/mcp", "headers": { "Authorization": "Bearer TOKEN" } } } }`
- VS Code (`.vscode/mcp.json`): `{ "servers": { "magpie": { "type": "http", "url": "http://127.0.0.1:PORT/mcp", "headers": { "Authorization": "Bearer TOKEN" } } } }`
- Codex CLI (`~/.codex/config.toml`): `[mcp_servers.magpie]` with `url = "http://127.0.0.1:PORT/mcp"` and `http_headers = { Authorization = "Bearer TOKEN" }`
- Gemini CLI (`~/.gemini/settings.json`): `mcpServers.magpie` with `httpUrl` and `headers`
- Clients that only speak stdio (Claude Desktop's local config is one): bridge with `npx mcp-remote http://127.0.0.1:PORT/mcp --header "Authorization: Bearer TOKEN"`
Claude Code is the one client tried end to end; for the others, the shapes
above show where the URL and header go, and their own docs have the rest.
Three read-only tools:
- `search`: `source` is one of `local`, `stars`, `bookmarks`, `history`,
`clips`; local queries take the palette's filters (`ext:pdf`, `>10mb`,
`7d`, `in:folder`). Hits are ranked exactly as the palette ranks them.
- `read_file`: the indexed text of one local hit (PDF, Office and OCR text
included), 20 000 characters by default. Only paths inside the indexed
folders.
- `recent`: what you opened lately through magpie.
What keeps it contained: the server binds `127.0.0.1` on a random port that
is then remembered; every request needs the bearer token (minted when first
enabled, "New token" replaces it); foreign `Host` and browser `Origin`
headers are refused; nothing writes. Token and port never enter a settings
export. If your shell sets `HTTP_PROXY`, add `127.0.0.1` to `NO_PROXY` so the
client reaches the server directly.
## Install
Grab the latest build from [Releases](https://github.com/newdee/magpie/releases):
Windows NSIS installer, macOS dmg (Apple Silicon), Linux AppImage/deb/rpm.
The Linux builds run on Ubuntu 22.04 or newer and other distributions with
glibc 2.35+; they carry Microsoft's ONNX Runtime library for semantic search.
On a Mac, Homebrew works too:
```sh
brew install --cask newdee/tap/magpie
```
macOS builds are Developer ID signed and notarized (since v0.1.24), so they
open like any other app and folder-permission grants survive updates.
The first start opens on a short welcome and asks whether to turn on
semantic search. Nothing is downloaded until you say yes; then the text
model (~500 MB) comes down once, with keyword search working meanwhile, and
the image model (~200 MB) follows once an image, a video or an image clip is
indexed. Without it, search matches words (videos are listed by name, not
split into scenes) and everything else works the same. Settings → General switches it on or off, and can pause it to free
the models' memory (about 0.8 GB on Windows) for a game or another heavy
program; the tray menu can too. A paused search runs on keywords until you
resume it or restart magpie. Installs from before this keep semantic search
on.
## Build from source
```sh
pnpm install
pnpm tauri dev # development
pnpm tauri build # release bundle
cargo test -p magpie-core # core tests
```
On Linux, run `scripts/fetch-onnxruntime.sh` once first: it puts Microsoft's
ONNX Runtime library where the bundles pick it up. A dev build finds it
through `ORT_DYLIB_PATH="$PWD/src-tauri/lib/libonnxruntime.so" pnpm tauri dev`.
Requires Rust, Node + pnpm, and a WebView2/WebKit runtime (bundled on
Windows 11 and macOS).
## Architecture
```
core/ Rust library: SQLite + FTS5, GitHub sync, folder indexing,
bookmark + history + clipboard + app sources, e5 + SigLIP
embeddings, hybrid ranking
src-tauri/ thin Tauri shell: commands, tray, global hotkey, window,
clipboard watcher, auto-updater
src/ React palette UI (one window)
```
The vector "database" is deliberately boring: L2-normalized f32 BLOBs in
SQLite, brute-forced in memory (<15 ms at tens of thousands of chunks, 100%
recall). If a corpus ever outgrows that, `sqlite-vec` drops into the same
file.
## Roadmap
- Twitter/X likes as a source (via your data-export archive, no paid API)
## Thanks
To everyone who has reported a bug or suggested an idea in
[Issues](https://github.com/newdee/magpie/issues):
## License
[MIT](LICENSE)