fatsecret-mcp
by alien-agent
README.md
# fatsecret-mcp
An MCP server that gives any LLM agent read-only access to FatSecret's food and recipe database — the same data the FatSecret mobile app uses. It was built by reverse-engineering the app's private API, where it turned out the read endpoints (search and detail lookup) accept requests with no authentication at all. So there is zero setup: no API keys, no OAuth, no account. Deployed as a Cloudflare Worker exposing an HTTP MCP endpoint. Two tools: `search_food` (paginated search with per-item macros) and `get_food` (full nutrient breakdown plus all serving sizes), both returning compact Markdown to keep token usage low.
> Unofficial project, not affiliated with or endorsed by FatSecret. It talks to a private, reverse-engineered API that isn't a public contract — endpoints may change or get blocked without notice. Intended for personal/educational use.
**Auth.** claude.ai's custom-connector UI only supports "no auth" or full OAuth 2.1 — there's no plain bearer-token/API-key field ([anthropics/claude-ai-mcp#112](https://github.com/anthropics/claude-ai-mcp/issues/112), [#411](https://github.com/anthropics/claude-ai-mcp/issues/411)). Running real OAuth for a personal read-only proxy is disproportionate, so instead the Worker only responds on one path: a long random secret (`SECRET_PATH`), set with `wrangler secret put SECRET_PATH` and never committed. Every other path — including bare `/` — returns a plain 404, identical whether the path is wrong or just doesn't exist, so a wrong guess doesn't confirm anything. The full connector URL (`https://<your-worker>.workers.dev/<secret>`) is itself the credential: paste that whole URL into claude.ai, and treat it like a password. This is obscurity, not cryptographic auth — fine for a personal, read-only, non-sensitive proxy; rotate the secret (`wrangler secret put SECRET_PATH` again) if the URL ever leaks.
## Tools
- **`search_food(query, page?, language?, market?)`** — free-text search across foods and recipes. Returns a Markdown table: id, title, source, kcal, protein_g, fat_g, carbs_g, portion (the gram weight the macros are for, or a serving description for the rare recipe with no gram weight at all). The macros are usually enough to answer on their own — call `get_food` only for micronutrients or when the user's quantity doesn't match the row's portion.
- **`get_food(id, language?, market?)`** — full nutrient breakdown (fiber, sugar, sodium_mg, potassium_mg, calcium_mg, iron_mg, vitamin_a_iu, vitamin_c_mg, ...) and every serving size for an id from `search_food`, with the serving the nutrients were computed for marked `(base)`.
FatSecret's own search data pairs the macros' gram weight with an *unrelated* named serving (e.g. `gramsPerPortion=100` shown next to a "1 medium banana" default label that's actually 118g) — so `search_food`'s portion column deliberately shows only the verified number, never a serving name paired with it. `get_food` cross-checks its serving table by gram weight before marking one `(base)`, so it never asserts an unverified pairing either.
`language` (e.g. `"ru"`, `"en"`) and `market` (e.g. `"RU"`, `"US"`, `"GB"`) are optional per-call parameters — FatSecret's catalog and translations are regionalized, so set them to match the user; omit both for a generic international result set.
## Run / deploy
```
npm install
openssl rand -hex 24 | npx wrangler secret put SECRET_PATH # once, or to rotate
npm run deploy # deploy to Cloudflare (needs CLOUDFLARE_API_TOKEN / CLOUDFLARE_ACCOUNT_ID)
```
For local dev, put the same value in a `.dev.vars` file (`SECRET_PATH=...`, gitignored) and run `npm run dev` — `http://localhost:8787/`.
The deployed Worker exposes a single MCP endpoint at `https://<your-worker>.workers.dev/<SECRET_PATH>`: POST a JSON-RPC 2.0 message (`initialize`, `tools/list`, `tools/call`) to it. That full URL is what you paste into claude.ai's custom connector setup.
## Known limitations
- Read-only: no diary writes, no custom foods, no login, no per-user account — every call reads the same shared public database anonymously.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessSyncing