fatsecret-mcp
fatsecret-mcp
Un servidor MCP (Model Context Protocol) remoto y personal que permite a Claude buscar en la base de datos de alimentos/recetas de FatSecret y leer/escribir tu propio diario de alimentos, peso y registro de ejercicio directamente en la conversación. Desplegado en el nivel gratuito Hobby de Vercel. Proyecto hermano de fitness-mcp (Hevy): un servidor MCP por producto, que comparte el mismo patrón de autenticación.
Licencia
Estado
Búsqueda (Fase 2): implementada:
search_foods,get_food_detail,search_recipes,get_recipe_detail,find_food_by_barcode. No se necesita autorización de usuario de FatSecret; solo el ID/Secreto de cliente de OAuth 2.0 de la consola de desarrollador de FatSecret.Diario/peso/ejercicio/perfil (Fase 4): implementada, pero sin verificar con una cuenta real de FatSecret; no existía ningún registro de la API de FatSecret cuando se construyó esto (consulta «Qué no está verificado» más abajo). Confirma los nombres exactos de los campos de cada método con una cuenta real antes de confiar en él, y actualiza el código/las pruebas si algo no cuadra.
Script de configuración OAuth1 de tres patas (Fase 3): implementado (
scripts/fatsecret-oauth-setup.ts), aún no ejecutado contra una cuenta real de FatSecret.
Dos capas de autenticación
Este servidor se sitúa entre Claude y FatSecret, y cada una de esas dos relaciones se autentica de forma completamente distinta: es lo principal que hay que entender antes de tocar el código.
Claude <──①── this server (fatsecret-mcp) ──②──> FatSecret API① Claude ↔ este servidor: un único secreto compartido, mismo patrón que fitness-mcp. Claude envía Authorization: Bearer <MCP_BEARER_TOKEN> en cada petición; lib/auth.ts lo comprueba. Dado que la opción de cabecera estática de Claude sigue estando detrás de un beta, este servidor también ejecuta su propio servidor de autorización OAuth 2.1 mínimo (lib/oauth.ts, /api/oauth/authorize, /api/oauth/token) para que los campos estándar de ID/Secreto de cliente de OAuth de Claude funcionen como respaldo siempre disponible; consulta el README de fitness-mcp para ver el razonamiento completo, que se aplica aquí sin cambios.
② este servidor ↔ FatSecret: aquí es donde se vuelve más complejo que fitness-mcp, porque el propio FatSecret usa dos versiones diferentes de OAuth para dos tipos distintos de métodos de API, y no hay forma de evitarlo: así está diseñada la API de FatSecret, no es una decisión tomada aquí.
Categoría de método de FatSecret | Métodos de ejemplo | Cómo autentica este servidor |
Solicitud firmada (sin usuario concreto implicado) |
| OAuth 2.0 credenciales de cliente — |
Solicitud firmada y delegada (lee/escribe tu cuenta de FatSecret) |
| OAuth 1.0a, de tres patas, firmado con HMAC-SHA1 — |
En concreto: search_foods/get_food_detail/search_recipes/get_recipe_detail/find_food_by_barcode funcionan en cuanto registras una aplicación de FatSecret y estableces FATSECRET_CLIENT_ID/FATSECRET_CLIENT_SECRET. Todas las demás herramientas necesitan además FATSECRET_CONSUMER_KEY/FATSECRET_CONSUMER_SECRET (OAuth1: un par de credenciales diferente de la misma aplicación de FatSecret) y FATSECRET_ACCESS_TOKEN/FATSECRET_ACCESS_TOKEN_SECRET (obtenidos ejecutando el script de configuración una vez).
Herramientas expuestas
Herramienta | Tipo | Autenticación necesaria | Descripción |
| lectura | OAuth2 (aplicación) | Busca en la base de datos de alimentos de FatSecret por nombre |
| lectura | OAuth2 (aplicación) | Información nutricional completa por ración de un alimento |
| lectura | OAuth2 (aplicación) | Busca en la base de datos de recetas de FatSecret |
| lectura | OAuth2 (aplicación) | Ingredientes e instrucciones completos de una receta |
| lectura | OAuth2 (aplicación) | Resuelve un código de barras GTIN-13 a un foodId: necesita el ámbito |
| lectura | OAuth1 (usuario) | Lista las entradas del diario de alimentos de una fecha |
| lectura | OAuth1 (usuario) | Lista los alimentos favoritos |
| lectura | OAuth1 (usuario) | Lista los alimentos más consumidos, opcionalmente por comida |
| lectura | OAuth1 (usuario) | Lista los alimentos consumidos recientemente, opcionalmente por comida |
| lectura | OAuth1 (usuario) | Lista las entradas de peso de un mes — posiblemente solo Premier |
| lectura | OAuth1 (usuario) | Lista las entradas de ejercicio de una fecha |
| lectura | OAuth1 (usuario) | Obtiene el resumen del perfil de FatSecret del usuario |
| escritura | OAuth1 (usuario) | Registra un alimento en el diario |
| escritura | OAuth1 (usuario) | Actualiza una entrada existente del diario |
| escritura | OAuth1 (usuario) | Elimina una entrada del diario |
| escritura | OAuth1 (usuario) | Registra/actualiza una entrada de peso — posiblemente solo Premier |
| escritura | OAuth1 (usuario) | Registra una entrada de ejercicio |
Las herramientas de escritura son de ejecución en seco por defecto
Mismo diseño que fitness-mcp: cada herramienta de escritura requiere un argumento confirm: true. Sus descripciones indican al LLM que llama que muestre al usuario exactamente qué se va a escribir y obtenga primero su aprobación explícita. Es un empujón estructural, no una garantía: el mismo LLM que decide si llamar a la herramienta también establece confirm, y no hay separación de ámbitos entre herramientas de lectura y escritura en la capa de autenticación, por lo que cualquier llamador que tenga un MCP_BEARER_TOKEN válido puede invocar cualquier herramienta.
Qué no está verificado
No existía ningún registro de la API de FatSecret cuando se construyó este proyecto (ese paso requiere una persona: consulta Configuración más abajo), por lo que:
Los nombres de método y los parámetros principales de
search_foods/get_food_detail/search_recipes/get_recipe_detail/profile.get/food_entries.get/weights.get_monthestán confirmados con implementaciones de clientes FatSecret de terceros que funcionan (no son suposiciones); consulta el historial de git para ver las fuentes.La forma de la respuesta de
food.find_id_for_barcode, los nombres de los parámetros deweight.updatey todoexercise_entries.*son reconstrucciones de mejor esfuerzo, marcadas en línea enlib/fatsecret/*.tscon el razonamiento. Trátalas como un buen punto de partida, no como una verdad verificada.Ejecuta la lista de comprobación de verificación manual que aparece a continuación con una cuenta real después de registrarte y corrige cualquier discrepancia en los nombres de los campos que encuentres (las pruebas unitarias en
lib/fatsecret/*.test.tsnecesitarán actualizaciones correspondientes).
Configuración
Registra una aplicación de la API de la plataforma FatSecret en https://platform.fatsecret.com/. Obtendrás:
Un ID/Secreto de cliente de OAuth 2.0 (para
FATSECRET_CLIENT_ID/FATSECRET_CLIENT_SECRET).Una Clave/Secreto de consumidor de OAuth 1.0 (para
FATSECRET_CONSUMER_KEY/FATSECRET_CONSUMER_SECRET): un par independiente de la misma aplicación, no el mismo que las credenciales OAuth2 anteriores.Comprueba qué ámbitos incluye tu plan (
basic/premier/barcode/ ...) — se ha informado de queweights.get_month/weight.update/find_food_by_barcoderequieren Premier o los ámbitosbarcode/premier; confírmalo con tu propio plan y ajustaFATSECRET_OAUTH2_SCOPEsi es necesario.Autoriza en lista blanca tu(s) IP(s) de salida para las peticiones de token OAuth2: FatSecret lo exige (hasta 15 direcciones/rangos). Si despliegas en Vercel, necesitas una IP de salida estática (p. ej., mediante un proxy/complemento de salida compatible con Vercel); las funciones serverless por defecto de Vercel no tienen una IP fija.
Ejecuta el servidor de desarrollo local una vez para hacer una prueba rápida de búsqueda (la Fase 2 solo necesita el paso 1):
npm install
cp .env.example .env.local # fill in FATSECRET_CLIENT_ID/SECRET + the MCP_BEARER_TOKEN/OAuth trio
vercel devEjecuta la configuración OAuth1 de tres patas una sola vez (necesaria para todas las herramientas excepto las 5 de búsqueda/detalle): consulta la Fase 3 más abajo.
Despliega en Vercel: consulta Despliegue más abajo.
Desarrollo local
npm install
cp .env.example .env.local # fill in real values
vercel devPrueba rápida (reemplaza $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"}'Debería devolver las 17 herramientas anteriores. Una petición con un token ausente o incorrecto debería devolver 401.
Fase 3: configuración única de OAuth1 de tres patas
Todas las herramientas excepto search_foods/get_food_detail/search_recipes/get_recipe_detail/find_food_by_barcode necesitan un token/secreto de acceso OAuth1 vinculado a tu cuenta de FatSecret. Obténlo una vez:
npm run fatsecret:oauth-setupEste (scripts/fatsecret-oauth-setup.ts) hará:
Solicita un token de petición no autorizado a FatSecret.
Imprime una URL de autorización: ábrela, inicia sesión en FatSecret y aprueba. FatSecret muestra un código de confirmación.
Te pide que pegues ese código y luego lo canjea por un token/secreto de acceso permanente.
Escribe
FATSECRET_ACCESS_TOKEN/FATSECRET_ACCESS_TOKEN_SECRETen.env.local.
A continuación, añade también esos mismos dos valores a las variables de entorno de Vercel (.env.local nunca se despliega); consulta Despliegue más abajo.
Según la documentación de FatSecret, este token de acceso no expira. Si alguna vez se revoca (p. ej., eliminas el acceso de la aplicación desde la configuración de tu cuenta de FatSecret), simplemente vuelve a ejecutar el script para obtener uno nuevo; en espíritu, sigue el patrón derive() de fitness-mcp: perder una credencial aquí no es un desastre, es una solución de un solo comando, aunque esta vez interactiva en lugar de una rederivación determinista.
Generando los secretos para Claude a partir de una única frase de contraseña memorable
MCP_BEARER_TOKEN, OAUTH_CLIENT_ID y OAUTH_CLIENT_SECRET (capa ① — Claude ↔ este servidor, no relacionadas con las credenciales de FatSecret anteriores) pueden derivarse todas de forma determinista a partir de una única frase de contraseña maestra, así que perder los valores almacenados no es un desastre: basta con volver a derivarlos:
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_SECRETLas cadenas de etiqueta no son secretas (es seguro mantenerlas en este README); solo lo es la frase de contraseña. Volver a ejecutar derive con la misma frase de contraseña reproduce siempre los mismos valores. Esto no se aplica a las credenciales del lado de FatSecret (FATSECRET_CLIENT_ID/SECRET, FATSECRET_CONSUMER_KEY/SECRET, FATSECRET_ACCESS_TOKEN/SECRET), que provienen de la consola de desarrollador de FatSecret y del script de configuración de OAuth1, no de esta frase de contraseña.
Pruebas
Tres capas, todas ejecutadas en CI (.github/workflows/ci.yml) en cada push/PR: ninguna requiere secretos reales de FatSecret, por lo que funcionan igual en un repositorio público:
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)Pruebas unitarias (
lib/**/*.test.ts): verificación del token de portador, firma de código OAuth2.1/PKCE/lista blanca de URI de redirección (incluido el vector de prueba RFC 7636), obtención/caché/refresco del token de OAuth2 Client Credentials de FatSecret (lib/fatsecret/appAuth.test.ts), firma OAuth1 HMAC-SHA1 contrastada con una reimplementación independiente (lib/fatsecret/oauth1.test.ts) y normalización de la forma de respuesta de todos loslib/fatsecret/*.ts(objeto único frente a array, cadena numérica frente a número, peculiaridades de respuesta vacía).Integración (
test/integration/*.test.ts): el manejador realapp/api/mcp/route.tsconectado a los módulos realeslib/fatsecret/*con solofetchsimulado, cubriendo tanto las rutas de herramientas OAuth2 (Signed Request) como OAuth1 (Signed & Delegated), y la confirmación obligatoria en cada herramienta de escritura; las rutas reales/api/oauth/authorize//api/oauth/token; las rutas de metadatos OAuth.well-known.E2E (
test/e2e/*.e2e.test.mjs): arranca la compilación de producción y verifica a través de HTTP real: comprobación de salud, 401 ante autenticación incorrecta o ausente,tools/listdevuelve las 17 herramientas, metadatos de descubrimiento OAuth y un recorrido completo de código de autorización + PKCE. No utiliza datos reales de FatSecret (CI no tiene credenciales reales por diseño).
Verificación manual con una cuenta real de FatSecret
CI nunca toca datos reales de FatSecret y, según «Lo que no está verificado» más arriba, algunas suposiciones de este servidor sobre las formas exactas de respuesta de FatSecret no se han comprobado contra una cuenta real en absoluto. Tras registrarte y ejecutar el script de configuración de OAuth1, recorre esta lista de comprobación y corrige cualquier discrepancia que encuentres:
Establece los valores reales de
FATSECRET_CLIENT_ID/FATSECRET_CLIENT_SECRETen.env.local, ejecutavercel devy llama asearch_foodscon una consulta real (p. ej., mediante el patróncurlde prueba de humo de más arriba, usandotools/call); confirma que llegan resultados reales y queget_food_detailsobre uno de ellos devuelve cifras nutricionales razonables.Llama a
search_recipesyget_recipe_detailde manera similar.Si tu plan incluye el ámbito
barcode, llama afind_food_by_barcodecon el código de barras de un producto real y confirma que la forma de la respuesta coincide conRawFindIdForBarcodeResponsedelib/fatsecret/foods.ts; corrígelo si no es así.Ejecuta
npm run fatsecret:oauth-setupy luego llama aget_profileyget_food_diary; confirma que los nombres de los campos enlib/fatsecret/profile.ts/lib/fatsecret/diary.tscoinciden con la respuesta real (se reconstruyeron a partir de la documentación, no se capturaron).Llama a
create_food_diary_entryconconfirm: truey una entrada claramente desechable, luego aget_food_diarypara la misma fecha y confirma que aparece con el alimento/ración/cantidad/comida correctos. Después, hazupdate_food_diary_entrysobre ella ydelete_food_diary_entry; confirma que cada operación completa el ciclo correctamente.Si tu plan incluye el seguimiento de peso, llama a
update_weightconconfirm: truey confirma queget_weight_historylo refleja.create_exercise_entryyget_exercise_diaryson la pareja menos verificada de esta base de código (consulta la advertencia al principio delib/fatsecret/exercise.ts); confirma el nombre y los parámetros exactos del método en https://platform.fatsecret.com/docs/guides antes de confiar en ella; puede que necesite correcciones reales, no solo verificación.Nunca hagas commit de credenciales reales de FatSecret y nunca ejecutes esta lista de comprobación en CI.
Variables de entorno
Variable | Propósito |
| OAuth 2.0 Client Credentials — métodos Signed Request (herramientas de búsqueda/detalle) |
| Opcional. Ámbito(s) OAuth2 separados por espacios; por defecto |
| Opcional. Por defecto es |
| OAuth 1.0 Consumer Key/Secret: firma tanto el script de configuración único como cada llamada Signed & Delegated. |
| Token y secreto de acceso OAuth 1.0 para tu cuenta de FatSecret; se obtienen mediante |
| Secreto compartido que este servidor exige en cada solicitud y el access_token que emite nuestro flujo OAuth. |
| Credenciales para el servidor de autorización OAuth mínimo de este servidor. |
| Opcional. Lista blanca separada por comas para el |
Configúralas en las Variables de Entorno del proyecto de Vercel (Production + Preview). Nunca hagas commit de valores reales: .env.example solo documenta los nombres.
Despliegue
vercel linkvercel env add FATSECRET_CLIENT_ID(repítelo para cada variable de la tabla anterior de la que tengas un valor; como mínimoFATSECRET_CLIENT_ID/SECRET,MCP_BEARER_TOKEN,OAUTH_CLIENT_ID/SECRET; añade el parFATSECRET_CONSUMER_*/FATSECRET_ACCESS_TOKEN*una vez que hayas ejecutado el script de configuración de OAuth1).Conecta este repositorio de GitHub en el panel de Vercel para el despliegue automático al hacer push a
main, o ejecutavercel --prodmanualmente.Anota la URL del despliegue (consulta Proyecto → Configuración → Dominios, ya que
fatsecret-mcp.vercel.apppuede estar ya ocupado en el espacio de nombres compartido de Vercel).Añade la IP saliente de ese despliegue a la lista blanca en la consola de desarrollador de FatSecret para las solicitudes de token OAuth2 (consulta el paso 1 de Configuración): es el paso que con más probabilidad causa problemas en producción, ya que las funciones serverless de Vercel no tienen una IP fija por defecto.
Conectar con Claude
Los conectores personalizados solo se pueden añadir desde claude.ai (web) o la aplicación de escritorio, no desde la aplicación móvil. Una vez añadidos allí, se pueden utilizar desde el móvil automáticamente.
En claude.ai: Configuración → Conectores → Añadir conector personalizado.
Nombre:
FatSecret. URL:https://<your-deployment>/api/mcp.Si tu cuenta tiene la beta de «Encabezados de solicitud»: añade
Authorization: Bearer <MCP_BEARER_TOKEN>allí y salta al paso 5.De lo contrario, abre la configuración avanzada y rellena ID de cliente OAuth / Secreto de cliente OAuth con los valores
OAUTH_CLIENT_ID/OAUTH_CLIENT_SECRETconfigurados en Vercel. Claude descubrirá automáticamente los endpoints/authorizey/tokena través de los metadatos.well-knownde este servidor.Guarda. Claude debería mostrar las 17 herramientas anteriores.
Prueba a preguntar: «バナナのカロリーを教えて» (dime las calorías de un plátano) o «今日の朝食にバナナを1本記録して» (registra un plátano para el desayuno de hoy, una vez que la fase 3/4 esté configurada y verificada).
Agradecimientos
El diseño del flujo OAuth1 de tres patas se inspiró en fcoury/fatsecret-mcp (MIT), que expone el flujo OAuth como herramientas MCP; este proyecto, en cambio, lo ejecuta una sola vez como script de configuración independiente (scripts/fatsecret-oauth-setup.ts), ya que está pensado para una única cuenta personal de FatSecret en lugar de un uso multiusuario. No se copió código de él.
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