{"id":50467079,"url":"https://github.com/n0mad-ai/bastra-recall","last_synced_at":"2026-06-01T08:00:57.260Z","repository":{"id":354766641,"uuid":"1225075047","full_name":"n0mad-ai/bastra-recall","owner":"n0mad-ai","description":"Local-first persistent memory for Claude Code, Cursor, ChatGPT \u0026 every MCP client — one Markdown vault, shared across every AI tool.","archived":false,"fork":false,"pushed_at":"2026-06-01T06:47:02.000Z","size":1950,"stargazers_count":3,"open_issues_count":20,"forks_count":5,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-01T07:08:48.423Z","etag":null,"topics":["agent","ai","anthropic","claude","claude-code","claude-desktop","cursor","llm","local-first","markdown","mcp","memory","model-context-protocol","obsidian","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/n0mad-ai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-29T23:27:57.000Z","updated_at":"2026-06-01T06:47:51.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/n0mad-ai/bastra-recall","commit_stats":null,"previous_names":["danielautoland/nexus-recall","danielautoland/bastra-recall"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/n0mad-ai/bastra-recall","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n0mad-ai%2Fbastra-recall","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n0mad-ai%2Fbastra-recall/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n0mad-ai%2Fbastra-recall/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n0mad-ai%2Fbastra-recall/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/n0mad-ai","download_url":"https://codeload.github.com/n0mad-ai/bastra-recall/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/n0mad-ai%2Fbastra-recall/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33765379,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-01T02:00:06.963Z","response_time":115,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent","ai","anthropic","claude","claude-code","claude-desktop","cursor","llm","local-first","markdown","mcp","memory","model-context-protocol","obsidian","typescript"],"created_at":"2026-06-01T08:00:33.304Z","updated_at":"2026-06-01T08:00:57.253Z","avatar_url":"https://github.com/n0mad-ai.png","language":"TypeScript","funding_links":["https://github.com/sponsors/n0mad-ai"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./assets/github-banner.png\" alt=\"Bastra — the open memory layer for AI assistants and agents\" width=\"100%\" /\u003e\n\u003c/p\u003e\n\n# Bastra.Recall\n\n\u003e A persistent teammate memory for any AI assistant — across every surface.\n\u003e Ein persistentes Teammate-Gedächtnis für jeden AI-Assistenten — über jede Oberfläche hinweg.\n\n[![License: MIT](https://img.shields.io/github/license/n0mad-ai/bastra-recall?color=blue)](./LICENSE)\n[![GitHub stars](https://img.shields.io/github/stars/n0mad-ai/bastra-recall?style=flat\u0026color=yellow)](https://github.com/n0mad-ai/bastra-recall/stargazers)\n[![GitHub issues](https://img.shields.io/github/issues/n0mad-ai/bastra-recall)](https://github.com/n0mad-ai/bastra-recall/issues)\n[![Last commit](https://img.shields.io/github/last-commit/n0mad-ai/bastra-recall)](https://github.com/n0mad-ai/bastra-recall/commits/main)\n[![TypeScript](https://img.shields.io/badge/built%20with-TypeScript-3178c6)](https://www.typescriptlang.org/)\n[![MCP](https://img.shields.io/badge/MCP-compatible-orange)](https://modelcontextprotocol.io/)\n[![Sponsor](https://img.shields.io/github/sponsors/n0mad-ai?label=sponsor\u0026color=ea4aaa\u0026logo=github)](https://github.com/sponsors/n0mad-ai)\n\n---\n\n## 🇬🇧 English\n\n**What it is** — A long-term memory for any AI assistant or agent: Claude (Code, Desktop, Web), ChatGPT (via Custom GPT Actions), Cursor, and anything else that speaks MCP or HTTP. Whenever you correct it, state a rule, or commit to a decision, it gets saved as a small note. In your next chat — days or weeks later, in any tool — the AI pulls those notes back automatically. No more repeating yourself. Everything stays on your own Mac as plain Markdown files (Obsidian-compatible). All your AI tools share the same memory at the same time.\n\n**Status** — 🟢 Early beta. M0 (eval) and M1 (read path) done, M2 (save path) functional, and the Claude Code reflex layer ships with hooks for `SessionStart`, `UserPromptSubmit`, `PreToolUse` file edits / todos / bash safety, `PostToolUse` bash failures, plus optional `Stop` save-eval. Distribution and multi-surface hardening are active. See [PLAN.md](./PLAN.md).\n\n### Why\n\nWorking with an AI assistant over months means re-explaining the same things. Pitfalls it already learned in one project recur in the next. Stable preferences (*\"give me a recommendation, not a 5-option menu\"*) get forgotten between sessions. Project-specific facts get re-discovered every time.\n\nMost AI tools have memory features, but they're **passive**: a static index file at best, no proactive recall, no cross-surface continuity.\n\nThe cost isn't just frustration — it's that the user ends up thinking *for* the AI. *\"Wait, didn't we solve this last week?\"* That's the bug.\n\n### What bastra-recall does\n\nA persistent memory layer that:\n\n- **Saves autonomously** — when a lesson is learned (frustration, repeated correction, durable preference, finalized decision), the AI writes it to the vault without being asked. Trigger discipline ships as a Claude Code Skill; other clients are conditioned through their own system prompt or Custom GPT instructions.\n- **Recalls before acting** — not only when the user prompts. The AI is instructed to query the vault before writing code, before plans, and at session start. The highest-weighted search field is `recall_when`, declared at save time.\n- **Works across surfaces** — one local daemon serves all your AI tools at once: Claude Code (via MCP), Claude Desktop (via MCP), ChatGPT (via Custom GPT Actions over HTTP), Cursor, and anything else that speaks MCP or HTTP.\n- **Plain markdown, Obsidian-compatible** — the vault is a folder of `.md` files with YAML frontmatter. Edit in Obsidian, in the AI, or by hand. Vaults on Google Drive / iCloud / Dropbox mounts are supported via automatic polling-mode in the file watcher.\n\n### The single success metric\n\n\u003e **The user doesn't have to think for the AI anymore.**\n\nIf recurring mistakes still recur, if the user still has to re-state preferences each session — the project failed, regardless of how clean the architecture is.\n\n### How it works\n\n```\nVault (configurable, plain markdown + YAML frontmatter, Obsidian-compatible)\n          │  chokidar (auto-polls on cloud-storage mounts)\n          ▼\nbastra-recall daemon (TypeScript / Node 22+, single local process)\n  - In-memory BM25 index (MiniSearch) — recall_when×5, title×4, tags×3\n  - Hybrid recall: BM25 + embeddings (Ollama or OpenAI) via RRF fusion\n  - Tools: recall, load_memory, save_memory, find/read/save_document\n  - Save path: validates frontmatter → writes file → force-reindexes\n    (so a save and a recall in the same turn are consistent)\n  - Transport: stdio MCP + HTTP REST (for non-MCP clients)\n          │\n          ▼\nOne daemon ↔ many AI clients\n  - Claude Code / Desktop / Cursor → via thin MCP forwarder (stdio → HTTP)\n  - ChatGPT Custom GPT, web apps, custom scripts → via REST /api/v1/*\n  - All clients share the same vault, index, telemetry stream\n```\n\nThe Claude Code reflex layer ships with six quiet hooks by default, all\nspeaking to the daemon's loopback HTTP endpoint:\n\n- **`PreToolUse`** (`bastra-recall-hook`) — fires before every `Write`/`Edit`/`MultiEdit`/`NotebookEdit`. Topic-detects from the tool intent and injects `\u003crecall-hints\u003e` as `additionalContext`.\n- **`SessionStart`** (`bastra-recall-session-hook`) — fires on `startup`/`resume`/`clear`/`compact`. Preloads top user-prefs + cross-project rules + project-scoped memories as `\u003csession-context\u003e` so the AI knows who, what, and what-not from the first prompt.\n- **`UserPromptSubmit`**, **`TodoWrite`**, **Bash safety**, and **Bash failure** hooks cover lookup prompts, topology recall before plans, destructive-command safety, and command-failure lesson recall.\n\nThe **`Stop`** save-eval hook exists but is opt-in because it can emit\nmulti-line suggestions at turn end. Enable it explicitly with\n`bastra install claude-code --with-stop-hook` if you want that behavior.\nTelemetry (`scripts/stats.ts`) tracks per-hook latency, hint-quality, and\nfollow-through (did the AI actually `load_memory` after a hint).\n\nDetails: [docs/architecture.md](./docs/architecture.md), [docs/memory-schema.md](./docs/memory-schema.md), [docs/triggers.md](./docs/triggers.md).\n\n### Memory shape\n\nEach memory is a markdown file with structured frontmatter:\n\n```yaml\n---\nid: css-input-focus-ring-stacking\ntitle: \"Don't stack focus styles on inputs\"\ntype: lesson\nsummary: \"Stacking ring + outline + custom :focus on nested inputs causes double focus rings. Use single :focus-visible.\"\ntopic_path: [css, input, focus]\ntags: [css, input, focus-ring, ui-bug]\nscope: all-projects\nrecall_when:\n  - creating new input component\n  - writing input or form css\n  - focus or accessibility styling\nrelated: [css-effects-stacking-antipattern]\nsource: \"carnexus, recurring lesson\"\nconfidence: 0.95\n---\n```\n\nThe `recall_when` field is the bridge between save and recall: when saving, the AI declares the contexts under which future-sessions should be reminded. See [docs/memory-schema.md](./docs/memory-schema.md) for full field semantics and six example memories covering `lesson`, `preference`, `project-fact`, `meta-working`, `decision`, `workflow`.\n\n### Install\n\nThree paths, in order of friction. bastra-recall is self-contained: the daemon, the MCP server, the REST gateway, the `bastra` CLI, and the Skill all ship in this repo — nothing else needed for full vault functionality.\n\n#### A) One double-click — easiest, for non-coders (rolling out)\n\n1. Download **Install Bastra.command** from the latest GitHub release.\n2. Double-click it in Finder.\n3. Done. Restart Claude Code / Claude Desktop / Cursor.\n\nThe script installs Homebrew if it's missing, adds the bastra tap, installs `bastra-recall`, and runs `bastra install all` — no terminal knowledge required.\n\n\u003e Until the Homebrew tap (`n0mad-ai/tap`) is published and the `.command` asset is attached to a release ([#3](https://github.com/n0mad-ai/bastra-recall/issues/3)), use path B.\n\n#### B) One command — for developers\n\nPre-requisites: Node 22+, Git.\n\n```bash\ngit clone https://github.com/n0mad-ai/bastra-recall.git\ncd bastra-recall\nnpm install\nnpm run build\n\nnode packages/daemon/dist/cli.js install all --vault /abs/path/to/your/vault\nnode packages/daemon/dist/cli.js doctor\nnode packages/daemon/dist/cli.js doctor --fix   # repair stale/missing registrations\nnode packages/daemon/dist/cli.js uninstall all\n```\n\nAdapter status:\n\n| Surface | What gets installed | Status |\n|---|---|---|\n| `claude-desktop` | MCP server entry in `claude_desktop_config.json` + Skill in `.claude/skills/` | ✅ implemented |\n| `claude-code` | MCP server in `.claude.json` + Skill in `.claude/skills/` + hooks \u0026 powerline statusLine in `.claude/settings.json` | ✅ implemented |\n| `cursor` | MCP server entry in `.cursor/mcp.json` | ✅ implemented (Cursor Rules layer is a separate roadmap item) |\n\nEvery write is **idempotent** (re-runs are no-ops), **atomic** (tmp file + rename), **backed up** (timestamped `.bak-…` next to the original), and **parse-safe** (broken JSON aborts the run instead of corrupting it). Vault path resolves in this order: `--vault \u003cpath\u003e` flag → `BASTRA_VAULT_PATH` env → auto-detect from an existing registration in `~/.claude.json` or `claude_desktop_config.json`. The CLI bails with a clear message if none of those produce a path.\n\nOnce installed through Homebrew or npm, this collapses to `bastra install all`.\n\n#### C) Fully manual — fallback\n\nAdd the MCP server block to your client's config (`~/.claude.json` for Claude Code, `~/Library/Application Support/Claude/claude_desktop_config.json` for Claude Desktop, `~/.cursor/mcp.json` for Cursor).\n\n**Recommended (forwarder mode — shares one daemon across all sessions):**\n\n```json\n\"bastra-recall\": {\n  \"command\": \"node\",\n  \"args\": [\"/abs/path/to/bastra-recall/packages/daemon/dist/mcp-forwarder.js\"],\n  \"env\": {\n    \"BASTRA_VAULT_PATH\": \"/abs/path/to/your/vault\"\n  }\n}\n```\n\nThe forwarder is a thin stdio-MCP wrapper that talks to a single local HTTP daemon (port 6723 by default). All MCP clients — Claude Code, Claude Desktop, Cursor, additional sessions — share the same vault state, embedding index, and telemetry. The forwarder auto-spawns the daemon on first run if no one is listening yet.\n\n**Standalone mode (one MCP client only, no sharing):**\n\n```json\n\"bastra-recall\": {\n  \"command\": \"node\",\n  \"args\": [\"/abs/path/to/bastra-recall/packages/daemon/dist/index.js\"],\n  \"env\": {\n    \"BASTRA_VAULT_PATH\": \"/abs/path/to/your/vault\"\n  }\n}\n```\n\nFor Claude Code, also drop the Skill + hooks by hand:\n\n```bash\nbash packages/skill/install.sh        # copies SKILL.md → ~/.claude/skills/bastra-recall/\nbash packages/skill/install-hook.sh   # registers the 6 default reflex-layer hooks (add --with-stop-hook for the 7th, Stop save-eval)\n```\n\n`bastra install claude-code` does both of these for you in path B. Re-run `install.sh` whenever `SKILL.md` changes; re-run `install-hook.sh` only if hook binary paths move. To remove the hooks again: `bash packages/skill/install-hook.sh --uninstall`.\n\n### Updating\n\n`bastra update` pulls the latest release (npm or Homebrew), re-registers every surface, and restarts the daemon. Opt into hands-off updates with `bastra config set update.mode auto` — bastra then stages a new version at session start without disrupting a running session. Running `bastra` with no arguments shows version, update status, daemon health, and vault size.\n\nFull details: **[Updating \u0026 settings](https://github.com/n0mad-ai/bastra-recall/wiki/Updating)** (wiki).\n\n### REST API (for non-MCP clients)\n\nThe daemon exposes a REST API on `http://127.0.0.1:6723/api/v1/` covering every tool the MCP server offers. This is the integration point for clients that can't speak stdio-MCP — most notably **ChatGPT Custom GPT Actions**, which call HTTPS endpoints with an OpenAPI schema.\n\nEndpoints (all `POST`, JSON body):\n\n| Endpoint | Tool |\n|---|---|\n| `/api/v1/recall` | recall |\n| `/api/v1/load_memory` | load_memory |\n| `/api/v1/save_memory` | save_memory |\n| `/api/v1/find_document` / `read_document` / `open_document` | document search |\n| `/api/v1/save_document` / `recategorize_document` / `move_document` | document write (Pro) |\n\nAuth and CORS:\n\n- If `BASTRA_API_TOKEN` is set, the daemon requires `Authorization: Bearer \u003ctoken\u003e` on every `/api/v1/*` request.\n- Loopback callers (`127.0.0.1`) bypass auth by default. Set `BASTRA_AUTH_LOOPBACK_SKIP=0` to require the token even locally.\n- CORS is permissive by default (`Access-Control-Allow-Origin: *`). Restrict via `BASTRA_CORS_ORIGIN=https://your.host`.\n\nTo expose this API to a hosted client like ChatGPT, point a tunnel (Cloudflare Tunnel / ngrok / your own reverse proxy) at `127.0.0.1:6723` and configure the Custom GPT with the tunnel URL + your token. An OpenAPI 3.0 starter spec lives in [docs/openapi.yaml](./docs/openapi.yaml).\n\n\u003e **Status:** the ChatGPT Custom GPT Actions path does **not work end-to-end yet**. The REST API and the OpenAPI spec are in place, but the Custom GPT integration is still being worked out — see the roadmap below.\n\n### Roadmap\n\nMilestone-based, not phase-based. Each gate is a hard pass/fail.\n\n| Milestone | Scope | Status |\n|---|---|---|\n| **M0** | Recall-quality eval on real vault | ✅ **Done** — Recall@1 98.3%, Recall@3 100%, MRR 0.992 across 59 memories (own-trigger baseline). BM25 + `recall_when`-boost is sufficient; embeddings deferred. |\n| **M1** | Daemon + read path (`recall`, `load_memory`) | ✅ **Done** — MCP server live, watcher works on cloud-storage mounts. |\n| **M2** | Save path + autonomous-save triggers | 🟡 **Functional** — `save_memory` MCP tool live with force-reindex. Trigger discipline shipped as a Skill. False-save / missed-save metrics not yet collected. |\n| **M0.5** | Stress-test recall (paraphrased / cross-memory / anti-hallucination) | ⏳ Open — see issues. |\n| **M3** | Reflex layer: hooks for `SessionStart` / `UserPromptSubmit` / `PreToolUse` / `PostToolUse` plus opt-in `Stop` | 🟡 **Functional** — six quiet Claude Code hooks are installed by default; `Stop` save-eval is available behind `--with-stop-hook`. |\n| **Distribution** | Homebrew tap, `bastra` CLI, `Install Bastra.command`, npm package | 🟡 **Functional / hardening** — `bastra` CLI ships with adapters for every surface; Homebrew formula and double-click installer exist; npm publish workflow and public smoke fixtures are being hardened. |\n| **Multi-surface** | One install per AI client (MCP + Skill + Hooks where applicable) + REST gateway for non-MCP clients | 🟡 **Functional** — `bastra install` covers Claude Code (MCP + Skill + Hooks), Claude Desktop (MCP + Skill), Cursor (MCP). REST `/api/v1/*` exposes every tool over HTTPS + tunnel for non-MCP clients. Open: ChatGPT Custom GPT Actions (not working end-to-end yet), Claude.ai web Custom Connector registration (#7). |\n\nOut of v0: **multi-device sync**. See [PLAN.md](./PLAN.md).\n\nMulti-device today works via the OS-level sync of the vault folder (iCloud / Google Drive / Dropbox / Git) — the file watcher's polling mode handles the latency. A browser-based UI is not planned — Obsidian already provides a great Markdown editor for the vault.\n\n### Bastra Mac App\n\nA native macOS app is being built on top of bastra-recall — same vault, same daemon, just a graphical interface for people who don't want to live in the terminal. In development; a dedicated page with screenshots and updates will follow.\n\n### License\n\nMIT — see [LICENSE](./LICENSE).\n\nPublic docs and code on this branch are published under the open license; private notes (in `private/`, gitignored) are not.\n\nThe statusline (`packages/statusline/`) bundles [owloops/claude-powerline](https://github.com/owloops/claude-powerline) (MIT, © 2025 Owloops) as its rendering engine, with the bastra-status segment built in; the upstream license is retained in [`packages/statusline/LICENSE`](./packages/statusline/LICENSE).\n\n### Status \u0026 contact\n\nEarly beta. See [PLAN.md](./PLAN.md). Issues and discussions welcome — early feedback shapes the design. Please report security issues privately via [SECURITY.md](./SECURITY.md).\n\nBuilt by [@n0mad-ai](https://github.com/n0mad-ai).\n\n---\n\n## 🇩🇪 Deutsch\n\n**Was es ist** — Ein Langzeit-Gedächtnis für jeden AI-Assistenten oder Agent: Claude (Code, Desktop, Web), ChatGPT (via Custom GPT Actions), Cursor und alles andere, was MCP oder HTTP spricht. Sobald du etwas korrigierst, eine Regel aufstellst oder eine Entscheidung triffst, wird das als kleine Notiz gespeichert. In der nächsten Sitzung — Tage oder Wochen später, in jedem Tool — holt die AI diese Notizen automatisch wieder hervor. Schluss mit ewigem Wiederholen. Alles bleibt lokal auf deinem Mac als reine Markdown-Dateien (Obsidian-kompatibel). Alle deine AI-Tools teilen sich dasselbe Gedächtnis gleichzeitig.\n\n**Status** — 🟢 Frühe Beta. M0 (Eval) und M1 (Read-Path) fertig, M2 (Save-Path) funktional, und der Claude-Code-Reflex-Layer liefert Hooks für `SessionStart`, `UserPromptSubmit`, `PreToolUse` (Datei-Edits / Todos / Bash-Safety), `PostToolUse` (Bash-Fehler) plus optionalen `Stop` Save-Eval. Distribution und Multi-Surface-Hardening laufen. Siehe [PLAN.md](./PLAN.md).\n\n### Warum\n\nWenn du Monate mit einem AI-Assistenten arbeitest, erklärst du dieselben Dinge immer wieder. Stolperfallen, die er in einem Projekt schon mal gelernt hat, kommen im nächsten zurück. Stabile Vorlieben (*\"gib mir eine Empfehlung, kein 5-Optionen-Menü\"*) sind zwischen Sitzungen vergessen. Projekt-spezifische Fakten werden jedes Mal neu entdeckt.\n\nDie meisten AI-Tools haben zwar Memory-Features, aber die sind **passiv**: bestenfalls eine statische Index-Datei, kein proaktives Erinnern, keine Kontinuität über verschiedene Oberflächen hinweg.\n\nDer Preis ist nicht nur Frust — sondern dass am Ende der User für die AI mitdenkt. *\"Moment, das hatten wir doch letzte Woche schon gelöst?\"* Genau das ist der Bug.\n\n### Was bastra-recall macht\n\nEine persistente Gedächtnis-Schicht, die:\n\n- **Autonom speichert** — wenn etwas gelernt wird (Frust, wiederholte Korrektur, dauerhafte Vorliebe, finale Entscheidung), schreibt die AI das ungefragt in den Vault. Die Trigger-Disziplin wird als Claude Code Skill ausgeliefert; andere Clients werden über ihren System-Prompt oder Custom-GPT-Instructions konditioniert.\n- **Vor dem Handeln erinnert** — nicht erst auf User-Anfrage. Die AI wird angewiesen, den Vault vor dem Code-Schreiben, vor Plänen und beim Sitzungsstart abzufragen. Das höchstgewichtete Suchfeld ist `recall_when`, das beim Speichern deklariert wird.\n- **Über alle Oberflächen hinweg funktioniert** — ein lokaler Daemon bedient alle deine AI-Tools gleichzeitig: Claude Code (via MCP), Claude Desktop (via MCP), ChatGPT (via Custom GPT Actions über HTTP), Cursor und alles weitere, was MCP oder HTTP spricht.\n- **Reines Markdown, Obsidian-kompatibel** — der Vault ist ein Ordner mit `.md`-Dateien und YAML-Frontmatter. Bearbeitbar in Obsidian, durch die AI oder per Hand. Vaults auf Google Drive / iCloud / Dropbox werden über den automatischen Polling-Modus des File-Watchers unterstützt.\n\n### Der einzige Erfolgs-Maßstab\n\n\u003e **Der User muss nicht mehr für die AI mitdenken.**\n\nWenn wiederkehrende Fehler weiter auftreten, wenn der User in jeder Sitzung dieselben Vorlieben wiederholen muss — dann ist das Projekt gescheitert, egal wie sauber die Architektur ist.\n\n### Wie es funktioniert\n\n```\nVault (konfigurierbar, reines Markdown + YAML-Frontmatter, Obsidian-kompatibel)\n          │  chokidar (Auto-Polling auf Cloud-Storage-Mounts)\n          ▼\nbastra-recall Daemon (TypeScript / Node 22+, ein lokaler Prozess)\n  - In-Memory BM25-Index (MiniSearch) — recall_when×5, title×4, tags×3\n  - Hybrid Recall: BM25 + Embeddings (Ollama oder OpenAI) via RRF-Fusion\n  - Tools: recall, load_memory, save_memory, find/read/save_document\n  - Save-Path: validiert Frontmatter → schreibt Datei → erzwingt Reindex\n    (sodass save und recall im selben Turn konsistent sind)\n  - Transport: stdio-MCP + HTTP-REST (für Nicht-MCP-Clients)\n          │\n          ▼\nEin Daemon ↔ viele AI-Clients\n  - Claude Code / Desktop / Cursor → über dünnen MCP-Forwarder (stdio → HTTP)\n  - ChatGPT Custom GPT, Web-Apps, eigene Skripte → über REST /api/v1/*\n  - Alle Clients teilen denselben Vault, Index und Telemetry-Stream\n```\n\nDer Claude-Code-Reflex-Layer installiert standardmäßig sechs ruhige Hooks, die\nden lokalen HTTP-Endpoint des Daemons nutzen:\n\n- **`PreToolUse`** (`bastra-recall-hook`) — feuert vor jedem `Write`/`Edit`/`MultiEdit`/`NotebookEdit`. Erkennt das Thema aus dem Tool-Aufruf und injiziert `\u003crecall-hints\u003e` als `additionalContext`.\n- **`SessionStart`** (`bastra-recall-session-hook`) — feuert bei `startup`/`resume`/`clear`/`compact`. Lädt Top-User-Präferenzen + projektübergreifende Regeln + projekt-spezifische Memories als `\u003csession-context\u003e` vor, damit die AI ab dem ersten Prompt weiß: wer, was, und was-nicht.\n- **`UserPromptSubmit`**, **`TodoWrite`**, **Bash-Safety** und **Bash-Failure** decken Lookup-Prompts, Topology-Recall vor Plänen, Safety bei riskanten Shell-Befehlen und Lesson-Recall bei fehlgeschlagenen Commands ab.\n\nDer **`Stop`** Save-Eval-Hook existiert, ist aber opt-in, weil er am Turn-Ende\nmehrzeilige Vorschläge ausgeben kann. Aktivierung bewusst per\n`bastra install claude-code --with-stop-hook`. Die Telemetrie (`scripts/stats.ts`)\nmisst pro Hook Latenz, Hint-Qualität und Follow-Through (hat die AI nach einem\nHint wirklich `load_memory` gemacht).\n\nDetails: [docs/architecture.md](./docs/architecture.md), [docs/memory-schema.md](./docs/memory-schema.md), [docs/triggers.md](./docs/triggers.md).\n\n### Aufbau einer Memory\n\nJede Memory ist eine Markdown-Datei mit strukturiertem Frontmatter:\n\n```yaml\n---\nid: css-input-focus-ring-stacking\ntitle: \"Don't stack focus styles on inputs\"\ntype: lesson\nsummary: \"Stacking ring + outline + custom :focus on nested inputs causes double focus rings. Use single :focus-visible.\"\ntopic_path: [css, input, focus]\ntags: [css, input, focus-ring, ui-bug]\nscope: all-projects\nrecall_when:\n  - creating new input component\n  - writing input or form css\n  - focus or accessibility styling\nrelated: [css-effects-stacking-antipattern]\nsource: \"carnexus, recurring lesson\"\nconfidence: 0.95\n---\n```\n\nDas `recall_when`-Feld ist die Brücke zwischen Save und Recall: beim Speichern deklariert die AI die Kontexte, in denen die spätere Sitzung daran erinnert werden soll. Siehe [docs/memory-schema.md](./docs/memory-schema.md) für die vollständige Feld-Semantik und sechs Beispiel-Memories für `lesson`, `preference`, `project-fact`, `meta-working`, `decision`, `workflow`.\n\n### Installation\n\nDrei Wege, nach Aufwand sortiert. bastra-recall ist eigenständig: Daemon, MCP-Server, REST-Gateway, `bastra`-CLI und Skill liegen alle in diesem Repo — mehr braucht es nicht für die volle Vault-Funktionalität.\n\n#### A) Ein Doppelklick — am einfachsten, für Nicht-Coder (Rollout läuft)\n\n1. Lade **Install Bastra.command** aus dem aktuellen GitHub-Release.\n2. Doppelklick im Finder.\n3. Fertig. Claude Code / Claude Desktop / Cursor neu starten.\n\nDas Skript installiert bei Bedarf Homebrew, fügt den bastra-Tap hinzu, installiert `bastra-recall` und führt `bastra install all` aus — kein Terminal-Wissen nötig.\n\n\u003e **Status (heute):** `distribution/Install Bastra.command` liegt im Repo. Der Homebrew-Tap (`n0mad-ai/tap`), den das Skript erwartet, wird mit Schließen von [#3](https://github.com/n0mad-ai/bastra-recall/issues/3) veröffentlicht. Bis dahin Pfad B nutzen.\n\n#### B) Ein Befehl — für Entwickler\n\nVoraussetzungen: Node 22+, Git.\n\n```bash\ngit clone https://github.com/n0mad-ai/bastra-recall.git\ncd bastra-recall\nnpm install\nnpm run build\n\nnode packages/daemon/dist/cli.js install all --vault /abs/pfad/zu/deinem/vault\nnode packages/daemon/dist/cli.js doctor\nnode packages/daemon/dist/cli.js doctor --fix   # veraltete/fehlende Registrierungen reparieren\nnode packages/daemon/dist/cli.js uninstall all\n```\n\nAdapter-Status:\n\n| Surface | Was installiert wird | Status |\n|---|---|---|\n| `claude-desktop` | MCP-Server-Eintrag in `claude_desktop_config.json` + Skill in `.claude/skills/` | ✅ implementiert |\n| `claude-code` | MCP-Server in `.claude.json` + Skill in `.claude/skills/` + Hooks \u0026 Powerline-statusLine in `.claude/settings.json` | ✅ implementiert |\n| `cursor` | MCP-Server-Eintrag in `.cursor/mcp.json` | ✅ implementiert (Cursor-Rules-Layer separater Roadmap-Punkt) |\n\nJeder Write ist **idempotent** (Re-Runs sind No-Ops), **atomar** (Tmp-File + Rename), **gesichert** (timestamped `.bak-…` neben dem Original) und **parse-safe** (kaputtes JSON bricht den Lauf ab statt es zu zerstören). Vault-Pfad-Auflösung in dieser Reihenfolge: `--vault \u003cpfad\u003e`-Flag → `BASTRA_VAULT_PATH`-ENV → Auto-Detect aus bestehender Registrierung in `~/.claude.json` oder `claude_desktop_config.json`. Wenn nichts greift, bricht die CLI mit klarer Meldung ab.\n\nSobald über Homebrew oder npm installiert, verkürzt sich das zu `bastra install all`.\n\n#### C) Komplett manuell — Fallback\n\nMCP-Server-Block in die Client-Config eintragen (für Claude Code: `~/.claude.json`, für Claude Desktop: `~/Library/Application Support/Claude/claude_desktop_config.json`, für Cursor: `~/.cursor/mcp.json`).\n\n**Empfohlen (Forwarder-Modus — ein Daemon für alle Sitzungen):**\n\n```json\n\"bastra-recall\": {\n  \"command\": \"node\",\n  \"args\": [\"/abs/path/to/bastra-recall/packages/daemon/dist/mcp-forwarder.js\"],\n  \"env\": {\n    \"BASTRA_VAULT_PATH\": \"/abs/path/to/your/vault\"\n  }\n}\n```\n\nDer Forwarder ist ein dünner stdio-MCP-Wrapper, der mit einem einzigen lokalen HTTP-Daemon spricht (Standard-Port 6723). Alle MCP-Clients — Claude Code, Claude Desktop, Cursor, weitere Sitzungen — teilen sich denselben Vault-State, Embedding-Index und Telemetry-Stream. Der Forwarder spawnt den Daemon beim ersten Start automatisch, falls noch keiner läuft.\n\n**Standalone-Modus (nur ein MCP-Client, kein Sharing):**\n\n```json\n\"bastra-recall\": {\n  \"command\": \"node\",\n  \"args\": [\"/abs/path/to/bastra-recall/packages/daemon/dist/index.js\"],\n  \"env\": {\n    \"BASTRA_VAULT_PATH\": \"/abs/path/to/your/vault\"\n  }\n}\n```\n\nFür Claude Code zusätzlich Skill + Hooks manuell ablegen:\n\n```bash\nbash packages/skill/install.sh        # kopiert SKILL.md → ~/.claude/skills/bastra-recall/\nbash packages/skill/install-hook.sh   # registriert die 6 Standard-Reflex-Layer-Hooks (--with-stop-hook für den 7., Stop-Save-Eval)\n```\n\n`bastra install claude-code` aus Pfad B erledigt beides für dich. `install.sh` neu ausführen, wenn sich `SKILL.md` ändert; `install-hook.sh` nur, wenn sich Hook-Binärpfade verschieben. Hooks wieder entfernen: `bash packages/skill/install-hook.sh --uninstall`.\n\n### Updates\n\n`bastra update` zieht den neuesten Release (npm oder Homebrew), registriert alle Surfaces neu und startet den Daemon neu. Für freihändige Updates `bastra config set update.mode auto` — bastra stagt dann am Session-Start eine neue Version, ohne eine laufende Session zu stören. `bastra` ohne Argument zeigt Version, Update-Status, Daemon-Health und Vault-Größe.\n\nDetails: **[Updating \u0026 settings](https://github.com/n0mad-ai/bastra-recall/wiki/Updating)** (Wiki).\n\n### REST API (für Nicht-MCP-Clients)\n\nDer Daemon exponiert eine REST-API unter `http://127.0.0.1:6723/api/v1/`, die alle Tools des MCP-Servers abdeckt. Das ist der Integrationspunkt für Clients, die kein stdio-MCP sprechen können — allen voran **ChatGPT Custom GPT Actions**, die HTTPS-Endpoints mit OpenAPI-Schema aufrufen.\n\nEndpoints (alle `POST`, JSON-Body):\n\n| Endpoint | Tool |\n|---|---|\n| `/api/v1/recall` | recall |\n| `/api/v1/load_memory` | load_memory |\n| `/api/v1/save_memory` | save_memory |\n| `/api/v1/find_document` / `read_document` / `open_document` | Document-Suche |\n| `/api/v1/save_document` / `recategorize_document` / `move_document` | Document-Schreiben (Pro) |\n\nAuth und CORS:\n\n- Wenn `BASTRA_API_TOKEN` gesetzt ist, verlangt der Daemon `Authorization: Bearer \u003ctoken\u003e` bei jedem `/api/v1/*`-Aufruf.\n- Loopback-Aufrufer (`127.0.0.1`) umgehen die Auth per Default. Mit `BASTRA_AUTH_LOOPBACK_SKIP=0` wird das Token auch lokal verlangt.\n- CORS ist per Default permissiv (`Access-Control-Allow-Origin: *`). Einschränken mit `BASTRA_CORS_ORIGIN=https://dein.host`.\n\nUm die API für einen gehosteten Client wie ChatGPT verfügbar zu machen: einen Tunnel (Cloudflare Tunnel / ngrok / eigener Reverse-Proxy) auf `127.0.0.1:6723` legen und im Custom GPT die Tunnel-URL + dein Token konfigurieren. Eine OpenAPI-3.0-Starter-Spec liegt in [docs/openapi.yaml](./docs/openapi.yaml).\n\n\u003e **Status:** Der ChatGPT-Custom-GPT-Actions-Weg **funktioniert noch nicht end-to-end**. REST-API und OpenAPI-Spec stehen, aber die Custom-GPT-Anbindung ist noch in Arbeit — siehe Roadmap unten.\n\n### Roadmap\n\nMilestone-basiert, nicht Phasen-basiert. Jedes Gate ist hartes Pass/Fail.\n\n| Milestone | Scope | Status |\n|---|---|---|\n| **M0** | Recall-Qualität auf echtem Vault evaluieren | ✅ **Fertig** — Recall@1 98.3%, Recall@3 100%, MRR 0.992 über 59 Memories (Own-Trigger-Baseline). BM25 + `recall_when`-Boost reicht; Embeddings zurückgestellt. |\n| **M1** | Daemon + Read-Path (`recall`, `load_memory`) | ✅ **Fertig** — MCP-Server live, Watcher funktioniert auf Cloud-Storage-Mounts. |\n| **M2** | Save-Path + autonome Save-Trigger | 🟡 **Funktional** — `save_memory` MCP-Tool live mit Force-Reindex. Trigger-Disziplin als Skill ausgeliefert. False-Save- / Missed-Save-Metriken noch nicht erhoben. |\n| **M0.5** | Stresstest für Recall (paraphrasiert / cross-memory / anti-halluzination) | ⏳ Offen — siehe Issues. |\n| **M3** | Reflex-Layer: Hooks für `SessionStart` / `UserPromptSubmit` / `PreToolUse` / `PostToolUse` plus opt-in `Stop` | 🟡 **Funktional** — sechs ruhige Claude-Code-Hooks werden standardmäßig installiert; `Stop` Save-Eval ist bewusst hinter `--with-stop-hook`. |\n| **Distribution** | Homebrew-Tap, `bastra`-CLI, `Install Bastra.command`, npm-Package | 🟡 **Funktional / Hardening** — `bastra`-CLI mit Adaptern für jedes Surface; Homebrew-Formula (head-only) liegt im Repo, der Tap `n0mad-ai/tap` wird mit [#3](https://github.com/n0mad-ai/bastra-recall/issues/3) veröffentlicht; `distribution/Install Bastra.command` als Doppelklick-Wrapper. Offen: End-to-End-Brew-Test, npm publish, GitHub-Release mit der `.command`-Datei als Asset (#3). |\n| **Multi-Surface** | Ein Install pro AI-Client (MCP + Skill + Hooks wo zutreffend) + REST-Gateway für Nicht-MCP-Clients | 🟡 **Funktional** — `bastra install` deckt Claude Code (MCP + Skill + Hooks), Claude Desktop (MCP + Skill), Cursor (MCP) ab. REST `/api/v1/*` stellt alle Tools via HTTPS + Tunnel für Nicht-MCP-Clients bereit. Offen: ChatGPT Custom GPT Actions (end-to-end noch nicht funktionsfähig), Claude.ai Web Custom Connector Registrierung (#7). |\n\nAußerhalb von v0: **Multi-Device-Sync**. Siehe [PLAN.md](./PLAN.md).\n\nMulti-Device funktioniert heute über OS-Level-Sync des Vault-Ordners (iCloud / Google Drive / Dropbox / Git) — der Polling-Modus des File-Watchers gleicht die Latenz aus. Ein Browser-basiertes UI ist nicht geplant — Obsidian liefert bereits einen sehr guten Markdown-Editor für den Vault.\n\n### Bastra Mac App\n\nEine native macOS-App entsteht auf Basis von bastra-recall — selber Vault, selber Daemon, nur mit grafischer Oberfläche für Leute, die nicht im Terminal leben wollen. In Entwicklung; eine eigene Seite mit Screenshots und Updates folgt.\n\n### Lizenz\n\nMIT — siehe [LICENSE](./LICENSE).\n\nPublic Docs und Code auf diesem Branch laufen unter der Open License; private Notizen (in `private/`, gitignored) nicht.\n\nDie Statusline (`packages/statusline/`) nutzt [owloops/claude-powerline](https://github.com/owloops/claude-powerline) (MIT, © 2025 Owloops) als Rendering-Engine, mit eingebautem bastra-status-Segment; die Upstream-Lizenz liegt unverändert in [`packages/statusline/LICENSE`](./packages/statusline/LICENSE).\n\n### Status \u0026 Kontakt\n\nFrühe Beta. Siehe [PLAN.md](./PLAN.md). Issues und Diskussionen willkommen — frühes Feedback formt das Design. Sicherheitsprobleme bitte vertraulich über [SECURITY.md](./SECURITY.md) melden.\n\nGebaut von [@n0mad-ai](https://github.com/n0mad-ai).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fn0mad-ai%2Fbastra-recall","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fn0mad-ai%2Fbastra-recall","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fn0mad-ai%2Fbastra-recall/lists"}