Agenten-Brain mit MCP: remember/recall für Claude-Sessions

KI-Agenten vergessen alles, sobald eine Session endet. Jede neue Claude-Instanz (Cowork, Claude.ai, Desktop) startet bei null und weiss nichts von den vorherigen. Dieser Guide beschreibt, wie ich ein zweites, getrenntes Second Brain aufsetze, das genau das löst: einen Memory-Layer, den jede Session über zwei Werkzeuge anspricht, remember und recall. Das eigene Brain (human-kuratiert) bleibt unberührt, das Agenten-Brain ist ein separater Speicher, in den die Maschine schreibt und aus dem sie liest.

Die Idee stammt aus der Analyse von JonasKruegerCode/SecondBrain, aber bewusst auf die schlanke, kostenlose Variante reduziert: kein Neo4j, kein Qdrant, kein Redis. Nur Markdown in Git plus ein Cloudflare Worker.

1. 🧠 Was wir bauen

Drei Teile, alle auf Free-Tier:

TeilWas es ist
brain-agent-Repoprivates GitHub-Repo, Markdown-Notizen, eingehängt als Submodule in den Brain-Build
MCP-WorkerCloudflare Worker mit zwei Tools (remember, recall), schreibt/liest das Repo über die GitHub-API
Claude-Connectorjede Claude-Session bindet den Worker per URL ein und kann damit erinnern und abrufen

Der Datenfluss: Eine Session ruft remember("..."), der Worker legt eine Markdown-Datei im brain-agent-Repo an (commit über die GitHub-API, kein lokales Git). Eine andere Session ruft später recall("was weiss ich über X"), der Worker liest die passenden Dateien und gibt sie zurück. Das Repo ist gleichzeitig als Submodule im privaten Brain gerendert, du siehst also alles, was die Agenten schreiben, in der Sidebar unter agent.

Das Prinzip dahinter ist dasselbe wie im Konzept-Post: Wissen liegt als portable Files in Git, nicht in einer gemieteten Datenbank. recall gibt in der Grundversion die fertige Seite zurück, nicht eine RAG-Synthese. Semantische Suche ist eine optionale Ausbaustufe (Abschnitt 8), kein Startbedarf.

2. 📦 Schritt 1: Das brain-agent-Repo

Lege auf GitHub ein privates Repo brain-agent an. Es ist als Hugo-Content strukturiert, weil es im Brain-Build mitgerendert wird. Minimalinhalt:

brain-agent/
  _index.md            # Sektions-Index, damit relearn die Sidebar-Sektion zeigt
  README.md            # was das Repo ist, für Menschen
  notes/
    _index.md          # Unter-Sektion für Agenten-Notizen
    .gitkeep

Das _index.md braucht nur einen Titel:

---
title: "Agenten-Gedächtnis"
---

Der Worker-Code lebt im selben brain-agent-Repo unter worker/ (gerendert wird er nicht, dafür sorgt eine ignoreFiles-Zeile in hugo.toml, siehe Abschnitt 6). Ein Beispiel-Eintrag und die Struktur sind im Repo bereits angelegt.

3. 🔗 Schritt 2: Als Submodule einhängen

Im blog-Repo, lokal:

git submodule add git@github.com:<dein-user>/brain-agent.git content/agent
git commit -m "Agenten-Brain als Submodule eingehängt"
git push

Wichtig ist die SSH-URL (git@github.com:...), nicht HTTPS. Genau an der HTTPS-URL scheitert der Cloudflare-Build später beim Klonen des privaten Submodules. Die Git-Befehle führst du selbst aus, nicht der Agent, wegen der OneDrive-Locks (siehe Betrieb & Moderation).

Voraussetzung SSH-Key: Die SSH-URL setzt voraus, dass ein SSH-Schlüssel in deinem GitHub-Account hinterlegt ist, sonst scheitert der Befehl mit «Permission denied (publickey)». Falls du bisher über HTTPS pushst, einmalig einrichten:

ssh-keygen -t ed25519 -C "deine-mail"   # dreimal Enter
cat ~/.ssh/id_ed25519.pub                # public key kopieren
# GitHub: Settings > SSH and GPG keys > New SSH key > einfuegen
ssh -T git@github.com                    # Test

Alternativ ginge der lokale submodule add auch über die HTTPS-URL, aber die landet dann in .gitmodules und bricht später den Cloudflare-Build. Darum lieber gleich den SSH-Key und die SSH-URL.

4. 🛡️ Schritt 3 + 4: Lokal prüfen und der Build sieht das Submodule

Lokal prüfen:

git submodule update --init --recursive
hugo server -D

In der Seitenleiste muss jetzt eine Sektion agent erscheinen. Wenn ja, ist die Einbindung korrekt.

Der Knackpunkt ist der Cloudflare-Build des brain-Projekts. Cloudflare Pages klont ein privates Submodule nicht automatisch mit, auch wenn beide Repos dir gehören. Zwei Wege, einer reicht:

  1. Deploy-Key (SSH): Erzeuge ein SSH-Schlüsselpaar, hinterlege den public key im brain-agent-Repo unter Settings, Deploy keys (read-only genügt), und den private key als Build-Secret im Pages-Projekt. Sauberste Trennung, weil der Key nur dieses eine Repo liest.
  2. PAT über GIT_CREDENTIALS: Ein Personal Access Token mit read auf brain-agent, im Pages-Projekt als Environment-Variable GIT_CREDENTIALS gesetzt.

Das ist der erste Token im Spiel, und er kann nur lesen. Der Schreib-Token kommt erst in Schritt 5.

