log_meal
Durably logs one natural-language meal as one or more component rows. Send everything you have. When a food photo is available, include it in images[]; do not omit a photo you have. When no photo exists, ask the human and retry with confirm_no_photo=true. When exact values or calorie/protein estimates are available, include them. Optional evidence disclosure booleans help callers be explicit, but the receipt data_quality is based on actual payload contents.
| Parameter | Type | Required | Description |
|---|
| description | string | yes | Plain-language meal description. Comma/semicolon/and-separated foods are itemized into separate rows when components are not supplied. |
| idempotency_key | string | no | Optional explicit replay key. Reusing the same key returns existing component rows instead of inserting duplicates. |
| external_id | string | no | Optional caller-owned external identifier with the same explicit replay behavior as idempotency_key. |
| evidence_disclosure | { has_photo?: boolean; has_exact_values?: boolean; has_agent_estimate?: boolean } | no | Optional honesty disclosure for available evidence. True values must be backed by matching input data. Omitted or false values never block logging by themselves; the server evaluates actual payload contents. |
| components | array | no | Optional explicit component list. Each component can include description, quantity, unit, exact calories/protein, agent estimate, and value_source. |
| images | string[] | no | Base64 encoded image strings or data URLs. Combined decoded image bytes must not exceed 3 MiB. For larger photos, POST to /api/mcp/images/upload with Authorization: Bearer <token> (multipart field "file" or raw body; max 30 MiB), then pass the returned url in image_urls. When a food photo is available, include it. When neither images nor image_urls are provided, confirm_no_photo=true is required after asking the human. |
| image_urls | string[] | no | Vercel Blob URLs from POST /api/mcp/images/upload (MCP/agent) or POST /api/nutrition/images/upload (browser) for photos larger than the base64 transport cap. Combined with images[], max 5 total. |
| exact_calories_kcal | number | no | Exact calories for a single-component call. Include when genuinely known from a label, receipt, menu, or trusted source. |
| exact_protein_g | number | no | Exact protein for a single-component call. Include when genuinely known from a label, receipt, menu, or trusted source. |
| agent_estimated_calories_kcal | number | no | Caller/agent calorie estimate for a single-component call. When you have made an estimate, include it; do not invent one to improve quality. |
| agent_estimated_protein_g | number | no | Caller/agent protein estimate for a single-component call. When you have made an estimate, include it; do not invent one to improve quality. |
| value_source | label | historical | agent_estimate | nim_estimate | manual | unknown | no | Source for supplied exact/caller values. Receipts show this per component. |
| meal_time | string | no | Optional ISO 8601 timestamp with offset for when the meal was eaten (e.g. 2026-06-28T14:00:00Z or 2026-06-28T20:00:00+06:00). Defaults to now. |
| confirm_backdate | boolean | no | Required as true when meal_time is more than ~10 minutes in the past. |
| confirm_no_photo | boolean | no | Required as true when logging without images[] or image_urls[] after asking the human and confirming no photo exists. |
| confirm_image_time_mismatch | boolean | no | Required as true when EXIF capture time differs from meal_time/logged time by more than 12 hours. |
Returns: Terminal receipt with meal group ID, data_quality { quality, reason, guidance }, every component row ID, value source, exact/agent/backend estimates, historical calibration, divergence flags, launch activity context, today totals, and verify URLs.
correct_meal
Creates an immutable correction for a logged meal. Include correction images when available. The original row is never updated, and the corrected row is inserted before queued backend NIM re-estimation.
| Parameter | Type | Required | Description |
|---|
| original_row_id | uuid | yes | nutrition_log.id of the row being corrected. |
| correction_text | string | yes | What was wrong and what the corrected food entry should be. |
| images | string[] | no | Base64 encoded correction images, including data URLs when available. Combined decoded image bytes must not exceed 3 MiB. For larger photos, POST to /api/mcp/images/upload then use image_urls on tools that accept them. |
| meal_time | string | no | Optional ISO 8601 timestamp with offset for the corrected meal time. Defaults to now. |
| confirm_backdate | boolean | no | Required as true when meal_time is more than ~10 minutes in the past. |
| confirm_image_time_mismatch | boolean | no | Required as true when correction image EXIF capture time differs from meal_time by more than 12 hours. |
Returns: Correction receipt with original entry, corrected pending entry, calorie/protein deltas, new row ID, queued backend NIM status, and verify URLs for both rows.
list_meals
Searches active nutrition_log meal rows by date range and/or description keyword. This is read-only and never estimates nutrition.
| Parameter | Type | Required | Description |
|---|
| start_date | string | no | Optional YYYY-MM-DD user-local date or ISO timestamp lower bound for logged_at. |
| end_date | string | no | Optional YYYY-MM-DD user-local inclusive date or ISO timestamp upper bound for logged_at. |
| keyword | string | no | Optional case-insensitive substring match against description. |
| limit | number | no | Maximum active rows to return, from 1 to 100. Defaults to 50. |
Returns: JSON array of matching rows with id, logged_at, description, calories, protein, and meal_group_id.
annotate_meal
Appends context to an existing meal by inserting an immutable nutrition_log row that references the original row. Calories and protein are copied unchanged and NIM is skipped.
| Parameter | Type | Required | Description |
|---|
| meal_id | uuid | yes | nutrition_log.id of the row receiving extra context. |
| context | string | yes | Context to append to the meal description. |
Returns: Annotation receipt with original entry, annotated entry, copied calories/protein, skipped NIM status, and verify URLs for both rows.
void_meal
Excludes a duplicate or invalid meal from active totals by inserting an immutable zero-calorie/zero-protein row that supersedes the original.
| Parameter | Type | Required | Description |
|---|
| meal_id | uuid | yes | nutrition_log.id of the row to exclude from active totals. |
| reason | string | no | Audit reason stored in raw_submission and notes. |
| idempotency_key | string | no | Optional caller replay key. Defaults to void:{meal_id}. |
Returns: Void receipt with original entry, immutable zero-value superseding row, active totals effect, and verify URLs for both rows.
track_metric
Tracks an observed manual health metric. Use the actual device/app/manual value available to you; do not fabricate missing measurements. Weight goes to body_measurements; others (water, caffeine, steps, etc.) go to health_metrics.
| Parameter | Type | Required | Description |
|---|
| metricType | weight | sleep | mood | steps | water | caffeine | yes | Metric category. |
| value | number | yes | Observed metric value. |
| unit | string | no | Unit label. For weight, pass kg or lb (lb converts to kg). Other metrics accept hours, steps, ml, oz, mg, etc. |
| measured_at | string | no | ISO timestamp with offset for weight. Defaults to now. |
| confirm_backdate | boolean | no | Required true when measured_at is more than 10 minutes in the past. |
Returns: Terminal receipt with inserted row ID, metric value, and timestamp.
get_user_history
Reads recent logged nutrition, body measurements, and health metrics for the single hardcoded user.
| Parameter | Type | Required | Description |
|---|
| metricType | meals | weight | sleep | mood | steps | water | caffeine | all | no | History category filter. |
| days | number | no | Lookback window from 1 to 90 days. Defaults to 7. |
| include_raw_fields | boolean | no | When true and metricType is weight or all, include raw_fields and unmapped key values on weight rows. |
Returns: JSON string containing matching history rows.
get_nutrition_guidance
Returns static evidence-based nutrition guidance by goal.
| Parameter | Type | Required | Description |
|---|
| goal | weight_loss | muscle_gain | maintenance | general_health | yes | Nutrition goal. |
| dietaryRestrictions | string[] | no | Optional restrictions. |
Returns: Plain text guidance.
import_apple_health
Imports a HealthAutoExport JSON payload into health_metrics.
| Parameter | Type | Required | Description |
|---|
| payload | object | yes | Full HealthAutoExport JSON payload. Rejected when the serialized payload exceeds the 4 MiB direct-import limit; use import_apple_health_document for larger exports. |
Returns: Terminal receipt with immutable import receipt row ID, timestamp, row counts, date range, metric names, and a verify URL.
import_apple_health_document
Hands off an OpenClaw Apple Health export document for asynchronous blob import job processing. Use when OpenClaw transport delivers a zip/json export by URL rather than inline HealthAutoExport JSON.
| Parameter | Type | Required | Description |
|---|
| original_filename | string | yes | Original export filename, e.g. HealthAutoExport.zip. |
| size_bytes | number | yes | Exact byte size of the document (max 100MB). |
| content_type | string | yes | MIME type such as application/zip or application/json. |
| blob_url | string | no | Vercel Blob URL when the document is already stored in blob storage. Provide exactly one of blob_url or file_url. |
| file_url | string | no | HTTPS URL on an allowed host when OpenClaw fetched the document elsewhere. Provide exactly one of blob_url or file_url. |
| blob_pathname | string | no | Optional blob pathname hint when using blob_url. |
Returns: Async handoff receipt with job_id, status (processing or failed), filename/size echo, and note that completion is import-job based. Poll GET /api/import/apple-health/jobs for completion.
import_document
Hands off an arbitrary document (scale export, spreadsheet, PDF, image) via blob_url or file_url for asynchronous universal import processing. Flag tier: caller should disclose uncertain file provenance when known.
| Parameter | Type | Required | Description |
|---|
| original_filename | string | yes | Original document filename. |
| size_bytes | number | yes | Exact byte size of the document (max 50MB). |
| content_type | string | yes | MIME type such as application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/pdf, or image/jpeg. |
| blob_url | string | no | Vercel Blob URL when the document is already stored. Provide exactly one of blob_url or file_url. |
| file_url | string | no | HTTPS URL on an allowed host when the document was fetched elsewhere. Provide exactly one of blob_url or file_url. |
Returns: Async handoff receipt with job_id and status. Poll GET /api/import/universal/jobs for completion. Low-confidence observations may require confirm_import_observations.
confirm_import_observations
Confirms and writes low-confidence universal import observations that were flagged on an import job. Without confirm_import_observations=true, returns the flagged rows and the exact boolean to set after asking the human.
| Parameter | Type | Required | Description |
|---|
| job_id | uuid | yes | import_jobs.id of the universal import job with flagged observations. |
| observation_indexes | number[] | no | Optional subset of flagged observation indexes to confirm. Defaults to all flagged observations. |
| confirm_import_observations | boolean | no | Must be true after human confirmation to write the flagged observations. |
Returns: Confirmation receipt with written/skipped counts, or an instructive gate listing flagged rows when confirm_import_observations is not true.
import_body_measurements
Imports body composition scale measurement payloads (spreadsheet row shape or compatible vendor measure-group JSON). Timestamps without an offset are interpreted in your configured timezone.
| Parameter | Type | Required | Description |
|---|
| payload | object | yes | Body composition scale measurement payload (row array, measurements object, or compatible vendor measure-group JSON). |
| source | string | no | Optional source label to persist with the row. |
| weight_unit | kg | lb | no | Unit for bare numeric weight/mass values when the payload does not carry a suffix. Defaults to kg. |
Returns: Terminal receipt with parsed/inserted/updated counts and preserved-but-unmapped field names (stored in raw_fields).
process_pending_nutrition
Retries pending or failed backend NIM enrichment for durable nutrition_log rows.
| Parameter | Type | Required | Description |
|---|
| limit | number | no | Maximum rows to process, from 1 to 50. Defaults to 10. |
Returns: Terminal receipt with checked, processed, failed, skipped counts and per-row statuses.
estimate_meal
Runs or queues backend AI nutrition comparison for an existing nutrition_log row without inserting duplicate food rows. Canonical logged calories/protein stay unchanged; backend NIM output is stored separately. Uses stored meal evidence only.
| Parameter | Type | Required | Description |
|---|
| meal_id | uuid | yes | nutrition_log.id of the existing meal row to compare. |
| process_now | boolean | no | Run immediately when true (default). When false, queue as pending for batch processing. |
Returns: Comparison receipt with canonical logged totals, provided vs backend NIM estimates, delta lines when both sides exist, estimate status, and verify URL.
attach_meal_evidence
Attaches new photo evidence to an active meal by inserting an immutable superseding nutrition_log row, merging images (max 5 total), and running backend NIM comparison immediately.
| Parameter | Type | Required | Description |
|---|
| meal_id | uuid | yes | nutrition_log.id of the active meal row receiving new evidence. |
| images | string[] | no | Base64 image strings or data URLs for new evidence photos. At least one new image is required across images and image_urls. Combined decoded base64 bytes must not exceed 3 MiB; larger photos go through POST /api/mcp/images/upload then image_urls. |
| image_urls | string[] | no | Vercel Blob URLs from POST /api/mcp/images/upload or POST /api/nutrition/images/upload for large new photos. |
| note | string | no | Optional context about the newly attached evidence. |
| confirm_image_time_mismatch | boolean | no | Required as true when new image EXIF capture time differs from meal logged time by more than 12 hours. |
Returns: Evidence attach receipt with original and superseding row IDs, merged image counts, NIM status, duplicate/EXIF advisory flags, and verify URLs.
set_user_timezone
Sets the calendar timezone used for date buckets, day bounds, and history windows.
| Parameter | Type | Required | Description |
|---|
| timezone | string | yes | Valid IANA timezone name, e.g. America/Edmonton. |
Returns: Confirmation with the persisted timezone. Takes effect within the 60-second settings cache window.