Cloudflare verbindet Claude mit meinem Journal
Heute eingerichtet: ein Remote-MCP-Konnektor für kurze Journal-Einträge direkt aus Claude.
Verbindung
Claude: Handy / Desktop / Browser
→ Anthropic-Cloud
→ Cloudflare Worker: /mcp
→ Grav-API: /api/v1
→ /journal/<entry_id>
Zweck: Ein gemeinsamer Zugang für alle Geräte. Worker und Grav laufen unabhängig von meinem PC. GitHub-OAuth prüft meine Identität; der Worker verwendet einen separaten Grav-API-Key.
Warum Cloudflare?
- Erreichbarkeit: Claude ruft Remote-Konnektoren aus der Anthropic-Cloud auf. Unser MiniPC im Tailscale-Netz wäre darüber allein nicht erreichbar.
- Betrieb: Der Worker stellt eine öffentliche HTTPS-Adresse bereit, ohne Portfreigabe am Heimrouter oder einen ständig laufenden eigenen Server.
- Bausteine: Workers für den MCP-Endpunkt, KV für OAuth-Daten und Secrets für Zugangsdaten. Die Grav-Webseite bleibt der Speicher für die Einträge.
1. Worker bereitgestellt
Im Projektordner services/journal-mcp:
npx.cmd wrangler login
npx.cmd wrangler kv namespace create OAUTH_KV
npm.cmd run deploy
Wirkung: Cloudflare-Zugang autorisiert, KV-Speicher für OAuth angelegt und Worker veröffentlicht.
Auszug aus wrangler.jsonc:
{
"SITE_URL": "https://pfeisinger.com",
"GRAV_API_URL": "https://pfeisinger.com/api",
"JOURNAL_ENABLED": "true"
}
Zweck: Zieladressen festlegen. Schreibfunktionen erst nach Einrichtung von Journal-Template und CMS-Seite freischalten. Diese Werte stehen unter vars; Zugangsdaten bleiben außerhalb der Datei.
2. Anmeldung und Secrets eingerichtet
GitHub OAuth App angelegt:
Homepage:
https://pfeisinger-journal.registration-56d.workers.dev
Callback:
https://pfeisinger-journal.registration-56d.workers.dev/callback
npx.cmd wrangler secret put GITHUB_CLIENT_ID
npx.cmd wrangler secret put GITHUB_CLIENT_SECRET
npx.cmd wrangler secret put COOKIE_ENCRYPTION_KEY
npx.cmd wrangler secret put GRAV_API_KEY
Wirkung: Werte jeweils am verdeckten Prompt hinterlegt. GitHub-OAuth erlaubt nur meine konfigurierte GitHub-ID. Der Grav-Key gehört zum eigenen Benutzer journal-connector mit Seiten-Lese- und Schreibrechten.
3. Grav-API angebunden
Gekürzter Auszug aus src/journal.ts:
this.api = api.href.replace(/\/+$/, "");
if (!this.api.endsWith("/v1")) this.api += "/v1";
Zweck: Aus der Basisadresse den API-Endpunkt https://pfeisinger.com/api/v1 bilden.
headers: {
"X-API-Key": this.settings.GRAV_API_KEY,
Accept: "application/json",
...(etag ? { "If-Match": etag } : {})
}
Wirkung: Grav authentifiziert den Worker über den API-Key. Bei Änderungen verhindert If-Match das Überschreiben einer inzwischen geänderten Version.
Zwei Fehler im Worker behoben:
export const GRAV_REDIRECT_MODE = "manual" as const;
// Standardwert für den injizierbaren Request-Handler:
(input, init) => fetch(input, init)
Warum: Die Worker-Laufzeit unterstützte redirect: "error" nicht. Weiterleitungen werden jetzt manuell erkannt und abgelehnt. Der Wrapper verhindert den falschen Funktionskontext beim Aufruf von fetch als Objektmethode.
4. Journal von Blog getrennt
# Journal-Übersicht
content:
items: '@self.children'
order:
by: date
dir: desc
pagination: false
Wirkung: Die Übersicht lädt eigene Journal-Kindseiten, neueste zuerst. Das Twig-Template filtert veröffentlichte Einträge und teilt sie in Seiten mit jeweils 20 Einträgen.
# Neuer Eintrag
published: false
visible: false
routable: true
status: entwurf
Zweck: Zuerst einen Entwurf speichern. visible: false hält einzelne Einträge aus dem Hauptmenü; erst nach Veröffentlichung wird der eigene Link öffentlich erreichbar.
Templates: journal.html.twig und journal-entry.html.twig. Codeblöcke bekommen Syntaxhervorhebung und einen Kopierknopf. „Notizen aus der Praxis“ auf der Startseite verlinkt jetzt auf /journal.
5. Claude verbunden und Workflow festgelegt
Konnektor-Name: Pfeisinger Journal URL
https://pfeisinger-journal.registration-56d.workers.dev/mcp
Journal save draft
→ Entwurf mit stabiler entry_id speichern
Journal read
→ Inhalt und aktuellen ETag lesen
Journal publish
→ mit ETag veröffentlichen
→ öffentlichen Link auf Eintrags-Markierung prüfen
Wirkung: Wiederholungen behalten dieselbe ID. Vor erneutem Schreiben wird der vorhandene Eintrag gelesen. Veröffentlichte Einträge überschreibt der Konnektor in Version 1 nicht.
Auftrag im Chat:
Verwende „Pfeisinger Journal URL“.
Speichere diese Arbeitsnotiz als Journalentwurf:
[Meine Notiz und Codeschnipsel]
Noch nicht veröffentlichen.
Geprüft / noch offen
- Geprüft: 16 automatisierte Tests, TypeScript-Prüfung und Worker-Deployment.
- Claude Desktop: „Journal list“ lieferte beim ersten erfolgreichen Aufruf
[]. - Webseite: erster Eintrag über Grav-MCP veröffentlicht; Übersicht und Einzelansicht erreichbar.
- Offen: echter Schreibaufruf aus Claude Desktop und vom Handy.