Skip to main content
Glama

log_meal

Add a meal to the user's food diary: one or more food items, each with an optional quantity and macros, plus an optional meal label, date, note and provenance source. The reply names the new entry's id and local_date, which identify it for a later edit or deletion. A restaurant meal's numbers depend most on the restaurant, the specific menu item, its size and its add-ons (cheese, fries, sauce, dressing); a bare dish name is logged as a typical serving. When the user names one of their saved recipes ("my chicken and rice", "half my chili"), send their words as one item's name, with any amount in quantity; Forkmate logs the recipe's own foods and numbers in its place. Portion amounts are checked against the user's own words for the meal when they arrive in said, and the reply lists each food with the amount it was logged at. All calorie and macro values, including carbohydrates, are estimates from USDA FoodData Central, Open Food Facts, the user's own entry or an AI assistant's estimate — approximate, not lab-measured or specific to a package or batch, and not suitable for insulin dosing (including carb counting for a meal bolus), blood-glucose prediction or any other medical decision.

Input Schema

NameRequiredDescriptionDefault
atNoISO-8601 instant the meal was eaten; defaults to now.
mealNoWhich meal of the day this was.
noteNoOptional free-text note stored with the meal, e.g. 'post-run'.
saidNoThe amounts are checked against this: the user's own words for this meal, verbatim (e.g. 'a pint of IPA and wings at the bar'). Only the meal description — not other parts of the conversation. Optional; without it, the amounts are logged as sent.
itemsYesThe foods in this meal, one entry per food.
sourceNoOptional provenance for these items: the `source` label of the food-database candidate they came from ('USDA', 'Open Food Facts', 'Forkmate' or 'product label'), or 'estimate'. Defaults to 'estimate'; unrecognized values are recorded as an estimate.
local_dateNoYYYY-MM-DD diary date; defaults to the user's local date (from their timezone).

Output Schema

