docs: update README for Linux support, Qdrant backend, and portable systemd unit

This commit is contained in:
Apunkt 2026-05-12 16:58:32 +02:00
parent 8a116d270c
commit 01e5903035
No known key found for this signature in database
2 changed files with 38 additions and 8 deletions

View file

@ -9,7 +9,7 @@
<p align="center"> <p align="center">
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a> <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a>
<img src="https://img.shields.io/badge/python-3.11%20%7C%203.12-blue.svg" alt="Python 3.11 | 3.12"> <img src="https://img.shields.io/badge/python-3.11%20%7C%203.12-blue.svg" alt="Python 3.11 | 3.12">
<img src="https://img.shields.io/badge/platform-macOS-lightgrey.svg" alt="Platform: macOS"> <img src="https://img.shields.io/badge/platform-macOS%20%7C%20Linux-lightgrey.svg" alt="Platform: macOS | Linux">
</p> </p>
<p align="center"> <p align="center">
<img src="https://img.shields.io/badge/verbatim%20recall-%E2%89%A599%25%20at%2010k-brightgreen.svg" alt="Verbatim recall >= 99%"> <img src="https://img.shields.io/badge/verbatim%20recall-%E2%89%A599%25%20at%2010k-brightgreen.svg" alt="Verbatim recall >= 99%">
@ -17,6 +17,7 @@
<img src="https://img.shields.io/badge/encryption-AES--256--GCM-green.svg" alt="AES-256-GCM"> <img src="https://img.shields.io/badge/encryption-AES--256--GCM-green.svg" alt="AES-256-GCM">
<img src="https://img.shields.io/badge/local--only-no%20telemetry-green.svg" alt="Local only, no telemetry"> <img src="https://img.shields.io/badge/local--only-no%20telemetry-green.svg" alt="Local only, no telemetry">
<img src="https://img.shields.io/badge/MCP-compatible-purple.svg" alt="MCP compatible"> <img src="https://img.shields.io/badge/MCP-compatible-purple.svg" alt="MCP compatible">
<img src="https://img.shields.io/badge/backend-LanceDB%20%7C%20Qdrant-blue.svg" alt="Backend: LanceDB | Qdrant">
</p> </p>
--- ---
@ -56,14 +57,12 @@ I built this for myself. It worked. I've been running it daily for months, and n
### Prerequisites ### Prerequisites
- macOS (Apple Silicon tested) - macOS (Apple Silicon tested) or Linux
- Python 3.11 or 3.12 - Python 3.11 or 3.12
- Node.js 18+ - Node.js 18+
- [Claude Code](https://docs.claude.com/en/docs/claude-code/overview) as the MCP host - [Claude Code](https://docs.claude.com/en/docs/claude-code/overview) as the MCP host
- ~500 MB free disk - ~500 MB free disk
Windows and Linux not supported yet but I'm working on it.
### Install ### Install
```bash ```bash
@ -72,7 +71,7 @@ cd iai-mcp
bash scripts/install.sh bash scripts/install.sh
``` ```
The installer creates a Python venv, installs dependencies (LanceDB, sentence-transformers, torch-hd, NetworkX, igraph), builds the TypeScript MCP wrapper, pre-downloads the default embedding model (~130 MB), symlinks the CLI to `~/.local/bin/iai-mcp`, and on macOS registers the daemon with launchd. The installer creates a Python venv at `~/.venv/iai-mcp`, installs dependencies (LanceDB, sentence-transformers, torch-hd, NetworkX, igraph), builds the TypeScript MCP wrapper, pre-downloads the default embedding model (~130 MB), symlinks the CLI to `~/.local/bin/iai-mcp`, and on macOS registers the daemon with launchd. On Linux, install the systemd unit from `deploy/systemd/iai-mcp-daemon.service`.
Make sure `~/.local/bin` is on your `PATH`: Make sure `~/.local/bin` is on your `PATH`:
@ -149,6 +148,21 @@ tail ~/.iai-mcp/logs/capture-$(date -u +%Y-%m-%d).log
You should see a `rc=0` line. That's your first memory. You should see a `rc=0` line. That's your first memory.
### Linux (systemd)
Install the systemd user unit:
```bash
mkdir -p ~/.config/systemd/user
cp deploy/systemd/iai-mcp-daemon.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now iai-mcp-daemon.service
```
For survival past logout (headless servers): `loginctl enable-linger $USER`
Check status: `systemctl --user status iai-mcp-daemon.service`
--- ---
## Usage ## Usage
@ -185,8 +199,14 @@ All records are encrypted at rest with AES-256-GCM. The key lives in `~/.iai-mcp
Everything lives at `~/.iai-mcp/`. Embeddings are computed locally with `bge-small-en-v1.5`. The only data that leaves the machine is your normal conversation with whatever LLM API your client uses. Everything lives at `~/.iai-mcp/`. Embeddings are computed locally with `bge-small-en-v1.5`. The only data that leaves the machine is your normal conversation with whatever LLM API your client uses.
### Storage backends
The default backend is **LanceDB** (embedded, zero-config, local). For larger deployments or multi-machine setups, an optional **Qdrant** backend is available. Set `QDRANT_URL` to enable it — the system auto-selects the backend via a factory function.
Migrate from LanceDB to Qdrant: `iai-mcp migrate qdrant`
``` ```
Claude Code <--MCP-stdio--> TypeScript wrapper <--UNIX socket--> Python daemon <--> LanceDB Claude Code <--MCP-stdio--> TypeScript wrapper <--UNIX socket--> Python daemon <--> LanceDB / Qdrant
``` ```
--- ---
@ -224,9 +244,19 @@ The LongMemEval-S run is blind on purpose. No dataset-specific tuning, no hyperp
|---|---|---| |---|---|---|
| `IAI_MCP_STORE` | `~/.iai-mcp/` | Data directory | | `IAI_MCP_STORE` | `~/.iai-mcp/` | Data directory |
| `IAI_MCP_EMBED_MODEL` | `bge-small-en-v1.5` | Embedding model. `bge-m3` for multilingual at ~3x size. | | `IAI_MCP_EMBED_MODEL` | `bge-small-en-v1.5` | Embedding model. `bge-m3` for multilingual at ~3x size. |
| `QDRANT_URL` | _(unset)_ | Qdrant server URL. When set, uses Qdrant backend instead of LanceDB. |
| `QDRANT_API_KEY` | _(unset)_ | Qdrant API key |
Switching embedders requires re-embedding the store: `iai-mcp migrate reembed`. Switching embedders requires re-embedding the store: `iai-mcp migrate reembed`.
### Non-AVX CPUs
If your CPU lacks AVX support, rebuild the venv with the CPU-only PyTorch wheel:
```bash
bash scripts/rebuild-venv.sh
```
--- ---
## Doctor ## Doctor
@ -302,7 +332,7 @@ Claude Desktop should work (uses `claude_desktop_config.json` instead of `~/.cla
Other MCP-over-stdio hosts speak the same protocol and should work in principle. Not tested. Other MCP-over-stdio hosts speak the same protocol and should work in principle. Not tested.
If you get it running on something else, open an issue or PR. Linux support via systemd is available. macOS via launchd.
--- ---

View file

@ -16,7 +16,7 @@ After=default.target
[Service] [Service]
Type=simple Type=simple
ExecStart=/home/andreas/.venv/iai-mcp/bin/python -m iai_mcp.daemon ExecStart=%h/.venv/iai-mcp/bin/python -m iai_mcp.daemon
Restart=on-failure Restart=on-failure
RestartSec=30 RestartSec=30
StartLimitIntervalSec=60 StartLimitIntervalSec=60