Local-first observability for your computer. Patcha runs as a background daemon, collects activity from your browser, terminal, git, and screen, stores it in a local vector database, and lets you query it semantically — from the CLI or as an MCP tool inside Claude and other MCP clients.
Everything stays on your machine. Embeddings and screen understanding run
on-device; the only network calls are optional (LLM summarization, which can
also run through a local claude CLI — see LLM backend).
Platform: macOS only. Patcha relies on macOS Accessibility, Screen Recording, and Vision (OCR) APIs.
- Daemon (
patcha daemon) polls activity sources on a configurable interval and writes events to a local SQLite database. - Collectors pull from browser history, shell history, git (commits/stashes/staging), and the active window/screen via macOS Accessibility + OCR. See docs/collectors.md.
- Perception filters redundant frames and captions screenshots on-device (FastVLM gist + MobileCLIP visual prefilter) so retrieval works on what you were doing, not just literal on-screen text.
- Embedding turns events into vectors with a local fastembed model (BGE). No API key required. See docs/embedding.md.
- Storage & retrieval live in SQLite with the
sqlite-vecextension for approximate-nearest-neighbor search, plus a knowledge graph for structural queries. See docs/retrieval/retrieval.md. - Compaction nightly folds raw events into structured tasks and prunes the store. See docs/compaction.md.
- MCP server (
patcha mcp) exposes retrieval as tools for Claude or any MCP client. See docs/retrieval/mcp.md.
The core is written in Rust (rust/patcha). A native macOS menu bar app
(swift-xcode/) manages the daemon so you never need a terminal.
- macOS (Apple Silicon or Intel)
- Rust (stable) to build the CLI/daemon
- Xcode or the Xcode Command Line Tools (for the Swift helper binaries and the menu bar app)
- Optional: the
claudeCLI installed and logged in, to run AI features (summaries, categorization, chat) fully locally without a patcha account
No OpenAI key and no external vector database are required — embeddings and the vector store are local.
Clone and build the CLI:
git clone https://github.com/xtanion/patcha.git
cd patcha/rust
cargo build --release
# binary at rust/target/release/patchaBuild the Swift helper binaries (Accessibility, OCR, visual embedder, window observer) that the daemon shells out to:
bash build.shbuild.sh compiles the Swift helpers, builds the Rust release binary, and (if
Xcode is present) packages the menu bar app into dist/Patcha.app.
Install the git hooks (commit-message linting + test run):
bash scripts/install-hooks.shThe screen/window collectors need Accessibility and Screen Recording
access. Grant them under System Settings → Privacy & Security. The menu bar
app requests these on first run; if you run the CLI directly, add your terminal
(or the patcha binary) to both lists.
Start the background daemon:
patcha daemonRun a one-off collection cycle without the daemon:
patcha collectSearch your activity semantically:
patcha search "sqlite-vec setup"Summarize a day, or review a range:
patcha summarize
patcha review --from 2026-08-01 --to 2026-08-07Run patcha --help or patcha <command> --help for full options.
Categorization, summaries, compaction, and chat use an LLM. Patcha picks the backend automatically:
- No login (default): requests run through your local
claudeCLI — nothing leaves your machine beyond what the CLI itself sends. - Signed in (
patcha login): requests route through patcha-api.
Override with the PATCHA_LLM_BACKEND environment variable:
| Value | Behavior |
|---|---|
auto |
(default) use claude when there is no token, else API |
claude |
always use the local claude CLI |
api |
always use patcha-api (requires patcha login) |
Collection, embedding, storage, and search never require a login or network.
| Command | Description |
|---|---|
daemon |
Run the background collector + processing loop |
mcp |
Run the MCP server (stdio or HTTP) |
collect |
Run one collection cycle from all sources |
observe |
Collect and cluster without calling an LLM |
search <query> |
Semantic search over activity history |
review |
Review activity over a date range |
summarize |
Generate a written daily summary |
cluster / patterns |
Cluster activity / find recurring patterns |
tasks |
List identified tasks |
task-details <id> |
Show full detail for a task |
compact-day |
Manually compact a past date into tasks |
rag-summary |
RAG-enhanced summary |
analyze-graph |
Analyze the activity knowledge graph |
login / logout |
Sign in / out of patcha-api (optional) |
reembed / migrate |
Maintenance: re-embed events / migrate old data |
Run patcha --help for the complete list.
The MCP server exposes six read-only tools: get_working_memory,
get_recent_activity, search_activity, get_activity_context,
get_session, and find_connected.
Add to your MCP client config (e.g. claude_desktop_config.json):
{
"mcpServers": {
"patcha": {
"command": "/path/to/patcha",
"args": ["mcp", "--stdio"]
}
}
}For HTTP transport: patcha mcp --port 6969.
See docs/retrieval/mcp.md for full tool documentation.
Patcha reads configuration from environment variables (and, if present,
~/.patcha/.env / .env in the working directory). Common variables:
| Variable | Default | Description |
|---|---|---|
PATCHA_DB_PATH |
~/.patcha/patcha.db |
SQLite database path |
DATA_DIR |
~/.patcha/data |
JSONL logs and snapshots |
EMBEDDING_MODEL |
BAAI/bge-base-en-v1.5 |
Local fastembed model |
EMBEDDING_CACHE_DIR |
~/.patcha/models |
Where embedding models are cached |
POLL_INTERVAL |
60 |
Seconds between collection cycles |
ENABLE_*_COLLECTOR |
true |
Toggle git/browser/terminal/window/AX |
PATCHA_LLM_BACKEND |
auto |
auto / claude / api |
LOG_LEVEL / RUST_LOG |
info |
Logging verbosity |
See rust/patcha/src/config.rs for the full list of tunables.
cd rust
cargo build
cargo test # some collector tests need macOS GUI permissions
cargo clippy --all-targets
cargo fmt --allCI runs fmt --check, clippy -D warnings, and build on macOS. The
cargo test suite is run locally via the pre-commit hook because several tests
exercise OCR / Accessibility and need a real GUI session.
Commits must follow type: description, where type is one of:
feat:— new featurefix:— bug fixchore:— maintenance, deps, tooling
Scope is optional: feat(cli): add --json flag. The commit-msg hook enforces
this — install hooks with bash scripts/install-hooks.sh.
See CONTRIBUTING.md for the full contributor guide.
| Topic | File |
|---|---|
| Collectors (browser, terminal, git, screen) | docs/collectors.md |
| Embedding pipeline | docs/embedding.md |
| Retrieval (working memory, search) | docs/retrieval/retrieval.md |
| MCP server | docs/retrieval/mcp.md |
| RAG & knowledge graph | docs/retrieval/rag.md |
| Daily compaction | docs/compaction.md |
MIT © the Patcha authors.