5. 🔑 Schritt 5: Fine-grained PAT zum Schreiben

Damit der Worker Notizen ins Repo schreiben kann, braucht er ein Token mit Schreibrecht, aber nur auf brain-agent. Auf GitHub: Settings, Developer settings, Fine-grained tokens. Resource owner = du, Repository access = nur brain-agent, Permissions: Contents: Read and write. Sonst nichts.

Das ist der ganze Sinn der Repo-Trennung: Selbst wenn dieses Token leakt, kann es ausschliesslich im Agenten-Brain Schaden anrichten, nie in deinem kuratierten Brain. Der Blast-Radius ist auf einen wegwerfbaren Speicher begrenzt. Das Token wird gleich Worker-Secret, es taucht nirgends im Code oder Repo auf.

6. ⚙️ Schritt 6: Der MCP-Worker

Der Worker ist ein Cloudflare Worker mit der Agents-SDK, der einen Remote-MCP-Server bereitstellt. Das vollständige, lauffähige Gerüst liegt im brain-agent-Repo unter worker/ (im Blog also content/agent/worker/). Damit Hugo diesen Deploy-Code nicht als Webseite rendert, ignoriert ihn hugo.toml per Zeile ignoreFiles = ['content/agent/worker/.*']. Hier die tragenden Teile.

Die zwei Tools

remember(text, title?, tags?) zerlegt bei Bedarf in Themen und schreibt pro Notiz eine Markdown-Datei. recall(query, limit?) sucht über die Dateien und gibt die passenden zurück. Die Schreib- und Leselogik läuft komplett über die GitHub-Contents-API, der Worker braucht also selbst keinen Speicher.

Schreiben über die GitHub-API

remember macht ein PUT auf /repos/<user>/brain-agent/contents/notes/<slug>.md mit Base64-kodiertem Inhalt und einer Commit-Message. Das Frontmatter setzt type: note, origin: agent, date, tags, und ganz wichtig kein public: true, damit nie etwas in den öffentlichen Build leakt.

// Kern von remember (gekürzt, vollständig im Starter)
const path = `notes/${slug}.md`;
const body = `---\ntype: note\norigin: agent\ndate: ${iso}\ntags: [${tags}]\npublic: false\n---\n\n${text}\n`;
await fetch(`https://api.github.com/repos/${OWNER}/brain-agent/contents/${path}`, {
  method: "PUT",
  headers: { Authorization: `Bearer ${env.GITHUB_PAT}`, "User-Agent": "brain-agent-mcp" },
  body: JSON.stringify({ message: `remember: ${slug}`, content: btoa(unescape(encodeURIComponent(body))) }),
});

Lesen über die GitHub-API

recall listet notes/ über die API, lädt die Kandidaten und filtert per Stichwort gegen Titel und Text. In der Grundversion ist das eine simple Keyword-Suche, kein RAG. Für ein Gedächtnis, das klein genug zum Durchscannen ist, reicht das völlig. Der Worker gibt die gefundenen Notizen als Text zurück, die aufrufende Session liest sie dann.

Auth

Der Worker darf nicht offen im Netz stehen, sonst kann jeder mit der URL schreiben. Zwei pragmatische Wege: entweder den Worker hinter Cloudflare Access legen (wie dein Brain), oder im Worker einen Bearer-Token prüfen (MCP_API_KEY), den nur du und der Claude-Connector kennen. Das ist die eine Stelle, an der du eine bewusste Sicherheitsentscheidung triffst.

Deploy

cd content/agent/worker     # = das worker/ im brain-agent-Repo
npm install
npx wrangler secret put GITHUB_PAT     # der write-PAT aus Schritt 5
npx wrangler secret put MCP_API_KEY    # ein selbst gewähltes Geheimnis
npx wrangler deploy

Danach liegt der Server unter https://brain-agent-mcp.<dein-account>.workers.dev/mcp.

Claude verbinden

In Claude (Cowork, Claude.ai oder Desktop): Customize, Connectors, Add custom connector, die /mcp-URL einfügen und mit dem MCP_API_KEY authentifizieren. Ab dann hat jede Session, die diesen Connector aktiviert hat, remember und recall, und teilt damit dasselbe Gedächtnis. Genau das war das Ziel: Agenten sind verschiedene Claude-Instanzen, und der gemeinsame Speicher macht sie über Sessions hinweg konsistent.

7. ✅ Fazit: was am Ende läuft

Du hast zwei getrennte Brains. Deins, human-kuratiert, unverändert. Und brain-agent, in das jede Claude-Session über MCP schreibt und liest, gerendert als Sektion agent in deinem privaten Brain, damit du jederzeit siehst und reviewst, was die Maschine sich gemerkt hat. Alles auf Free-Tier, alles portable Files in Git, kein gemieteter Datenbank-Stack. Der Write-first-Gedanke bleibt: Du siehst jeden Agenten-Eintrag im Brain und kannst ihn jederzeit korrigieren oder löschen.

8. 🚀 Ausbaustufe: semantisches recall

Wenn das Agenten-Brain zu gross zum Durchscannen wird, hängst du semantische Suche an, ohne Qdrant: Embeddings über Cloudflare Workers AI (Free-Tier, 10'000 Neuronen pro Tag, z.B. EmbeddingGemma) und den Vektorindex über Cloudflare Vectorize (Free-Tier zum Prototypen). Dann macht recall echtes Ähnlichkeits-Matching statt Stichwort. Das bleibt Cloudflare-nativ und im Free-Tier, ist aber bewusst erst Stufe zwei, weil semantische Suche ein Skalierungs-Feature ist, kein Startbedarf.