NameRequiredDescriptionDefault
entryYesOne diary entry: a meal with its foods.
day_totalsYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / items / items / properties / caffeine_mg / description
      Previous value: -"Optional caffeine content of this item, in milligrams (e.g. ~95 for a mug of brewed coffee)."New value: +"Optional caffeine content of this item, in milligrams (e.g. ~95 for an 8 oz brewed coffee). If you omit it, Forkmate fills it from the label or its reference table when it knows the drink."
  2. Changed1 schema field changed
    • changedInput schema / properties / items / items / properties / macros / description
      Previous value: -"Estimated nutrition for the portion eaten. Omitted fields are looked up from the food databases."New value: +"Estimated nutrition for the portion eaten. Omitted fields are looked up from the food databases. Without this object, kcal (or calories), protein_g, carb_g (or carbs_g) and fat_g set on the item itself are read as these macros."
  3. Changed1 schema field changed
    • changedInput schema / properties / said / description
      Previous value: -"Optional. The user's own words describing this meal, verbatim (e.g. 'a pint of IPA and wings at the bar'). Only the meal description — not other parts of the conversation."New value: +"The amounts are checked against this: the user's own words for this meal, verbatim (e.g. 'a pint of IPA and wings at the bar'). Only the meal description — not other parts of the conversation. Optional; without it, the amounts are logged as sent."
  4. Changed1 schema field changed
    • addedInput schema / properties / said
      Added value: +{
      +  "description": "Optional. The user's own words describing this meal, verbatim (e.g. 'a pint of IPA and wings at the bar'). Only the meal description — not other parts of the conversation.",
      +  "maxLength": 300,
      +  "type": "string"
      +}
  5. Changed2 schema fields changed
    • changedInput schema / properties / source / description
      Previous value: -"Optional provenance for these items: the `source` label of the food-database candidate they came from ('USDA', 'Open Food Facts' or 'Forkmate'), or 'estimate'. Defaults to 'estimate'; unrecognized values are recorded as an estimate."New value: +"Optional provenance for these items: the `source` label of the food-database candidate they came from ('USDA', 'Open Food Facts', 'Forkmate' or 'product label'), or 'estimate'. Defaults to 'estimate'; unrecognized values are recorded as an estimate."
    • changedInput schema / properties / source / enum
      Previous value: -[
      -  "USDA",
      -  "Open Food Facts",
      -  "Forkmate",
      -  "estimate"
      -]New value: +[
      +  "USDA",
      +  "Open Food Facts",
      +  "Forkmate",
      +  "product label",
      +  "estimate"
      +]
  6. Changed6 schema fields changed
    • changedInput schema / properties / source / description
      Previous value: -"Optional provenance for these items, e.g. 'usda' or 'off' for a food-database result. Defaults to 'client' (an estimate); unrecognized values are recorded as 'client'."New value: +"Optional provenance for these items: the `source` label of the food-database candidate they came from ('USDA', 'Open Food Facts' or 'Forkmate'), or 'estimate'. Defaults to 'estimate'; unrecognized values are recorded as an estimate."
    • changedInput schema / properties / source / enum
      Previous value: -[
      -  "client",
      -  "usda",
      -  "off",
      -  "usda-index",
      -  "mfp-import",
      -  "manual",
      -  "chain-menu"
      -]New value: +[
      +  "USDA",
      +  "Open Food Facts",
      +  "Forkmate",
      +  "estimate"
      +]
    • removedOutput schema / properties / entry / properties / created_at
      Removed value: -{
      -  "type": "string"
      -}
    • addedOutput schema / properties / entry / properties / id / description
      Added value: +"Identifies the entry for a later edit or deletion."
    • removedOutput schema / properties / entry / properties / items / items / properties / source
      Removed value: -{
      -  "description": "Where the macros came from (e.g. usda, off, client).",
      -  "type": "string"
      -}
    • addedOutput schema / properties / entry / properties / items / items / properties / unknown_macros
      Added value: +{
      +  "description": "Macros missing from the source data: shown as 0 but unknown, not a real zero.",
      +  "items": {
      +    "enum": [
      +      "protein_g",
      +      "carb_g",
      +      "fat_g"
      +    ],
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  7. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "day_totals": {
      +      "properties": {
      +        "caffeine_mg": {
      +          "type": "number"
      +        },
      +        "entry_count": {
      +          "type": "integer"
      +        },
      +        "fluid_ml": {
      +          "type": "number"
      +        },
      +        "local_date": {
      +          "description": "A local date, YYYY-MM-DD.",
      +          "type": "string"
      +        },
      +        "totals": {
      +          "description": "Calories and macros. Estimates, not lab-measured; not for insulin dosing.",
      +          "properties": {
      +            "carb_g": {
      +              "type": "number"
      +            },
      +            "fat_g": {
      +              "type": "number"
      +            },
      +            "kcal": {
      +              "type": "number"
      +            },
      +            "protein_g": {
      +              "type": "number"
      +            }
      +          },
      +          "required": [
      +            "kcal",
      +            "protein_g",
      +            "carb_g",
      +            "fat_g"
      +          ],
      +          "type": "object"
      +        }
      +      },
      +      "required": [
      +        "local_date",
      +        "entry_count",
      +        "totals"
      +      ],
      +      "type": "object"
      +    },
      +    "entry": {
      +      "description": "One diary entry: a meal with its foods.",
      +      "properties": {
      +        "at": {
      +          "description": "ISO-8601 UTC instant the food was eaten.",
      +          "type": "string"
      +        },
      +        "created_at": {
      +          "type": "string"
      +        },
      +        "id": {
      +          "type": "string"
      +        },
      +        "items": {
      +          "items": {
      +            "properties": {
      +              "caffeine_mg": {
      +                "type": "number"
      +              },
      +              "fluid_ml": {
      +                "type": "number"
      +              },
      +              "macros": {
      +                "description": "Calories and macros. Estimates, not lab-measured; not for insulin dosing.",
      +                "properties": {
      +                  "carb_g": {
      +                    "type": "number"
      +                  },
      +                  "fat_g": {
      +                    "type": "number"
      +                  },
      +                  "kcal": {
      +                    "type": "number"
      +                  },
      +                  "protein_g": {
      +                    "type": "number"
      +                  }
      +                },
      +                "required": [],
      +                "type": "object"
      +              },
      +              "name": {
      +                "type": "string"
      +              },
      +              "quantity": {
      +                "type": "string"
      +              },
      +              "source": {
      +                "description": "Where the macros came from (e.g. usda, off, client).",
      +                "type": "string"
      +              }
      +            },
      +            "required": [
      +              "name"
      +            ],
      +            "type": "object"
      +          },
      +          "type": "array"
      +        },
      +        "local_date": {
      +          "description": "A local date, YYYY-MM-DD.",
      +          "type": "string"
      +        },
      +        "meal": {
      +          "description": "breakfast, lunch, dinner or snack, when set.",
      +          "type": "string"
      +        },
      +        "note": {
      +          "type": "string"
      +        }
      +      },
      +      "required": [
      +        "id",
      +        "at",
      +        "local_date",
      +        "items"
      +      ],
      +      "type": "object"
      +    }
      +  },
      +  "required": [
      +    "entry",
      +    "day_totals"
      +  ],
      +  "type": "object"
      +}
  8. Changed10 schema fields changed
    • addedInput schema / properties / items / description
      Added value: +"The foods in this meal, one entry per food."
    • addedInput schema / properties / items / items / properties / barcode / description
      Added value: +"The package's UPC/EAN barcode, when the food came from a barcode lookup."
    • addedInput schema / properties / items / items / properties / macros / description
      Added value: +"Estimated nutrition for the portion eaten. Omitted fields are looked up from the food databases."
    • addedInput schema / properties / items / items / properties / macros / properties / carb_g / description
      Added value: +"Total carbohydrate for the whole portion eaten, in grams."
    • addedInput schema / properties / items / items / properties / macros / properties / fat_g / description
      Added value: +"Total fat for the whole portion eaten, in grams."
    • addedInput schema / properties / items / items / properties / macros / properties / kcal / description
      Added value: +"Energy for the whole portion eaten, in kilocalories (not per 100 g)."
    • addedInput schema / properties / items / items / properties / macros / properties / protein_g / description
      Added value: +"Protein for the whole portion eaten, in grams."
    • addedInput schema / properties / items / items / properties / name / description
      Added value: +"What the food is, e.g. 'scrambled eggs' or 'Greek yogurt, plain'."
    • addedInput schema / properties / meal / description
      Added value: +"Which meal of the day this was."
    • addedInput schema / properties / note / description
      Added value: +"Optional free-text note stored with the meal, e.g. 'post-run'."
  9. Changed5 schema fields changed
    • changedInput schema / properties / items / items / properties / caffeine_mg / description
      Previous value: -"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."New value: +"Optional caffeine content of this item, in milligrams (e.g. ~95 for a mug of brewed coffee)."
    • changedInput schema / properties / items / items / properties / fluid_ml / description
      Previous value: -"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."New value: +"Optional fluid/hydration volume of this item, in millilitres (e.g. 240 for an 8 oz cup)."
    • changedInput schema / properties / items / items / properties / quantity / description
      Previous value: -"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."New value: +"Portion as a display label, e.g. '3', '1 cup' or '2 × 1 frank (96 g)'. Display only: the server stores macros exactly as sent and does not re-scale them."
    • changedInput schema / properties / local_date / description
      Previous value: -"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."New value: +"YYYY-MM-DD diary date; defaults to the user's local date (from their timezone)."
    • changedInput schema / properties / source / description
      Previous value: -"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'."New value: +"Optional provenance for these items, e.g. 'usda' or 'off' for a food-database result. Defaults to 'client' (an estimate); unrecognized values are recorded as 'client'."
  10. Changed1 schema field changed
    • changedInput schema / properties / source / enum
      Previous value: -[
      -  "client",
      -  "usda",
      -  "off",
      -  "usda-index",
      -  "mfp-import",
      -  "manual"
      -]New value: +[
      +  "client",
      +  "usda",
      +  "off",
      +  "usda-index",
      +  "mfp-import",
      +  "manual",
      +  "chain-menu"
      +]
  11. Changed1 schema field changed
    • changedInput schema / properties / items / items / properties / quantity / description
      Previous value: -"Portion as stated, e.g. '3' or '1 cup'."New value: +"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."
  12. Changed2 schema fields changed
    • addedInput schema / properties / items / items / properties / caffeine_mg
      Added value: +{
      +  "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.",
      +  "type": "number"
      +}
    • addedInput schema / properties / items / items / properties / fluid_ml
      Added value: +{
      +  "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.",
      +  "type": "number"
      +}
  13. First observed

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well past the annotations (which only say it's a non-idempotent, non-destructive write) by disclosing the reply contents (`id` and `local_date` for later edit/delete), the recipe-substitution behavior, the `said` portion-checking behavior, and the provenance/estimate semantics including an explicit medical-use caveat. This is exactly the kind of context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and return value before moving to edge-case behaviors and disclaimers; each sentence carries information. The macro-source/medical disclaimer sentence is long and dense, which slightly dilutes scannability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter mutation tool with an output schema, nothing essential is missing: it covers write semantics, what identifies the new entry, portion validation, recipe handling, provenance defaults, and the estimate/medical caveat. An agent can call it correctly and know what to tell the user afterwards.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: the recipe-in-one-item convention, the role of `said` in validating amounts, and the fact that all macro values are approximations from named sources. It adds value beyond field-level schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource: 'Add a meal to the user's food diary', and enumerates what a meal consists of (items, optional label, date, note, source). This clearly separates it from update_meal and delete_meal, which act on an existing entry.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete operational guidance: how to handle restaurant meals (numbers depend on menu item/size/add-ons), how to log saved recipes (send the user's words as one item's name with amount in quantity), and how portions are validated against `said`. It stops short of explicitly routing between siblings (e.g., when to search_foods or lookup_barcode first, or when update_meal is the right call instead).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.