# USB Exobrain — Step-by-Step Test Recipe > Goal: put a KeiSeiKit "brain" on a physical USB drive or flash card, mount it into Claude Code (and Cursor / Continue / Zed if installed), verify MCP tools are live, unplug — verify clean detach. > > Target audience: someone trying the v0.21 exobrain feature for the first time on macOS (adapt paths for Linux). --- ## 0. Prerequisites On the host (your laptop): - KeiSeiKit installed: `./install.sh --profile=full` ran successfully, `cargo test -p keisei` shows 28/28 pass. - `keisei` CLI on PATH: `ls ~/.claude/agents/_primitives/_rust/target/release/keisei` returns the binary. Optionally `ln -sf ~/.claude/agents/_primitives/_rust/target/release/keisei ~/.local/bin/keisei` so you can just type `keisei`. - Claude Code installed (or Cursor / Continue / Zed — the CLI auto-detects all four). - A USB stick or flash card mounted on macOS — expected path `/Volumes/` (e.g. `/Volumes/EXOBRAIN`). On the USB drive: - Filesystem: exFAT or APFS (not HFS+ if you want cross-platform). FAT32 works but has 4 GB per-file limit — fine for brain dir (< 200 MB total even with 5 platform binaries). - Free space: ~500 MB recommended (5 mcp-server binaries × ~90 MB each = ~450 MB, plus room for memory/artifacts SQLite). --- ## 1. Create the brain directory Replace `EXOBRAIN` with your actual USB volume name. ```bash BRAIN=/Volumes/EXOBRAIN/my-brain mkdir -p "$BRAIN"/{bin,memory,artifacts,manifests} ``` Structure after step 1: ``` /Volumes/EXOBRAIN/my-brain/ ├── bin/ ├── memory/ ├── artifacts/ └── manifests/ ``` --- ## 2. Download MCP server binaries for every platform Grab the 5 single-binary compiles from the latest GitHub release. For v0.21.0: ```bash BASE=https://github.com/KeiSei84/KeiSeiKit/releases/download/v0.21.0 cd "$BRAIN/bin" # macOS Apple Silicon curl -fL -O "$BASE/kei-mcp-server-darwin-arm64" curl -fL -O "$BASE/kei-mcp-server-darwin-arm64.sha256" # macOS Intel curl -fL -O "$BASE/kei-mcp-server-darwin-x64" curl -fL -O "$BASE/kei-mcp-server-darwin-x64.sha256" # Linux x86_64 curl -fL -O "$BASE/kei-mcp-server-linux-x64" curl -fL -O "$BASE/kei-mcp-server-linux-x64.sha256" # Linux arm64 (may be unavailable on older releases — continue-on-error in CI) curl -fL -O "$BASE/kei-mcp-server-linux-arm64" 2>/dev/null || echo "skipped linux-arm64" # Windows x86_64 curl -fL -O "$BASE/kei-mcp-server-windows-x64.exe" curl -fL -O "$BASE/kei-mcp-server-windows-x64.exe.sha256" # Verify every downloaded binary against its .sha256 for f in kei-mcp-server-*.sha256; do shasum -a 256 -c "$f" || echo "FAIL: $f" done # Strip macOS Gatekeeper quarantine + chmod +x on Unix binaries chmod +x kei-mcp-server-darwin-* kei-mcp-server-linux-* 2>/dev/null || true xattr -d com.apple.quarantine kei-mcp-server-darwin-* 2>/dev/null || true ``` Expected: every `shasum -c` prints `OK`. --- ## 3. Write `manifest.toml` (schema v2, per-platform) ```bash cat > "$BRAIN/manifest.toml" <<'EOF' [brain] schema_version = 2 name = "my-brain" created = "2026-04-22T00:00:00Z" [paths] memory = "memory/" artifacts = "artifacts/" manifests = "manifests/" [paths.mcp_server] darwin-arm64 = "bin/kei-mcp-server-darwin-arm64" darwin-x64 = "bin/kei-mcp-server-darwin-x64" linux-x64 = "bin/kei-mcp-server-linux-x64" linux-arm64 = "bin/kei-mcp-server-linux-arm64" windows-x64 = "bin/kei-mcp-server-windows-x64.exe" EOF ``` Validation: `keisei` rejects the brain if `name` contains anything outside `^[a-z][a-z0-9_-]{0,63}$`, if any path is absolute, if any path contains `..`, or if the root is a symlink. --- ## 4. Verify the brain loads before attaching ```bash keisei list-adapters ``` Expected: 2-column table showing every adapter, `detected: yes` for at least `claude-code` (the others depend on whether Cursor / Continue / Zed are installed on this host). If you want a dry-run of the brain itself without touching any client config: ```bash # Loads manifest, validates path confinement + schema — then errors because # nothing attached yet. Use the error to confirm load-path is clean. keisei status # Expected: "no brain attached" ``` --- ## 5. Attach the brain to Claude Code Single-client, user scope (the safe default): ```bash keisei attach "$BRAIN" --scope=user ``` Expected output (literally): ``` attached brain 'my-brain' to claude-code (user scope) brain path: /Volumes/EXOBRAIN/my-brain mcp server: /Volumes/EXOBRAIN/my-brain/bin/kei-mcp-server-darwin-arm64 client cfg: /Users/you/.claude/settings.json marker: /Users/you/.keisei/attached.toml run /help in Claude Code to verify the MCP server is reachable ``` The last line is the client-specific post-attach hint. Each adapter emits its own. --- ## 6. Verify in Claude Code Close and reopen Claude Code (or run `/help` → "MCP servers" section). You should see `my-brain` listed with the `/Volumes/EXOBRAIN/my-brain/bin/kei-mcp-server-darwin-arm64` command. ```bash # On the host, inspect what just got written: cat ~/.claude/settings.json | jq '.mcpServers["my-brain"]' # Expected: # { # "command": "/Volumes/EXOBRAIN/my-brain/bin/kei-mcp-server-darwin-arm64", # "env": { # "KEISEI_BRAIN_ROOT": "/Volumes/EXOBRAIN/my-brain" # } # } ``` Run a Claude Code command that uses a tool from kei-mcp-server (any of the 25+ MCP tool endpoints). If Claude Code reports success, the brain is live. --- ## 7. Multi-client mount (all detected clients at once) ```bash keisei mount "$BRAIN" ``` Fan-out attach to every client detected on this host. For each, writes to user-scope config (`~/.claude/settings.json`, `~/.cursor/mcp.json`, `~/.continue/config.json`, `~/Library/Application Support/Zed/settings.json`). Expected summary: ``` mounted brain 'my-brain' to: claude-code ✓ cursor ✓ continue ✗ (not detected) zed ✓ ``` --- ## 8. Project-scope attach (Claude Code / Cursor only) Useful for per-project brains that stay with the repo: ```bash cd ~/path/to/your-repo keisei attach "$BRAIN" --scope=project ``` Writes to `./.claude/settings.json` (inside the repo) instead of `~/.claude/`. Continue and Zed reject this scope with a clear error — they don't have per-project MCP config. --- ## 9. Verify brain health ```bash keisei status ``` Expected: ``` attached: my-brain brain path: /Volumes/EXOBRAIN/my-brain attached at: 2026-04-22T17:30:00Z clients: - claude-code (user scope) ~/.claude/settings.json - cursor (user scope) ~/.cursor/mcp.json - zed (user scope) ~/Library/Application Support/Zed/settings.json health: OK (manifest readable, mcp_server binary exists) ``` If you unplug the USB, re-run `keisei status`: ``` health: WARN — mcp_server binary at is not reachable (brain was mounted at /Volumes/EXOBRAIN/my-brain, which no longer exists) ``` --- ## 10. Detach — clean up when done ```bash keisei detach ``` Strips the `mcpServers.my-brain` entry from every client's config (preserving any other MCP servers you have configured), then deletes the marker. Expected: ``` detached 'my-brain' from: claude-code ✓ cursor ✓ zed ✓ marker removed: ~/.keisei/attached.toml ``` Confirm: ```bash keisei status # → "no brain attached" jq '.mcpServers' ~/.claude/settings.json # → your own entries only ``` --- ## 11. Eject the USB safely ```bash # macOS: diskutil eject /Volumes/EXOBRAIN # Linux: umount /media/$USER/EXOBRAIN ``` Physically unplug. --- ## Troubleshooting ### "BrainNotFound" on attach - Check `/Volumes/EXOBRAIN/my-brain/manifest.toml` exists - Check the path to `keisei attach` is absolute (`/Volumes/...`), not relative ### "PathEscape" on attach - Every path under `[paths]` must be relative and resolve inside the brain root. No `../`, no absolute paths. ### "BrainIsSymlink" on attach - `/Volumes/EXOBRAIN/my-brain` is a symlink to elsewhere. Pass the real resolved path instead — `keisei` refuses symlink roots to prevent accidental host-dir pivot via crafted USB. ### "NoPlatformBinary" on Claude Code first-use - Your platform's binary isn't in `bin/`. Check `std::env::consts::{OS, ARCH}` on your host — the expected filename is `kei-mcp-server--` where macos→darwin, x86_64→x64, aarch64→arm64. ### Claude Code can't spawn the MCP server - Ensure `chmod +x` applied to the binary - On macOS: `xattr -d com.apple.quarantine ` to clear Gatekeeper - Check the binary actually runs standalone: `/Volumes/EXOBRAIN/my-brain/bin/kei-mcp-server-darwin-arm64 --help` ### "NameConflict" on attach - Another MCP server with the same name already exists in the client's config. Either rename your brain (`name` in manifest.toml) or remove the existing entry manually. --- ## What this tests end-to-end 1. **Portable brain** — works from read-only USB, no installer needed on the brain itself 2. **Per-platform dispatch** — schema v2 picks the right binary based on host OS+arch 3. **Multi-client fan-out** — `keisei mount` attaches to every detected client in one call 4. **Clean detach** — zero residue in host configs, preserves unrelated MCP servers 5. **Safety gates** — path confinement, name regex, symlink rejection, size bound (64 KiB manifest cap) 6. **Schema v1 compat** — drop in an older v1 brain with a single-string mcp_server, still works If all 11 steps above pass, the v0.21 exobrain is production-ready for single-user workflows. For shared-brain scenarios (team members all mounting the same brain over git / S3) see the `kei-store` backend docs — S3 backend via `keisei attach s3://my-bucket/brain/` (requires `--features s3` at install).