Tauri 2 + Rust backend, Svelte 5 frontend. A native macOS clipboard manager that runs silently at 8 MB, polls at 300 ms, and exposes your history to AI via MCP.
Architecture
Tauri bridges a Rust backend (clipboard, DB, shortcuts) with a Svelte 5 frontend via typed commands and event emission.
Rust Backend
Pure Rust — no npm deps. Each module owns a single responsibility.
Database Layer
SQLite via rusqlite with WAL mode, memory temp store, and 256 MB mmap. Single migration (v001) creates all tables. Singleton connection wrapped in Arc<Mutex> for thread-safe access.
Clipboard Watcher
Background thread polls system clipboard every 300ms via hash comparison. Handles text, images (saved as PNG), and file lists. Deduplicates by touching updated_at on identical content instead of creating new rows.
Content Detector
Regex-based classifier assigns content_type (url, email, color, code, image, file, text) and generates 200-char previews. URL, email, and color patterns are exact-match; code detected by multi-line + symbol density.
Shortcut Manager
Registers/deregisters global hotkeys via tauri-plugin-global-shortcut. Master shortcut (Cmd+Shift+V) shows window; per-folder shortcuts capture selected text via osascript + sentinel detection then save directly to that folder.
Window Manager
Controls the frameless always-on-top floating panel. ActivationPolicy::Accessory hides from Dock and Cmd+Tab. Window is pre-rendered and shown/hidden instantly via visibility toggle — no reload cost.
System Tray
Builds macOS menu bar icon with Open / Update / Quit context menu. Tray click shows/hides window. Listens for update events to add version badge and notification. No Dock presence.
Tauri Commands
Four command files expose the backend to Svelte: folders.rs (CRUD + reorder), clips.rs (get, pin, delete, move, copy, export), settings.rs (update with side effects), utility.rs (stats, cleanup, CLI install, update check).
CLI + MCP Server
Standalone 828-line Rust binary with subcommands: list, add, remove, pin, get, folder, context, mcp. The mcp subcommand launches a JSON-RPC 2.0 stdio server exposing 9 clipboard tools to Claude Desktop, Cursor, and Windsurf.
Svelte 5 Frontend
Svelte 5 runes for zero-runtime reactivity. Class-based stores with $state. Typed invoke() wrappers eliminate runtime errors.
lib/api/tauri.ts
Typed wrappers around Tauri invoke() for all backend commands. Type definitions for Folder, ClipItem, Settings, AppStats.
lib/stores/clips.svelte.ts
Svelte 5 rune-based store — items, isLoading, searchQuery, activeFolder, flashingId. Methods: load(), prependItem(), removeItem(), updateItem().
lib/stores/folders.svelte.ts
Folder list and active folder tracking with $state runes. Synced with backend via Tauri events.
App.svelte
Root shell. Registers Tauri event listeners (clip:new, folder:saved, cleanup:done, update:progress). Handles search debounce and window focus/blur logic.
ClipCard.svelte
Individual clip: preview text, type icon, timestamp, source app, pin badge. Hover reveals copy/pin/delete actions. Click triggers 150ms accent flash + copy command.
FolderModal.svelte
Create/edit folder with emoji picker, hex color picker, and global shortcut recorder with conflict detection.
SettingsPanel.svelte
Slide-in panel with sections: General, Clipboard, Shortcuts, Auto-cleanup, About. Setting changes trigger backend side effects (re-register shortcut, reschedule cleanup).
SearchBar.svelte
Full-width search with 150ms debounce. Cmd+F or / to focus. Empty/Escape to return to folder view. Searches across ALL folders.
Data Flow
From startup to clipboard copy — every step in sequence.
Tauri initializes, opens SQLite at ~/.monoclip/monoclip.db, runs migrations, creates AppState. Sets ActivationPolicy::Accessory (menu bar only). Initializes plugins, builds tray, registers global shortcuts, starts clipboard watcher thread, runs auto-cleanup if enabled.
Background thread reads system clipboard. Tries: file list → image → plain text. Hashes content; skips if identical to last. Runs content-type detector (regex). Deduplication: identical in Inbox → touch updated_at. New: INSERT into clip_items, enforce max_history_items (delete oldest unpinned), emit clip:new event.
watcher.rs → detector.rs → db/queries.rs → emit('clip:new', item)App.svelte listener fires on clip:new. If no search active and viewing Inbox: clipsStore.prependItem(item) with spring entrance animation. No full reload — single prepend keeps scroll position.
Global shortcut fires; window.show() + window.setFocus(). Pre-rendered Svelte UI instantly visible (no load time). Spring animation from 0.96→1.0 scale in 180ms. Content already populated from background sync.
Click on ClipCard → invoke copy_to_clipboard(id). Backend fetches content, writes to system clipboard via tauri-plugin-clipboard-manager. If paste_on_click=true: spawns async task to simulate Cmd+V after 150ms delay. Frontend shows 150ms color flash on the card.
User presses Cmd+Opt+1 (assigned to Work folder). shortcuts/manager fires: runs osascript to capture selected text (Cmd+C with sentinel). If selection found → save to folder. If not → read current clipboard. Emits folder:saved event. Toast: 'Work ← selection'.
osascript → sentinel detect → folder save → emit('folder:saved')User types in SearchBar. 150ms debounce fires clipsStore.load(undefined, query). Backend runs LIKE pattern on content + preview across ALL folders, returns ≤50 results. Frontend replaces list. Escape → reload current folder.
Triggers on startup + daily background timer. Deletes non-pinned, non-deleted clips older than auto_clean_days (default 30). Exceptions: always keeps 10 most recent Inbox items; pinned items never deleted. Emits cleanup:done. Toast: 'Auto-cleaned 42 old clips'.
Storage
Single file at ~/.monoclip/monoclip.db with 4 tables. WAL mode + mmap for concurrent read/write.
folders
clip_items
settings
schema_version
SQLite Performance Pragmas
journal_mode=WALConcurrent read/write
synchronous=NORMALFast writes, still safe
temp_store=MEMORYIn-memory temp tables
mmap_size=256MBMemory-mapped I/O
AI Integration
mclip mcp starts a JSON-RPC 2.0 stdio server exposing 9 clipboard tools to Claude Desktop, Cursor, and Windsurf.
list_clips
List clips with optional folder, search query, and pagination limit
add_clip
Insert new text clip into specified folder
get_clip
Fetch full raw content by clip ID
remove_clip
Delete clip by ID (soft delete)
pin_clip
Mark clip as pinned — skips auto-cleanup
unpin_clip
Remove pin status from clip
list_folders
Get all folders with emoji, color, shortcut
create_folder
Create new folder with emoji and hex color
delete_folder
Delete folder — clips moved to Inbox
Configuration
// ~/.config/claude/claude_desktop_config.json
{
"mcpServers": {
"mclip": {
"command": "mclip",
"args": ["mcp"]
}
}
}Performance
Tauri + Rust deliver native performance. Every metric is measured on macOS with SSD storage.
| Operation | Speed | Notes |
|---|---|---|
| Binary size | ~8 MB | vs Electron ~150 MB |
| RAM idle | ~30 MB | vs Electron ~300 MB |
| Startup to tray ready | <200 ms | No splash screen |
| Window reveal | <50 ms | Pre-rendered, just toggle visibility |
| Clipboard poll cycle | <1 ms | Hash check only if unchanged |
| Search (10K clips) | <50 ms | LIKE + LIMIT + indexed columns |
| DB queries | <10 ms | WAL mode + mmap + indexes |
| Image save to PNG | <30 ms | ~/.monoclip/images/ |
vs Electron Alternatives
Storage Limits