huckleberry-mcp-worker
huckleberry-mcp-worker
Ein Model Context Protocol-Server für die Huckleberry-Babytracking-App, ausgeführt als Cloudflare Worker.
Dies ist ein TypeScript-Port von
bckenstler/py-huckleberry-mcp.
Das Original ist ein Python- stdio-Server, der über
google-cloud-firestore mit Firestore kommuniziert, was gRPC spricht und daher
nicht auf Workern ausgeführt werden kann. Dieser Port erreicht dasselbe Backend
über die Firebase-REST-API mit fetch und
bedient MCP über Streamable HTTP.
Der praktische Unterschied: Er ist immer erreichbar. Es muss kein Laptop laufen, damit ein Client ein Nickerchen protokollieren kann.
Tools
Alle 23 Tools des Python-Servers sind implementiert, plus delete_record.
Bereich | Tools |
Kinder |
|
Schlaf |
|
Füttern |
|
Windel |
|
Wachstum |
|
Einträge |
|
Jedes Verlaufstool meldet die interval_id jedes Eintrags, die von
delete_record benötigt wird.
Korrekturen gegenüber dem Python-Server
Beim Portieren wurden vier Fehler gefunden, die hier behoben sind.
Stilldauern wurden in der falschen Einheit geschrieben. Das Backend speichert
leftDuration / rightDuration in Sekunden – das schreibt auch der eingebaute
Timer der App – aber log_breastfeeding übergab die Minuten des Aufrufers
einfach so. Die Protokollierung einer 5-minütigen Fütterung zeichnete 5 Sekunden
auf. Aufrufer mussten zuvor 300 übergeben, um 5 Minuten zu bedeuten; hier
bedeutet left_duration_minutes: 5 fünf Minuten.
Eintägige Verlaufsabfragen lieferten nichts zurück. Beide Enden eines
Datumsbereichs wurden auf Mitternacht aufgelöst, sodass start_date == end_date
ein leeres Fenster ergab und der Server für einen Tag, der viele Einträge hatte,
keine meldete. Bereiche sind jetzt halboffen: [start_of_start_date, start_of_end_date + 1 day), sodass beide Enden inklusive sind.
end_time im Schlafverlauf war immer null. Der Code las ein end-Feld aus,
das das Backend nie schreibt. Es wird jetzt aus start + duration abgeleitet.
birth_date in list_children war immer null. Das Backend-Feld ist
birthdate; der Server las birthDate.
get_feeding_history gibt jetzt auch für jeden Eintrag den mode sowie die
dazugehörigen Details zurück: Menge und Typ für Fläschchen, Lebensmittelnamen
und Reaktionen für feste Nahrung. Ohne sie ist ein Eintrag für feste Nahrung
eine leere Zeile, die von einer Still-Sitzung der Länge Null nicht zu
unterscheiden ist – genau so wird ein einwandfreier Eintrag fälschlicherweise
für einen fehlenden gehalten.
Einrichtung
Erfordert Node 18+ und ein Cloudflare-Konto.
npm install
npx wrangler loginLegen Sie die Geheimnisse fest – sie werden von Cloudflare verschlüsselt gespeichert und befinden sich nie im Repository:
npx wrangler secret put HUCKLEBERRY_EMAIL
npx wrangler secret put HUCKLEBERRY_PASSWORD
npx wrangler secret put MCP_AUTH_TOKEN # a long random string you generate
npx wrangler secret put HUCKLEBERRY_TIMEZONE # e.g. America/Sao_PauloHUCKLEBERRY_TIMEZONE hat den Standardwert America/New_York. Es entscheidet,
wie naive Datums-/Uhrzeitangaben wie "2026-08-17T15:47:00" interpretiert
werden, daher ist die korrekte Einstellung wichtig.
Bereitstellung:
npm run deployAuthentifizierung
Die Worker-URL ist öffentlich, und der Server enthält Anmeldedaten für die Gesundheitsdaten eines Kindes, daher muss jede Anfrage das Bearer-Token enthalten:
Authorization: Bearer <MCP_AUTH_TOKEN>Anfragen ohne gültiges Token erhalten eine 401, bevor ein Huckleberry-Aufruf
erfolgt. Generieren Sie ein Token mit etwas wie openssl rand -base64 32.
Clients, die keine Header senden können
Einige MCP-Clients akzeptieren nur eine URL – benutzerdefinierte Connectors von
claude.ai beispielsweise akzeptieren eine URL und optionale OAuth-Anmeldedaten
ohne Feld für Authorization. Für diese akzeptiert der Server das Token auch
als letztes Pfadsegment:
POST https://<your-worker>.workers.dev/mcp/<MCP_URL_TOKEN>MCP_URL_TOKEN ist ein separates Geheimnis von MCP_AUTH_TOKEN, und zwar
bewusst: Anforderungspfade landen in Zugriffsprotokollen, dem Browserverlauf und
Referrern, anders als Header. Die Trennung bedeutet, dass ein Leck über eine URL
die Header-Anmeldedaten nicht gefährdet, und beide können unabhängig voneinander
rotiert werden. Wenn MCP_URL_TOKEN nicht gesetzt ist, fällt die Route auf
MCP_AUTH_TOKEN zurück, was praktisch ist, aber diese Trennung aufgibt.
npx wrangler secret put MCP_URL_TOKENBevorzugen Sie die Header-Route, wo immer der Client sie unterstützt.
Client-Konfiguration
Für Claude Code:
claude mcp add --transport http huckleberry https://<your-worker>.workers.dev/mcp \
--header "Authorization: Bearer <MCP_AUTH_TOKEN>"Lokale Entwicklung
cp .dev.vars.example .dev.vars # then fill it in; .dev.vars is gitignored
npm run devcurl -X POST http://localhost:8787/mcp \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'Designhinweise
Zustandslos. Jede Anfrage erstellt einen neuen McpServer über
createMcpHandler aus dem Cloudflare agents-SDK. Es sind keine Durable
Objects und keine Sitzungsspeicherung beteiligt, da jedes Tool ein in sich
geschlossener Lese- oder Schreibvorgang ist.
Token-Caching. Firebase-ID-Token sind eine Stunde gültig und werden im Modul-Gültigkeitsbereich zwischengespeichert, sodass Anfragen, die auf einer warmen Isolate landen, die erneute Authentifizierung überspringen. Eine kalte Isolate kostet einen zusätzlichen Roundtrip. Ein während der Verarbeitung zurückgewiesenes Token löst eine erneute Authentifizierung und einen Wiederholungsversuch aus.
Numerische Typen. Firestore unterscheidet zwischen Ganzzahlen und
Gleitkommazahlen, und die App schreibt einige Felder als das eine und andere als
das andere. Werte, die als Gleitkommazahlen gespeichert werden müssen, werden in
dbl() eingeschlossen, sodass hier geschriebene Einträge mit denen
übereinstimmen, die von der App geschrieben wurden.
Dokumente mit mehreren Einträgen. Der Verlauf liegt in zwei Formen vor:
gewöhnliche Dokumente mit einem start auf oberster Ebene und
Batch-Dokumente, die viele Einträge unter data enthalten. Verschachtelte
Starts können serverseitig nicht gefiltert werden, daher werden Batch-Dokumente
vollständig abgerufen und im Worker gefiltert. Einträge geben über
is_multi_entry an, aus welcher Form sie stammen.
Löschen von Einträgen
Der Python-Server hatte keine Löschfunktion, und die allgemeine Annahme war,
dass das Backend dies nicht zuließ. Es tut es doch: Ein DELETE auf den
Dokumentenpfad gibt 200 zurück. Was tatsächlich fehlte, war die ID des Eintrags,
den die Verlaufstools nie gemeldet haben.
Daher geben Verlaufstools jetzt interval_id zurück, und delete_record
entfernt den benannten Eintrag. Batch-Einträge – mehrere Einträge, die in einem
Dokument unter data zusammengefasst sind – werden als <documentId>#<entryKey>
angesprochen und als ein Feld ihres übergeordneten Dokuments entfernt.
Das Löschen aktualisiert auch prefs.last* auf den neuesten überlebenden
Eintrag. Die App liest diese Zeiger direkt, sodass ein Löschen ohne diese
Aktualisierung dazu führt, dass sie einen Eintrag anzeigt, der nicht mehr
existiert.
Bekannte Einschränkungen
Löschungen sind endgültig. Es gibt keine Rückgängig-Funktion. Bestätigen Sie mit einer Verlaufsabfrage, bevor Sie
delete_recordaufrufen.Feste Nahrung ist schreibgeschützt.
get_feeding_historymeldet Einträge für feste Nahrung mit ihren Lebensmittelnamen und Reaktionen, aber es gibt kein Tool, um einen zu erstellen.start_sleepschützt nicht vor einem bereits laufenden Timer. Der Python-Server dokumentierte, dass er in diesem Fall fehlschlagen würde, hat es aber nie überprüft; das Verhalten wird hier beibehalten, anstatt es stillschweigend zu ändern.Notizen werden nicht in Schlafaufzeichnungen zurückgespielt. Das Feld
detailsist eine feste Struktur von Kontrollkästchen, kein Freitext.
Lizenz
MIT
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
Cloud-hosted MCP server for durable AI memory
Hosted remote MCP server for YNAB on Cloudflare Workers with OAuth
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jcrispiniano/huckleberry-mcp-worker'
If you have feedback or need assistance with the MCP directory API, please join our Discord server