{"slug": "luma-smart-launcher-for-you-and-your-ai-agent", "title": "Luma – smart launcher for you, and your AI agent", "summary": "Luma, a Linux launcher released by developer sakurartro, exposes its local CLIP and OCR photo index to AI agents through an MCP server (`luma mcp`) and a CLI (`luma query`), letting an agent retrieve a photo by content or embedded text in a single call under a second instead of walking the disk with `find`. In a single-run comparison using Claude Code with Sonnet 5.5 at medium effort, the same prompt took 11 seconds with Luma versus 1 minute 26 seconds without it. Luma indexes applications from all XDG directories, files and photos locally, with semantic photo search and OCR search both opt-in and the index and models kept on the user's machine.", "body_md": "**Smart launcher for you, and your AI agent**\n\nA Linux launcher that finds apps, files — and photos by what's in them. The same index is open to AI agents: ask one for \"the photo of a bear\" and it finds it in seconds.\n\n<sub>Same prompt, one run each (Claude Code, Sonnet 5.5, medium effort): 11 s with Luma, 1 min 26 s without.\nBoth at 3x speed. [More on agents](#for-ai-agents).</sub>\n\n```\ncurl -fsSL https://raw.githubusercontent.com/sakurartro/luma/main/install.sh | sh\n```\n\nThe script downloads the binary into `~/.local/bin` (or a path of your choice: `... | sh -s /usr/local/bin`).\n\n## Keybind and floating window for Hyprland, niri, GNOME, KDE\n\nLuma does not grab global keys itself — on Wayland that is forbidden by\nprotocol design. Bind a key to `luma --toggle`: it shows/hides the window\nof the running instance; launching the binary again while an instance is live\nacts the same. A cold start without the flag opens the window right away.\n\n**Keybind** — stock in `~/.config/hypr/hyprland.conf`; Omarchy (which does\nnot read `hyprland.conf`; the entry point is the Lua file) in\n`~/.config/hypr/bindings.lua`:\n\n```\nbind = SUPER, Space, exec, luma --toggle\nhl.bind(\"SUPER + SPACE\", hl.dsp.exec_cmd(\"luma --toggle\"))\n```\n\n**Floating window** for the app id `luma-rust` (Wayland apps cannot request\nfloating themselves — the compositor decides) — stock:\n\n```\nwindowrule = float, class:^(luma-rust)$\n```\n\nOmarchy in `~/.config/hypr/hyprland.lua`:\n\n```\no.window(\"^(luma-rust)$\", { float = true, center = true })\n```\n\nReload afterwards: `hyprctl reload`.\n\n**Keybind** — in `~/.config/niri/config.kdl`:\n\n```\nbinds {\n    Mod+Space { spawn \"luma\" \"--toggle\"; }\n}\n```\n\n**Floating window** — same file:\n\n```\nwindow-rule {\n    match app-id=\"luma-rust\"\n    open-floating true\n}\n```\n\nRestart niri to apply. If `Super+Space` is already taken (e.g. input source\nswitch), pick another combo — e.g. `SUPER, D` / `Mod+D` — and use it everywhere.\n\n**GNOME** — Settings → Keyboard → Custom Shortcuts, command `luma --toggle`.\nGNOME has no window rules; the window opens wherever the DE places it (force\nfloating with an extension, e.g. *Try*).\n\n**KDE** — System Settings → Shortcuts → Add Custom Command `luma --toggle`.\nFloating via Window Rules with Window class `luma-rust` (verify with `xprop`\nthat the class matches on X11).\n\nTransparency on X11 requires a compositor — GNOME and KDE ship one by default.\n\n**Search**\n\n- Fuzzy search of applications and files\n- Semantic photo search (CLIP) — opt-in; matching files show a `S(N%)` match-strength badge\n- Text-in-image search (OCR) — opt-in; matching files show a `T(N%)` badge\n- Calculator (`2 + 2` ) and currency conversion (`100 usd to eur` )\n\n**Apps**\n\n- Applications from all XDG dirs — system, `~/.local/share` , Flatpak, Snap; a user`.desktop` override shadows the system entry\n- Launch ranking from usage stats (with time decay), pinned apps on top (right-click to pin/unpin)\n- Category filter pills\n\n**Files and photos**\n\n- Separate views for apps, files, photos and settings (`Alt+1` …`Alt+4` )\n- File type icons and cached photo thumbnails in the files grid\n- File index with a background watcher and scan progress\n\n**System**\n\n- Power menu — shutdown, reboot, suspend, lock (power button in the bottom bar)\n- Settings menu in the launcher (`Alt+4` /`Ctrl+,` ) — edits`settings.json` for you\n- Full name on hover when a label is truncated\n\n**For AI agents**\n\n- MCP server (`luma mcp` ) and CLI (`luma query` ) over the same photo and screenshot index — see[below](#for-ai-agents)\n- One-click connect for Claude Code, Codex and opencode in Settings → Agents\n\n**Local by default** — the index and the models stay on your machine; see [Privacy](#privacy).\n\nAn agent that is asked to find a photo usually walks the disk with `find` and opens\nfiles one by one. Luma already holds a CLIP and OCR index of your photos, so the agent\nasks it instead: one call, under a second, by what is in the picture or by the words\nwritten on it.\n\n**Connect** — Settings → Agents (`Alt+4`) has a button for Claude Code, Codex and\nopencode: it registers `luma mcp` with the agent and switches the agent API on. By hand:\n\n```\nclaude mcp add luma --scope user -- luma mcp\ncodex mcp add luma -- luma mcp\n```\n\nand set `\"agent_api\": true` in `~/.config/luma/settings.json` (no restart needed). The API\nis off by default.\n\nThe server offers two tools: `luma_search_images` (what the picture shows, English\nqueries) and `luma_search_text` (words written on it, English text). Each returns the\nbest matches with a 0–100 score.\n\n**Requirements** — Luma must be running, and `semantic` (for images) and/or `ocr` (for\ntext) must be on, with indexing done. Only folders in `search_dirs` are searched. With a\nsearch not ready the tool answers with a message saying what to enable.\n\n**Without MCP** — `luma query clip \"river in fog\"` and `luma query ocr \"connection refused\"`\nprint one JSON line. [`agent/skills/luma/SKILL.md`](https://github.com/sakurartro/luma/blob/main/agent/skills/luma/SKILL.md) is a skill\nthat teaches an agent to use them.\n\nNothing leaves your machine except two things you can turn off: the model download\n(`semantic` / `ocr`, once) and exchange rates for `100 usd to eur` (`currency`, cached for\nan hour). Photos, thumbnails, the index and agent queries stay local.\n\n| Key | Action | \n|---|---|\n| `Enter` | Launch the selected (top) result | \n| `↑``↓``←``→` | Move the selection (left/right in the grid views) | \n| `Alt+1` | Apps | \n| `Alt+2` | Files | \n| `Alt+3` | Photos | \n| `Alt+4` /`Ctrl+,` | Settings | \n| `Esc` | Hide the window | \n| Right click | Pin / unpin an app | \n\nEdit settings in the launcher (`Alt+4` / `Ctrl+,`) or by hand in\n`~/.config/luma/settings.json`. Hand edits, `search_dirs`, `semantic` and `ocr`\napply after a restart (the menu offers a Restart button); everything else\napplies at once. New options are appended with their defaults; a broken file\nfalls back to defaults and is kept.\n\n| Option | Default |  | \n|---|---|---|\n| `bg`` surface``hover`` selected``border`` accent``text`` text_dim` | see below | Colors, `#RRGGBB` ; an unparsable value renders black | \n| `search_dirs` | `~/Documents``~/Pictures``~/Desktop` | Folders indexed for file search | \n| `hide_patterns` | `[\".\"]` | File name prefixes to hide (dotfiles) | \n| `semantic` | `false` | Photo search by meaning (CLIP, English queries). Downloads ~154 MB of models, indexes photos in the background | \n| `ocr` | `false` | Image search by the text on them (PaddleOCR, English). Downloads ~12 MB of models, runs after semantic indexing | \n| `agent_api` | `false` | Lets agents query Luma ( `luma mcp` ,`luma query` ). Set by Settings → Agents | \n| `currency` | `true` | `100 usd to eur` via open.er-api.com, rates cached for an hour.`false` = no network; the calculator still works | \n\n`semantic` and `ocr` cost nothing while off; turning them off keeps the models\nand index on disk for later.\n\nWhere things live (`$XDG_CONFIG_HOME` / `$XDG_CACHE_HOME` respected):\n`~/.config/luma/` — settings, `main.sqlite3`, `models/`;\n`~/.cache/luma/thumbs` — photo thumbnails.\nApps are read from `applications/` in `$XDG_DATA_HOME` and every\n`$XDG_DATA_DIRS` entry, refreshed when those dirs change.\n\nFull example (the defaults):\n\n```\n{\n  \"bg\": \"#0E120B\", \"surface\": \"#151B10\", \"hover\": \"#1E2716\", \"selected\": \"#28331C\",\n  \"border\": \"#2C3620\", \"accent\": \"#A9B665\", \"text\": \"#E4E7D0\", \"text_dim\": \"#7E8A6C\",\n  \"search_dirs\": [\"~/Documents\", \"~/Pictures\", \"~/Desktop\"],\n  \"hide_patterns\": [\".\"],\n  \"semantic\": false,\n  \"ocr\": false,\n  \"agent_api\": false,\n  \"currency\": true\n}\n```\n\n## Cold dark, warm, light\n\nCold dark:\n\n```\n{\"bg\": \"#0D1117\", \"surface\": \"#161B22\", \"hover\": \"#1C2431\", \"selected\": \"#24304A\", \"border\": \"#2D3748\", \"accent\": \"#58A6FF\", \"text\": \"#E6EDF3\", \"text_dim\": \"#8B949E\"}\n```\n\nWarm (gruvbox-like):\n\n```\n{\"bg\": \"#282828\", \"surface\": \"#32302F\", \"hover\": \"#3C3836\", \"selected\": \"#504945\", \"border\": \"#665C54\", \"accent\": \"#D8A657\", \"text\": \"#FBF1C7\", \"text_dim\": \"#A89984\"}\n```\n\nLight:\n\n```\n{\"bg\": \"#FBF7EF\", \"surface\": \"#F1EBDD\", \"hover\": \"#E9E1CE\", \"selected\": \"#DFE4CB\", \"border\": \"#D3CBB2\", \"accent\": \"#5B7A3A\", \"text\": \"#2E3324\", \"text_dim\": \"#8A8B76\"}\n```\n\n- Linux (glibc 2.39+ — Ubuntu 24.04, Fedora 40+, Arch; the ONNX runtime of the semantic search sets this floor)\n- The prebuilt binary links at runtime against libfontconfig, libGL (mesa) and libxkbcommon\n- Power menu uses systemd: `systemctl poweroff|reboot|suspend` ; lock is`loginctl lock-session` , so a locker must listen for it (e.g. hypridle with`lock_cmd` )\n\n```\ncargo build --release\n```\n\nDev packages (Debian/Ubuntu naming): `libxkbcommon-dev libfontconfig1-dev libgl1-mesa-dev libxcb1-dev`. Binary: `target/release/luma`.\n\n- Reset — delete `~/.config/luma/` (settings and database are recreated; models are downloaded again if enabled)\n- Wrong or stale thumbnails — delete `~/.cache/luma/thumbs` (regenerated on demand)\n- Stuck hotkey — kill the process or remove `$XDG_RUNTIME_DIR/luma-rust.sock` (or`/tmp/luma-rust-<uid>.sock` )\n- Agent does not see Luma — Luma must be running; `claude mcp list` should show`luma` ; with`semantic` /`ocr` off the tools return a hint, not results\n- Logs go to stderr — run Luma from a terminal to see them\n\n```\nrm -f ~/.local/bin/luma ~/.local/bin/luma_rust && rm -rf ~/.config/luma ~/.cache/luma\n```\n\n`luma_rust` is the old binary name; installs from before the rename keep it as a link.\nIf you connected an agent, remove it there too: Settings → Agents, or `claude mcp remove luma`.", "url": "https://wpnews.pro/news/luma-smart-launcher-for-you-and-your-ai-agent", "canonical_source": "https://github.com/sakurartro/luma", "published_at": "2026-10-29 16:30:06+00:00", "updated_at": "2026-10-29 16:47:18.961393+00:00", "lang": "en", "topics": ["ai-agents", "agent-protocols", "ai-tools", "developer-tools", "artificial-intelligence"], "entities": ["Luma", "sakurartro", "Claude Code", "Sonnet 5.5", "Codex", "opencode", "Hyprland", "niri"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/luma-smart-launcher-for-you-and-your-ai-agent", "markdown": "https://wpnews.pro/news/luma-smart-launcher-for-you-and-your-ai-agent.md", "text": "https://wpnews.pro/news/luma-smart-launcher-for-you-and-your-ai-agent.txt", "jsonld": "https://wpnews.pro/news/luma-smart-launcher-for-you-and-your-ai-agent.jsonld"}}