ForkMate
Log what you ate by talking to your AI assistant — calories and macros, completely free.
Should I use this
Quality & Safety
Findings (1)
- LOWin whoami
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"forkmate": {
"url": "https://app.forkmate.ai/mcp"
}
}
}Remote endpoints
https://app.forkmate.ai/mcpstreamable-httphttps://mcp.forkmate.ai/streamable-httpWhat it can do
Tool inventory
Tools (12)
🟢whoami
Diagnostic: returns the authenticated user id and scopes.
Input Schema
{
"type": "object",
"properties": {},
"additionalProperties": false
}🟢get_day(local_date)
Read the user's food diary for a day (entries + calorie/macro totals). SAFETY: all calorie and macro values here — including carbohydrates — are ESTIMATES (from USDA / Open Food Facts or the user's own entry), approximate and not lab-measured or per-batch. They are for general nutrition tracking ONLY. Do NOT use them for insulin dosing, carb-counting for a bolus, blood-glucose prediction, or any other medical decision, and do NOT compute a dose or glucose estimate from them. For anything medical, direct the user to the product's own label and their care team.
Input Schema
{
"type": "object",
"properties": {
"local_date": {
"type": "string",
"description": "YYYY-MM-DD; defaults to today."
}
}
}🟢get_range(start, end)
Read the user's diary across a date range, with per-day calorie/macro totals. SAFETY: all calorie and macro values here — including carbohydrates — are ESTIMATES (from USDA / Open Food Facts or the user's own entry), approximate and not lab-measured or per-batch. They are for general nutrition tracking ONLY. Do NOT use them for insulin dosing, carb-counting for a bolus, blood-glucose prediction, or any other medical decision, and do NOT compute a dose or glucose estimate from them. For anything medical, direct the user to the product's own label and their care team.
Input Schema
{
"type": "object",
"properties": {
"start": {
"type": "string",
"description": "YYYY-MM-DD (inclusive)."
},
"end": {
"type": "string",
"description": "YYYY-MM-DD (inclusive)."
}
},
"required": [
"start",
"end"
]
}🟢get_preferences
Read the user's saved dietary preferences so you can tailor logging and suggestions WITHOUT re-asking every chat: their diet style, a structured list of allergies to avoid (the big-9 major allergens), foods they dislike, and a typical-portion note. IMPORTANT: the allergen list is self-reported and is NOT a safety guarantee — always tell the user to check ingredient labels themselves; cross-contamination and gaps in food data are not captured (see the returned allergy_disclaimer). The `allergies` field covers the major US allergens ONLY; a user may have an allergen outside it (e.g. mustard, celery, corn, mollusks, barley/rye) — ask about those directly. NEVER treat the `dislikes` list as an allergy: it is a taste preference to de-prioritize, never a safety exclusion.
Input Schema
{
"type": "object",
"properties": {},
"additionalProperties": false
}🟢log_meal(items, meal, at, local_date, note, ...)
Log what the user ate to their food diary. Parse the user's free text into items and, when you can, include estimated macros per item for accuracy. SAFETY: all calorie and macro values here — including carbohydrates — are ESTIMATES (from USDA / Open Food Facts or the user's own entry), approximate and not lab-measured or per-batch. They are for general nutrition tracking ONLY. Do NOT use them for insulin dosing, carb-counting for a bolus, blood-glucose prediction, or any other medical decision, and do NOT compute a dose or glucose estimate from them. For anything medical, direct the user to the product's own label and their care team.
Input Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"quantity": {
"type": "string",
"description": "Portion as the user stated it, e.g. '3' or '1 cup'. When logging a search_foods/lookup_barcode candidate you scaled by its serving, write it as 'N × <serving_label> (<total_g> g)' to match the web app's diary — e.g. a candidate with serving_grams 48 and serving_label '1 frank', eaten ×2, becomes macros = the per-100 g figures × 0.96 (96 g total), quantity '2 × 1 frank (96 g)', and `source` set to that candidate's source. This field is a DISPLAY LABEL ONLY — you must still send the already-scaled macros; the server never re-scales them."
},
"barcode": {
"type": "string"
},
"macros": {
"type": "object",
"properties": {
"kcal": {
"type": "number"
},
"protein_g": {
"type": "number"
},
"carb_g": {
"type": "number"
},
"fat_g": {
"type": "number"
}
}
},
"caffeine_mg": {
"type": "number",
"description": "Optional caffeine content of this item, in milligrams (e.g. ~95 for a mug of brewed coffee). Include it for caffeinated drinks/foods when known; omit if unknown."
},
"fluid_ml": {
"type": "number",
"description": "Optional fluid/hydration volume of this item, in millilitres (e.g. 240 for an 8 oz cup). Include it for drinks when known; omit if unknown."
}
}
}
},
"meal": {
"type": "string",
"enum": [
"breakfast",
"lunch",
"dinner",
"snack",
"other"
]
},
"at": {
"type": "string",
"description": "ISO-8601 instant the meal was eaten; defaults to now."
},
"local_date": {
"type": "string",
"description": "YYYY-MM-DD diary date; defaults to the user's local date (from their timezone). Pass this to log a meal on a different day."
},
"note": {
"type": "string"
},
"source": {
"type": "string",
"enum": [
"client",
"usda",
"off",
"usda-index",
"mfp-import",
"manual",
"chain-menu"
],
"description": "Optional provenance for these items. After search_foods/lookup_barcode, pass the candidate's source class (e.g. 'usda' or 'off') so the diary shows it's grounded. Defaults to 'client' (your own estimate). Unrecognized values are recorded as 'client'."
}
},
"required": [
"items"
]
}🔴update_meal(id, local_date, item_index, name, quantity, ...)
Correct a food already logged to the user's diary — fix a wrong calorie/macro value, quantity, or name, or move an entry to a different meal. Identify the entry by its `id` and `local_date` (both from get_day) and the food by its `item_index` within that entry's items[]. Only the fields you send change; the macros you send are MERGED onto the existing ones (so sending just `kcal` leaves protein/carb/fat as they were). This overwrites the value IN PLACE — there is no history of the previous value. Editing never moves an entry to another day (to do that, delete and re-log). SAFETY: all calorie and macro values here — including carbohydrates — are ESTIMATES (from USDA / Open Food Facts or the user's own entry), approximate and not lab-measured or per-batch. They are for general nutrition tracking ONLY. Do NOT use them for insulin dosing, carb-counting for a bolus, blood-glucose prediction, or any other medical decision, and do NOT compute a dose or glucose estimate from them. For anything medical, direct the user to the product's own label and their care team.
Input Schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The entry id to edit (from get_day)."
},
"local_date": {
"type": "string",
"description": "YYYY-MM-DD diary date of the entry (from get_day)."
},
"item_index": {
"type": "number",
"description": "Which food in the entry's items[] to edit (0-based). Required when changing a food's name/quantity/macros/caffeine/fluid; omit for an entry-level change (meal/note)."
},
"name": {
"type": "string"
},
"quantity": {
"type": "string",
"description": "Portion as stated, e.g. '2' or '1 cup'."
},
"macros": {
"type": "object",
"description": "Corrected macros — only the components you send are changed.",
"properties": {
"kcal": {
"type": "number"
},
"protein_g": {
"type": "number"
},
"carb_g": {
"type": "number"
},
"fat_g": {
"type": "number"
}
}
},
"caffeine_mg": {
"type": "number",
"description": "Corrected caffeine content, in milligrams."
},
"fluid_ml": {
"type": "number",
"description": "Corrected fluid/hydration volume, in millilitres."
},
"meal": {
"type": "string",
"enum": [
"breakfast",
"lunch",
"dinner",
"snack",
"other"
],
"description": "Move the entry to a different meal label."
},
"note": {
"type": "string"
}
},
"required": [
"id",
"local_date"
]
}🔴delete_meal(id, local_date, item_index)
Delete a food from the user's diary — remove one food from an entry (by `item_index`), or the whole entry (omit `item_index`). Identify the entry by its `id` and `local_date` (both from get_day). This is a TRUE removal: the data is gone, with NO server-side tombstone and no undo. Deleting the last food in an entry removes the entry. Safe to retry — deleting something already gone is a no-op success. SAFETY: all calorie and macro values here — including carbohydrates — are ESTIMATES (from USDA / Open Food Facts or the user's own entry), approximate and not lab-measured or per-batch. They are for general nutrition tracking ONLY. Do NOT use them for insulin dosing, carb-counting for a bolus, blood-glucose prediction, or any other medical decision, and do NOT compute a dose or glucose estimate from them. For anything medical, direct the user to the product's own label and their care team.
Input Schema
{
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "The entry id to delete from (from get_day)."
},
"local_date": {
"type": "string",
"description": "YYYY-MM-DD diary date of the entry (from get_day)."
},
"item_index": {
"type": "number",
"description": "Which food to remove (0-based). Omit to delete the whole entry."
}
},
"required": [
"id",
"local_date"
]
}🟢get_pantry
Read the user's PANTRY — the foods they keep ON HAND (their staples), so you can suggest meals from what they actually have and pre-fill macros when they log one. Returns each item's name and, when the user saved them, macros (for the item's serving), a serving label, a `source`, and a short note. The pantry is the user's CURATED list of what they stock — separate from what they've logged (their diary) and from their frequents (what they log often). IMPORTANT: a `source` (e.g. 'usda') is the user's own CLAIM about where the macros came from, NOT a server-verified guarantee — treat it as a hint, never as certified.
Input Schema
{
"type": "object",
"properties": {},
"additionalProperties": false
}🟡add_pantry_item(name, macros, serving, source, note)
Add a food to the user's pantry, or UPDATE it if it's already there (matched by name, any casing) — e.g. 'add rolled oats to my pantry'. Only `name` is required; include `macros` (for one serving), a `serving` label, a `source`, and a short `note` when you know them, so a later log can reuse them. Re-adding the same food REPLACES its details (an upsert — it never creates a duplicate). Only pass a `source` you actually got from search_foods/lookup_barcode; an unrecognized value is recorded as the user's own estimate ('client'). This does NOT log a meal — it only curates the user's staples.
Input Schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The food to keep on hand, e.g. 'rolled oats'."
},
"macros": {
"type": "object",
"description": "Macros for ONE serving of this food, when known.",
"properties": {
"kcal": {
"type": "number"
},
"protein_g": {
"type": "number"
},
"carb_g": {
"type": "number"
},
"fat_g": {
"type": "number"
}
}
},
"serving": {
"type": "string",
"description": "Serving label the macros are for, e.g. '1 cup' or 'per 100 g'."
},
"source": {
"type": "string",
"enum": [
"client",
"usda",
"off",
"usda-index",
"mfp-import",
"manual",
"chain-menu"
],
"description": "Where the macros came from, if grounded via search_foods/lookup_barcode (e.g. 'usda'). Defaults to your own estimate ('client'); unrecognized values are recorded as 'client'."
},
"note": {
"type": "string",
"description": "Optional short note, e.g. 'the Costco tub'."
}
},
"required": [
"name"
],
"additionalProperties": false
}🔴remove_pantry_item(name)
Remove a food from the user's pantry by name — e.g. 'take eggs off my pantry list'. This removes it from their on-hand STAPLES only; it does NOT delete anything from their food diary. Safe to retry — removing something that isn't in the pantry is a no-op success.
Input Schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "The food to remove from the pantry (any casing)."
}
},
"required": [
"name"
],
"additionalProperties": false
}🟢search_foods(query, limit)
Search USDA FoodData Central and Open Food Facts for foods matching a query, returning candidates with macros and a `source` you can show the user. IMPORTANT: the macros are PER 100 g (see each candidate's `serving`) — scale them to the portion the user actually ate before logging with log_meal. A candidate MAY also carry `serving_grams`/`serving_label` for ONE household serving (e.g. 48 g / "1 frank") — when present, offer the user 'N servings' instead of asking for grams, but still scale the per-100 g macros to the resolved grams before logging. A curated chain-menu candidate carries a `provenance` object; when its `caveat` is present, relay it to the user verbatim — it is portion/build guidance (e.g. included cheese/mayo, scoop-size variance) that changes what they should log. When you log a chosen candidate, pass its `source` to log_meal so the diary records real provenance (USDA/Open Food Facts) instead of an estimate. SAFETY: all calorie and macro values here — including carbohydrates — are ESTIMATES (from USDA / Open Food Facts or the user's own entry), approximate and not lab-measured or per-batch. They are for general nutrition tracking ONLY. Do NOT use them for insulin dosing, carb-counting for a bolus, blood-glucose prediction, or any other medical decision, and do NOT compute a dose or glucose estimate from them. For anything medical, direct the user to the product's own label and their care team.
Input Schema
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Food to search, e.g. 'greek yogurt' or 'Chipotle chicken'."
},
"limit": {
"type": "number",
"description": "Max candidates to return (default 5, clamped to 1–10)."
}
},
"required": [
"query"
],
"additionalProperties": false
}🟢lookup_barcode(upc)
Look up a packaged food by its UPC/EAN barcode via Open Food Facts. IMPORTANT: the macros are PER 100 g (see `serving`) — scale to the portion eaten before logging with log_meal. It MAY also carry `serving_grams`/`serving_label` for one household serving — offer 'N servings' when present, still scaling the per-100 g macros before logging. Pass the returned `source` to log_meal to preserve provenance. SAFETY: all calorie and macro values here — including carbohydrates — are ESTIMATES (from USDA / Open Food Facts or the user's own entry), approximate and not lab-measured or per-batch. They are for general nutrition tracking ONLY. Do NOT use them for insulin dosing, carb-counting for a bolus, blood-glucose prediction, or any other medical decision, and do NOT compute a dose or glucose estimate from them. For anything medical, direct the user to the product's own label and their care team.
Input Schema
{
"type": "object",
"properties": {
"upc": {
"type": "string",
"description": "UPC/EAN barcode, digits only (8–14 digits)."
}
},
"required": [
"upc"
],
"additionalProperties": false
}Recommended Prompts
search_foodssearch_foodsget_dayget_daysearch_foodsupdate_mealCommunity
Evidence