Content
<div align="center">
# 🐟 silverfish
**A local-first, 100%-private memory companion for your Mac. The AI never leaves your machine.**
</div>
silverfish quietly remembers what you work on and lets you *search it, ask about
it, and write in your own voice* — using a large language model that runs
**entirely on your Mac** via [Ollama](https://ollama.com). No cloud. No API
tokens. No telemetry. Your activity is captured to a local SQLite database and
every AI request goes to `127.0.0.1` and nowhere else.
It doesn't lock you into one model, either: silverfish runs whatever Ollama
model your Mac can actually handle, and a built-in setup wizard
(`silverfish onboard`) tells you which one that is for *your* hardware —
instead of leaving you to research local-model sizing yourself.
If you're already using a similar local memory app, silverfish can import its
existing database on first run — your captured history carries over — and it
exposes an MCP interface today so your Claude Desktop / Claude Code / Cursor
integrations keep working, without anything ever phoning home.
---
## What it does
- **Captures** foreground activity every few seconds using macOS Accessibility
APIs — text and metadata only, **never screenshots**. App, window title, URL,
and focused text, coalesced into a searchable timeline.
- **Remembers privately** in SQLite with full-text search (FTS5).
- **Understands** your activity with local models: hierarchical summaries
(hour → day → week), a knowledge graph of people/projects/tools, and a
distilled wiki + identity profile.
- **Assists**: chat with your own memory, morning brief / evening wrap, and an
inline "write in my voice" rewrite that learns your style per surface.
- **Fits your machine**: four independently-configurable model slots, and a
setup wizard that recommends the right model for each based on your actual
hardware — see [Pick a model](#pick-a-model-that-fits-your-mac) below.
- **Integrates** with MCP clients so Claude can query your local memory.
## Privacy by construction
- The **only** code that makes an outbound request is `crates/ai/src/ollama.rs`,
and it refuses any endpoint that is not loopback (`ensure_local`).
- The MCP server binds to `127.0.0.1` only.
- Password managers, banks, and login/oauth/checkout/private-browsing pages are
blacklisted from capture by default; secret-shaped strings are redacted before
anything is written. Configure both in `~/.silverfish/config.toml`.
## Architecture
```
┌───────────────────────────────────────────┐
Claude Desktop/Code ──▶ │ silverfish-mcp (stdio↔HTTP proxy) │
└───────────────┬───────────────────────────┘
│ JSON-RPC over 127.0.0.1:3333
┌───────────────▼───────────────────────────┐
macOS AX APIs ─────▶ │ silverfishd │
(capture) │ capture · scheduler · MCP server │
└───────┬───────────────────────┬───────────┘
│ │
┌──────────▼─────────┐ ┌──────────▼──────────┐
│ silverfish-core │ │ silverfish-ai │
│ SQLite · config │ │ Ollama (127.0.0.1) │
└────────────────────┘ └─────────────────────┘
```
| Crate | Role |
|-------|------|
| `silverfish-core` | Config, SQLite schema + access layer, models, redaction |
| `silverfish-ai` | Local Ollama client + the one-method-per-capability engine |
| `silverfish-daemon` (`silverfishd`) | Capture, scheduler, and the local MCP server |
| `silverfish-cli` (`silverfish`) | Terminal access to your memory |
| `silverfish-mcp` | Generic stdio↔HTTP MCP bridge for Claude clients |
| `silverfish-bar` (`silverfish-bar`) | Menu-bar app: right-Option inline rewrite + local chat popover |
## Prerequisites
Before you build anything:
- **macOS (Apple Silicon).** silverfish's capture and menu-bar app are built on
macOS-only Accessibility APIs.
- **Rust, via [rustup](https://rustup.rs).** The workspace's declared minimum
is 1.85 (`Cargo.toml`'s `rust-version`), but this repo is developed and
tested against 1.95 (see `.tool-versions`) — installing current stable Rust
through rustup satisfies both.
- **Xcode Command Line Tools** — `xcode-select --install` is sufficient; you
do not need the full Xcode app.
- **[Ollama](https://ollama.com), installed *and running*** (`ollama serve`,
or just launch the Ollama.app from your Applications folder). silverfish
talks to it over `127.0.0.1:11434` and does nothing useful without it.
## Pick a model that fits your Mac
silverfish doesn't ship with one blessed model. It runs across four
independently-configurable slots — `fast`, `chat`, `summarize`, `heavy` (see
`OllamaConfig` in `crates/core/src/config.rs`) — and any model Ollama can serve
can go in any slot. What matters is picking sizes your Mac can actually run
well.
### Recommended: let `silverfish onboard` pick
`silverfish onboard` detects your Mac's RAM and chip, matches it against a
maintained hardware-tier cookbook, and recommends (and can pull + apply) a
model set sized for *that* machine — so an 8–16 GB Mac isn't steered onto a
23 GB model that will crawl or fail to load, and a workstation isn't left on
a small model out of undue caution.
```sh
./target/release/silverfish onboard # dry run: detect + recommend, print what it'd do
./target/release/silverfish onboard --pull --apply # fetch and write the recommendation into your config
```
(You'll need to have built silverfish first — see [Quickstart](#quickstart-the-menu-bar-app)
below.) See [`docs/onboarding.md`](docs/onboarding.md) for the full cookbook
table and how to override any slot by hand.
### Manual: pull the defaults yourself
If you'd rather choose tags yourself, or you're on a machine the hardware
probe can't read, silverfish's out-of-the-box defaults span three distinct
Ollama tags:
```sh
ollama pull llama3.2:3b # fast: extraction, classification
ollama pull qwen3.5:9b # chat + summarize (one tag, covers both slots)
ollama pull qwen3.6:35b # heavy: deepest weekly/monthly synthesis (~23 GB alone)
```
Pulling all three gets you the full default configuration and costs roughly
**33 GB of disk** in total. These are only the shipped defaults, not a
requirement — edit `[ollama]` in `~/.silverfish/config.toml` to point any slot
at a smaller, larger, or entirely different model you've already pulled.
## Quickstart: the menu-bar app
This is the actual product: a tray icon with a right-Option inline rewrite
assistant and a local chat popover. Build, package, and launch it:
```sh
cargo build --release
scripts/make-dev-cert.sh # once, optional but recommended — read it first
scripts/package-app.sh
open dist/Silverfish.app
```
`scripts/make-dev-cert.sh` creates a stable, self-signed local signing
identity. It's what makes the Accessibility grant below survive future
rebuilds — see [Troubleshooting](#troubleshooting) and
[`docs/dev/packaging.md`](docs/dev/packaging.md) for exactly why. Skipping it
still produces a working app (`package-app.sh` falls back to ad-hoc signing
with a warning), but every rebuild then gets a new identity and macOS resets
the grant, so you'll re-grant Accessibility after every
`cargo build --release` + `package-app.sh` cycle.
### Grant permissions
On first launch, silverfish pre-registers itself in **System Settings ▸
Privacy & Security ▸ Accessibility** — turn its toggle on. That's the
**only** permission it asks for; Input Monitoring is *not* required, because
the right-Option trigger polls modifier-key state instead of installing a
system-wide event tap. Accessibility is used solely to read the focused
field's text and paste the rewritten result back in.
If the tray shows a "↻ Relaunch silverfish to finish setup" banner right
after you grant it, click it — a grant made after the process already
started only takes effect on the next launch, and the app relaunches itself
for you.
### Use it
- **Tap right-Option** while a text field is focused to rewrite the selected
text — or the whole field, if nothing's selected — in your own learned
voice. Tap right-Option again right after a rewrite lands to say "not
quite, try again"; it'll give you a different take.
- **Open the chat popover** from the tray icon to ask your local memory a
question, or get a morning brief / evening wrap — all answered by the
local model, entirely offline.
- **Pause capture** any time from the tray menu.
### Troubleshooting
- **"Silverfish.app cannot be opened because it is from an unidentified
developer."** Expected for an unsigned/ad-hoc build. Go to **System
Settings ▸ Privacy & Security**, find the blocked-app notice, and click
**Open Anyway**. On macOS 15 (Sequoia) and later, that button sometimes
only appears *after* a first failed launch attempt.
- **A second `silverfishd` entry appears in the Accessibility list.**
silverfish bundles a background daemon alongside the tray app; depending on
macOS's process-attribution behavior, the daemon can show up as its own
line item ("Silverfish" *and* "silverfishd") rather than being covered by
one grant — both need the toggle switched on. If capture doesn't seem to be
running after granting Accessibility once, check for a second entry. See
[`docs/dev/packaging.md`](docs/dev/packaging.md).
- **Accessibility resets every time you rebuild.** You skipped
`scripts/make-dev-cert.sh`. Ad-hoc signing ties the grant to that exact
build's bytes, so any recompile invalidates it; run `make-dev-cert.sh` once
and repackage to make the grant persist across rebuilds.
## Advanced: CLI & headless daemon
Everything above is optional if you'd rather not run a menu-bar app at all —
the daemon and CLI work standalone:
```sh
cargo build --release
# One-off checks
./target/release/silverfish status
./target/release/silverfish ask "what was I working on yesterday?"
./target/release/silverfish search "auth migration"
./target/release/silverfish brief morning
# Run the daemon (capture + scheduler + MCP server on 127.0.0.1:3333)
./target/release/silverfishd run
```
On first run, grant **Accessibility** permission when prompted (System
Settings → Privacy & Security → Accessibility), then relaunch. As with the
packaged app, a bare ad-hoc-signed binary loses that grant on every rebuild —
see [Troubleshooting](#troubleshooting).
## Connect Claude clients (drop-in MCP)
If you're running the packaged app, `silverfishd` is already up (the tray app
supervises it as a child process) and its MCP server is listening on
`127.0.0.1:3333`. Point your MCP client at the proxy binary, in the standard
shape MCP clients expect:
```json
{
"mcpServers": {
"silverfish": { "command": "/path/to/target/release/silverfish-mcp" }
}
}
```
Tools exposed: `search_memory`, `recent_activity`, `ask_memory`, `get_briefing`,
`list_entities`, `search_wiki`, `write_in_my_voice`, `get_identity`.
## Configuration
`~/.silverfish/config.toml` (create with `silverfish config init`). Key knobs:
`db_path` (automatically adopts a pre-existing local memory database from a
previous similar app, if found), `mcp_port`,
`capture_interval_ms`, `redact_sensitive`, `[ollama]` base URL + per-task model
routing, and the `[[capture_blacklist]]` rules.
## Development
```sh
cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings # pedantic + nursery, zero warnings
cargo test --workspace
```
See `docs/dev/` for the macOS capture reference, the MCP contract, bar-app
behavior notes, and [`packaging.md`](docs/dev/packaging.md) for the `.app`
bundle layout and signing details.
## License
Apache-2.0. See [LICENSE](LICENSE).
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
No recommendations available