fatsecret-mcp
fatsecret-mcp
Ein persönlicher Remote-MCP-Server (Model Context Protocol), der es Claude ermöglicht, die Lebensmittel- und Rezeptdatenbank von FatSecret zu durchsuchen und dein eigenes Ernährungstagebuch, Gewicht und Trainingsprotokoll direkt im Gespräch zu lesen und zu schreiben. Bereitgestellt auf Vercels kostenlosem Hobby-Tarif. Schwesterprojekt zu fitness-mcp (Hevy) — ein MCP-Server pro Produkt, die dasselbe Authentifizierungsmuster nutzen.
Lizenz
Status
Suche (Phase 2): implementiert —
search_foods,get_food_detail,search_recipes,get_recipe_detail,find_food_by_barcode. Keine FatSecret-Benutzerautorisierung erforderlich; nur die OAuth-2.0-Client-ID und das Client-Secret aus der FatSecret-Entwicklerkonsole.Tagebuch/Gewicht/Training/Profil (Phase 4): implementiert, aber nicht gegen ein echtes FatSecret-Konto verifiziert — es gab keine FatSecret-API-Registrierung, als dies gebaut wurde (siehe „Was nicht verifiziert ist“ unten). Bestätige die genauen Feldnamen jeder Methode anhand eines echten Kontos, bevor du dich darauf verlässt, und aktualisiere Code/Tests, falls etwas nicht stimmt.
3-legged-OAuth1-Setupskript (Phase 3): implementiert (
scripts/fatsecret-oauth-setup.ts), aber noch nicht gegen ein echtes FatSecret-Konto ausgeführt.
Zwei Authentifizierungsebenen
Dieser Server sitzt zwischen Claude und FatSecret, und diese beiden Beziehungen werden jeweils völlig unterschiedlich authentifiziert — das ist das Wichtigste, was man verstehen sollte, bevor man den Code anfasst.
Claude <──①── this server (fatsecret-mcp) ──②──> FatSecret API① Claude ↔ dieser Server — ein einziges gemeinsames Geheimnis, gleiches Muster wie fitness-mcp. Claude sendet bei jeder Anfrage Authorization: Bearer <MCP_BEARER_TOKEN>; lib/auth.ts prüft es. Da Claudes Static-Header-Option weiterhin per Beta beschränkt ist, betreibt dieser Server auch einen eigenen minimalen OAuth-2.1-Autorisierungsserver (lib/oauth.ts, /api/oauth/authorize, /api/oauth/token), sodass die standardmäßigen OAuth-Client-ID/Secret-Felder von Claude als immer verfügbare Fallback-Option funktionieren — siehe README von fitness-mcp für die vollständige Begründung, die hier unverändert gilt.
② dieser Server ↔ FatSecret — hier wird es komplexer als bei fitness-mcp, weil FatSecret selbst zwei verschiedene OAuth-Versionen für zwei verschiedene Arten von API-Methoden verwendet, und daran führt kein Weg vorbei — so ist die FatSecret-API entworfen, keine Entscheidung, die hier getroffen wurde:
Kategorie der FatSecret-Methoden | Beispielmethoden | Wie dieser Server authentifiziert |
Signierte Anfrage (kein bestimmter Benutzer beteiligt) |
| OAuth 2.0 Client-Credentials — |
Signierte & delegierte Anfrage (liest/schreibt dein FatSecret-Konto) |
| OAuth 1.0a, 3-legged, HMAC-SHA1-signiert — |
Konkret: search_foods/get_food_detail/search_recipes/get_recipe_detail/find_food_by_barcode funktionieren, sobald du eine FatSecret-App registriert und FATSECRET_CLIENT_ID/FATSECRET_CLIENT_SECRET gesetzt hast. Alle anderen Tools benötigen zusätzlich FATSECRET_CONSUMER_KEY/FATSECRET_CONSUMER_SECRET (OAuth1 — ein anderes Anmeldedatenpaar aus derselben FatSecret-App) sowie FATSECRET_ACCESS_TOKEN/FATSECRET_ACCESS_TOKEN_SECRET (erhalten durch einmaliges Ausführen des Setupskripts).
Verfügbare Tools
Tool | Typ | Benötigte Authentifizierung | Beschreibung |
| lesen | OAuth2 (App) | Durchsucht die Lebensmitteldatenbank von FatSecret nach Namen |
| lesen | OAuth2 (App) | Vollständige Nährwertangaben pro Portion für ein Lebensmittel |
| lesen | OAuth2 (App) | Durchsucht die Rezeptdatenbank von FatSecret |
| lesen | OAuth2 (App) | Vollständige Zutaten/Anleitungen für ein Rezept |
| lesen | OAuth2 (App) | Löst einen GTIN-13-Barcode in eine foodId auf — benötigt den |
| lesen | OAuth1 (Benutzer) | Listet Tagebucheinträge zu Lebensmitteln für ein Datum auf |
| lesen | OAuth1 (Benutzer) | Listet bevorzugte Lebensmittel auf |
| lesen | OAuth1 (Benutzer) | Listet am häufigsten gegessene Lebensmittel auf, optional nach Mahlzeit |
| lesen | OAuth1 (Benutzer) | Listet kürzlich gegessene Lebensmittel auf, optional nach Mahlzeit |
| lesen | OAuth1 (Benutzer) | Listet Gewichtseinträge für einen Monat auf — möglicherweise nur Premier |
| lesen | OAuth1 (Benutzer) | Listet Trainingseinträge für ein Datum auf |
| lesen | OAuth1 (Benutzer) | Ruft die Profilzusammenfassung des Benutzers bei FatSecret ab |
| schreiben | OAuth1 (Benutzer) | Protokolliert ein Lebensmittel im Tagebuch |
| schreiben | OAuth1 (Benutzer) | Aktualisiert einen vorhandenen Tagebucheintrag |
| schreiben | OAuth1 (Benutzer) | Löscht einen Tagebucheintrag |
| schreiben | OAuth1 (Benutzer) | Protokolliert/aktualisiert einen Gewichtseintrag — möglicherweise nur Premier |
| schreiben | OAuth1 (Benutzer) | Protokolliert einen Trainingseintrag |
Schreib-Tools sind standardmäßig Dry-Runs
Gleiches Design wie fitness-mcp: Jedes Schreib-Tool erfordert ein Argument confirm: true. Ihre Beschreibungen weisen das aufrufende LLM an, dem Benutzer genau zu zeigen, was geschrieben wird, und zuerst eine ausdrückliche Zustimmung einzuholen. Das ist ein struktureller Anstoß, keine Garantie — dasselbe LLM, das entscheidet, ob das Tool aufgerufen wird, setzt auch confirm, und es gibt keine Trennung der Berechtigungen zwischen Lese-/Schreib-Tools auf der Authentifizierungsebene, sodass jeder Aufrufer mit einem gültigen MCP_BEARER_TOKEN jedes Tool aufrufen kann.
Was nicht verifiziert ist
Es gab keine FatSecret-API-Registrierung, als dieses Projekt gebaut wurde (dieser Schritt erfordert einen Menschen — siehe Einrichtung unten), daher:
Die Methodennamen und Kernparameter von
search_foods/get_food_detail/search_recipes/get_recipe_detail/profile.get/food_entries.get/weights.get_monthsind gegen funktionierende Drittanbieter-Implementierungen von FatSecret-Clients bestätigt (nicht geraten) — siehe die Git-Historie für Quellen.Die Antwortstruktur von
food.find_id_for_barcode, die Parameternamen vonweight.updateund alleexercise_entries.*sind Best-Effort-Rekonstruktionen, die inline inlib/fatsecret/*.tsmit der Begründung gekennzeichnet sind. Behandle sie als soliden Ausgangspunkt, nicht als verifizierte Wahrheit.Führe die manuelle Verifikations-Checkliste unten nach der Registrierung gegen ein echtes Konto aus und korrigiere alle Feldnamen-Abweichungen, die du findest (die Unit-Tests in
lib/fatsecret/*.test.tsmüssen entsprechend aktualisiert werden).
Einrichtung
Registriere eine FatSecret-Platform-API-App unter https://platform.fatsecret.com/. Du erhältst:
Eine OAuth-2.0-Client-ID/Secret (für
FATSECRET_CLIENT_ID/FATSECRET_CLIENT_SECRET).Einen OAuth-1.0-Consumer-Key/Secret (für
FATSECRET_CONSUMER_KEY/FATSECRET_CONSUMER_SECRET) — ein separates Paar aus derselben App, nicht identisch mit den OAuth2-Anmeldedaten oben.Prüfe, welche Scopes dein Tarif enthält (
basic/premier/barcode/ ...) —weights.get_month/weight.update/find_food_by_barcodesollen Premier bzw. die Scopesbarcode/premiererfordern; bestätige das für deinen eigenen Tarif und passeFATSECRET_OAUTH2_SCOPEbei Bedarf an.Nimm deine ausgehenden IP-Adressen in die Allowlist auf für OAuth2-Tokenanfragen — FatSecret verlangt das (bis zu 15 Adressen/Bereiche). Wenn du auf Vercel bereitstellst, benötigst du eine statische ausgehende IP (z. B. über einen von Vercel unterstützten Egress-Proxy/Add-on); die standardmäßigen serverlosen Funktionen von Vercel haben keine feste IP.
Führe den lokalen Entwicklungsserver einmal aus, um die Suche zu testen (Phase 2 benötigt nur Schritt 1): GXP2
Führe das einmalige 3-legged-OAuth1-Setup aus (erforderlich für jedes Tool außer den 5 Such-/Detail-Tools) — siehe Phase 3 unten.
Stelle auf Vercel bereit — siehe Bereitstellung unten.
Lokale Entwicklung
npm install
cp .env.example .env.local # fill in real values
vercel devSmoke-Test (ersetze $MCP_BEARER_TOKEN):
curl -X POST http://localhost:3000/api/mcp \
-H "Authorization: Bearer $MCP_BEARER_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Sollte die 17 Tools oben zurückgeben. Eine Anfrage mit fehlendem/falschem Token sollte 401 erhalten.
Phase 3: Einmaliges 3-legged-OAuth1-Setup
Jedes Tool außer search_foods/get_food_detail/search_recipes/get_recipe_detail/find_food_by_barcode benötigt ein OAuth1-Access-Token/Secret, das an dein FatSecret-Konto gebunden ist. Du erhältst es einmalig:
npm run fatsecret:oauth-setupDieses Skript (scripts/fatsecret-oauth-setup.ts) wird:
Ein nicht autorisiertes Request-Token von FatSecret anfordern.
Eine Autorisierungs-URL ausgeben — öffne sie, melde dich bei FatSecret an und genehmige. FatSecret zeigt einen Bestätigungscode.
Dich auffordern, diesen Code einzufügen, und ihn dann gegen ein dauerhaftes Access-Token/Secret eintauschen.
FATSECRET_ACCESS_TOKEN/FATSECRET_ACCESS_TOKEN_SECRETin.env.localschreiben.
Füge dann dieselben beiden Werte auch zu den Umgebungsvariablen von Vercel hinzu (.env.local wird niemals bereitgestellt) — siehe Bereitstellung unten.
Laut der FatSecret-Dokumentation läuft dieses Access Token nicht ab. Falls es jemals widerrufen wird (z. B. wenn du den App-Zugriff in deinen FatSecret-Kontoeinstellungen entfernst), führe einfach das Skript erneut aus, um ein neues zu erhalten — im Geiste des derive()-Musters von fitness-mcp: Verlorene Zugangsdaten sind hier keine Katastrophe, sondern mit einem einzigen Befehl behoben — nur diesmal interaktiv statt durch eine deterministische Neuableitung.
Generieren der Claude-zugewandten Geheimnisse aus einer einprägsamen Passphrase
MCP_BEARER_TOKEN, OAUTH_CLIENT_ID und OAUTH_CLIENT_SECRET (Ebene ① — Claude ↔ dieser Server, unabhängig von den FatSecret-Zugangsdaten oben) können alle deterministisch aus einer einzigen Master-Passphrase abgeleitet werden. Ein Verlust der gespeicherten Werte ist also keine Katastrophe — leite sie einfach neu ab:
derive() {
if [ -z "$MASTER_PASSPHRASE" ]; then
printf "Master passphrase: "
read -rs MASTER_PASSPHRASE
echo
fi
echo -n "$1" | openssl dgst -sha256 -hmac "$MASTER_PASSPHRASE" -hex | awk '{print $2}'
}
derive "fatsecret-mcp:bearer-token" # → MCP_BEARER_TOKEN
derive "fatsecret-mcp:oauth-client-id" # → OAUTH_CLIENT_ID
derive "fatsecret-mcp:oauth-client-secret" # → OAUTH_CLIENT_SECRETDie Label-Strings sind nicht geheim (sie können bedenkenlos in dieser README bleiben) — nur die Passphrase ist es. Wenn derive erneut mit derselben Passphrase ausgeführt wird, reproduziert es immer dieselben Werte. Dies gilt nicht für die FatSecret-seitigen Zugangsdaten (FATSECRET_CLIENT_ID/SECRET, FATSECRET_CONSUMER_KEY/SECRET, FATSECRET_ACCESS_TOKEN/SECRET) — diese stammen aus der FatSecret-Entwicklerkonsole und dem OAuth1-Einrichtungsskript, nicht aus dieser Passphrase.
Testen
Drei Ebenen, die bei jedem Push/PR in CI (.github/workflows/ci.yml) laufen — keine benötigt echte FatSecret-Geheimnisse, daher funktionieren sie in einem öffentlichen Repository genauso:
npm run test # unit + integration (vitest) — pure logic, plus the real Next.js
# route handler exercised with fetch mocked
npm run build
npm run test:e2e # starts a real `next start` server and hits it over real HTTP
# (node's built-in test runner, no extra dependency)Unit (
lib/**/*.test.ts): Bearer-Token-Verifizierung, OAuth2.1-Code-Signierung/PKCE/Redirect-URI-Allowlisting (RFC-7636-Testvektor enthalten), FatSecret-OAuth2-Client-Credentials-Token-Abruf/Cache/Refresh (lib/fatsecret/appAuth.test.ts), OAuth1-HMAC-SHA1-Signierung, die gegen eine unabhängige Neuimplementierung geprüft wurde (lib/fatsecret/oauth1.test.ts), und die Antwortform-Normalisierung jederlib/fatsecret/*.ts-Datei (Einzelobjekt-vs-Array, Zahlenstring-vs-Zahl, Leerantwort-Eigenheiten).Integration (
test/integration/*.test.ts): Der echteapp/api/mcp/route.ts-Handler, verbunden mit den echtenlib/fatsecret/*-Modulen, wobei nurfetchgemockt ist. Abgedeckt werden sowohl die OAuth2-Pfade (Signed Request) als auch die OAuth1-Pfade (Signed & Delegated) der Tools sowie die Bestätigungsabsicherung (confirm-gating) bei jedem Schreib-Tool; die echten Routen/api/oauth/authorize//api/oauth/token; die OAuth-Metadatenrouten unter.well-known.E2E (
test/e2e/*.e2e.test.mjs): Startet den Produktions-Build und prüft über echtes HTTP — Health Check, 401 bei fehlender/falscher Authentifizierung,tools/listliefert alle 17 Tools, OAuth-Discovery-Metadaten und einen vollständigen Authorization-Code- + PKCE-Roundtrip. Es werden keine echten FatSecret-Daten verwendet (CI hat bewusst keine echten Zugangsdaten).
Manuelle Überprüfung mit einem echten FatSecret-Konto
CI greift nie auf echte FatSecret-Daten zu, und — wie oben unter „Was ist unverifiziert“ erwähnt — wurden einige Annahmen dieses Servers über die exakten Antwortstrukturen von FatSecret noch nie mit einem echten Konto überprüft. Nach der Registrierung und dem Ausführen des OAuth1-Einrichtungsskripts arbeitest du diese Checkliste durch und behebst alle gefundenen Abweichungen:
Setze echte
FATSECRET_CLIENT_ID/FATSECRET_CLIENT_SECRETin.env.local, führevercel devaus und rufesearch_foodsmit einer echten Abfrage auf (z. B. über das Smoke-Test-curl-Muster oben mittools/call) — bestätige, dass echte Ergebnisse zurückkommen undget_food_detailfür eines davon plausible Nährwerte liefert.Rufe
search_recipesundget_recipe_detailentsprechend auf.Falls dein Plan den
barcode-Scope umfasst, rufefind_food_by_barcodemit dem Barcode eines echten Produkts auf und bestätige, dass die Antwortstruktur mitRawFindIdForBarcodeResponseauslib/fatsecret/foods.tsübereinstimmt — korrigiere sie andernfalls.Führe
npm run fatsecret:oauth-setupaus und rufe dannget_profileundget_food_diaryauf — bestätige, dass die Feldnamen inlib/fatsecret/profile.ts/lib/fatsecret/diary.tsmit der echten Antwort übereinstimmen (sie wurden aus Dokumentationen rekonstruiert, nicht aufgezeichnet).Rufe
create_food_diary_entrymitconfirm: trueund einem offensichtlichen Wegwerf-Eintrag auf, danachget_food_diaryfür dasselbe Datum und bestätige, dass der Eintrag mit den richtigen Werten für Lebensmittel/Portion/Menge/Mahlzeit erscheint. Anschließendupdate_food_diary_entryunddelete_food_diary_entry— bestätige, dass beide Vorgänge vollständig durchlaufen.Falls dein Plan Gewichtstracking umfasst, rufe
update_weightmitconfirm: trueauf und bestätige, dassget_weight_historydies widerspiegelt.create_exercise_entryundget_exercise_diarysind das am wenigsten verifizierte Paar in dieser Codebasis (siehe Warnung am Anfang vonlib/fatsecret/exercise.ts) — überprüfe den genauen Methodennamen/die Parameter gegen https://platform.fatsecret.com/docs/guides, bevor du dich darauf verlässt; es könnten echte Korrekturen nötig sein, nicht nur eine Verifizierung.Committe niemals echte FatSecret-Zugangsdaten und führe diese Checkliste niemals in CI aus.
Umgebungsvariablen
Variable | Zweck |
| OAuth 2.0 Client Credentials — Signed-Request-Methoden (Such-/Detail-Tools) |
| Optional. Leerzeichengetrennte OAuth2-Scope(s), Standard |
| Optional. Standardmäßig |
| OAuth 1.0 Consumer Key/Secret — signiert sowohl das einmalige Einrichtungsskript als auch jeden Signed-&-Delegated-Aufruf |
| OAuth 1.0 Access Token/Secret für dein FatSecret-Konto — erhalten über |
| Gemeinsames Geheimnis, das dieser Server bei jeder Anfrage verlangt, sowie das access_token, das unser OAuth-Flow ausstellt |
| Zugangsdaten für den eigenen minimalen OAuth-Autorisierungsserver dieses Servers |
| Optional. Kommagetrennte Allowlist für die |
Trage sie in den Umgebungsvariablen des Vercel-Projekts ein (Production + Preview). Committe niemals echte Werte — .env.example dokumentiert nur die Namen.
Bereitstellung
vercel linkvercel env add FATSECRET_CLIENT_ID(wiederhole dies für jede Variable in der obigen Tabelle, für die du einen Wert hast — mindestensFATSECRET_CLIENT_ID/SECRET,MCP_BEARER_TOKEN,OAUTH_CLIENT_ID/SECRET; füge das PaarFATSECRET_CONSUMER_*/FATSECRET_ACCESS_TOKEN*hinzu, sobald du das OAuth1-Einrichtungsskript ausgeführt hast)Verbinde dieses GitHub-Repository im Vercel-Dashboard für automatisches Deployment bei Push auf
main, oder führevercel --prodmanuell aus.Notiere die bereitgestellte URL (prüfe Projekt → Einstellungen → Domains, da
fatsecret-mcp.vercel.appim gemeinsamen Vercel-Namespace möglicherweise bereits vergeben ist).Nimm die ausgehende IP dieses Deployments in die Allowlist auf in der FatSecret-Entwicklerkonsole für OAuth2-Token-Anfragen (siehe Setup-Schritt 1) — das ist der Schritt, der in der Produktion am ehesten Probleme verursacht, da Vercel-Serverless-Funktionen standardmäßig keine feste IP haben.
Mit Claude verbinden
Benutzerdefinierte Connectors können nur von claude.ai (Web) oder der Desktop-App hinzugefügt werden — nicht von der Mobile-App. Sobald sie dort hinzugefügt wurden, sind sie automatisch auch mobil nutzbar.
Auf claude.ai: Einstellungen → Connectors → Benutzerdefinierten Connector hinzufügen.
Name:
FatSecret. URL:https://<your-deployment>/api/mcp.Falls dein Konto die Beta-Funktion „Request headers“ hat: füge dort
Authorization: Bearer <MCP_BEARER_TOKEN>hinzu und fahre mit Schritt 5 fort.Andernfalls öffne die erweiterten Einstellungen und trage unter OAuth Client ID / OAuth Client Secret die Werte
OAUTH_CLIENT_ID/OAUTH_CLIENT_SECRETein, die in Vercel festgelegt wurden. Claude erkennt die Endpunkte/authorizeund/tokenautomatisch über die.well-known-Metadaten dieses Servers.Speichern. Claude sollte die 17 Tools oben auflisten.
Versuche zu fragen: „バナナのカロリーを教えて“ (sag mir, wie viele Kalorien eine Banane hat), oder „今日の朝食にバナナを1本記録して“ (logge eine Banane für das heutige Frühstück — sobald Phase 3/4 eingerichtet und verifiziert sind).
Danksagungen
Das Design des 3-Leg-OAuth1-Flows wurde von fcoury/fatsecret-mcp (MIT) inspiriert, das den OAuth-Flow selbst als MCP-Tools bereitstellt; dieses Projekt führt ihn stattdessen einmalig als eigenständiges Einrichtungsskript (scripts/fatsecret-oauth-setup.ts) aus, da es für ein einzelnes persönliches FatSecret-Konto und nicht für die Nutzung durch mehrere Benutzer ausgelegt ist. Es wurde kein Code daraus übernommen.
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
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
MCP server for Withings health data — sleep, activity, heart, and body metrics.
GibsonAI MCP server: manage your databases with natural language
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/ikeike443/fatsecret-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server