# Reported issues for Nutrition MCP

Pod holds 20 of 36 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to [Nutrition MCP](/mcp/nutrition-mcp).

## Most discussed

### Import discards the export's timezone column, so a re-import re-dates every meal against the profile's current zone

Found while fixing #69 (PR #96); deliberately left out of scope there.

`export_meals` writes a `timezone` column precisely so the file is self-describing about which zone its wall clocks belong to — `src/export.ts:26` in `CSV_COLUMNS`, `src/export.ts:61` writing `csvEscape(tz)`, and the comment at `src/export.ts:50-52` says so outright. The importer then throws that away:

- The widget's `ALIASES` table (`public/widgets/src/templates/import-meals.html:260-344`) has no `timezone` entry, so the c

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/97) · 2026-08-07 · closed · 1 comment

### validateLoggedAt guards only the weight tools — meals and water accept future and garbage timestamps

**Found by logic audit (confirmed independently by two auditors).**

`validateLoggedAt` (`src/tz.ts:212-228`) is called only in `log_weight` (`src/mcp.ts:2679-2680`) and `update_weight` (`src/mcp.ts:3070-3071`). It is absent from `log_meal` (`:1026`), `update_meal` (`:2399`), and `log_water` (`:2467`). Bulk import independently caps future timestamps at 48 h (`src/import.ts:478-487`).

**Failure scenarios:**
- `log_meal(logged_at: "2027-03-01T09:00:00Z")` (mis-parsed year) succeeds silently; the

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/75) · 2026-08-04 · closed · 1 comment

### Import widget sends rows_skipped only with chunk 0, causing false 'rows may have been dropped' warnings

**Found by logic audit (confirmed independently by two auditors).**

`public/widgets/src/templates/import-meals.html:714` sends `rows_skipped: i === 0 ? S.skipped : 0`, but `S.skipped` counts skips across the whole file, and skipped rows create interior `source_line` gaps wherever they occur. The server's integrity check is per call (`src/import.ts:891-905`).

**Failure scenario:** a Lose It! export with deleted/blank/totals rows scattered through the file, large enough for 2+ chunks. A later ch

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/73) · 2026-08-04 · closed · 1 comment

### Cache token verification: ~80ms floor on every MCP request, ~92% of which do no tool work

## Finding

From a 4h25m production traffic review (2026-07-24 00:57–05:22 UTC):

`POST /mcp` responses that succeeded (200/202, n=1,295):

```
min  79 ms
p50 111 ms
p75 134 ms
p90 162 ms
p95 181 ms
p99 211 ms
max 448 ms
```

**Nothing ever returns faster than 79 ms.** For contrast, in the same window `GET /` health checks ran p50 **1 ms**, and 401/429 responses p50 **0 ms** — so the runtime itself is idle-fast. The floor is downstream work on the authenticated path, and the obvious candidate is

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/52) · 2026-07-24 · open · 1 comment

### Return 503, not 401, when a token cannot be verified

## Context

`getUserIdByToken` used to collapse "token not found" and "Supabase unreachable" into a single `null`. On branch `fix/unauth-mcp-rate-limiting` it was split into a discriminated `TokenLookup`:

```ts
export type TokenLookup =
    | { status: "valid"; userId: string }
    | { status: "invalid" }
    | { status: "unavailable" };
```

That split was needed because the new repeat-auth-failure bans would otherwise count an outage against every active user and keep them shed for 5–60 minut

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/48) · 2026-07-24 · open · 1 comment

### Add USDA FoodData Central support for generic/raw food lookups

**Problem**

`src/foods.ts` currently covers "Phase 1: barcode resolution via Open Food Facts" — great for branded/packaged products, but Open Food Facts is community-edited and its coverage/quality for generic, unbranded foods (a banana, a chicken breast, brown rice) is inconsistent. Today those fall through entirely to LLM estimation (see the `log_meal`/`fiber_g` guidance in `src/mcp.ts` that lists "your own estimate" as the last resort). USDA FoodData Central (Foundation Foods / SR Legacy dat

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/143) · 2026-08-30 · open · 0 comments

### Allow marking a day (or range) as "not tracked" so it's excluded from averages/streaks

**Problem**

There's currently no way to distinguish "I didn't eat/track anything today" from "I ate but didn't log it, or can't reliably reconstruct it." Both look identical to the server: a day with zero rows. Averages already exclude zero-row days from their denominator (see `src/insights.ts`), but that's the wrong signal here — a day I deliberately skipped tracking isn't the same as a day with nothing to report, and today it just quietly disappears from the count rather than being explicitly

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/142) · 2026-08-30 · open · 0 comments

### Show recent Patreon posts on the landing page's Support section

## Motivation

The landing page's existing `#support` section pitches Patreon membership but is static. Adding a small feed of the creator's most recent public Patreon posts shows the project has regular, active updates rather than a static pitch.

## Approach

- **`src/patreon.ts`** (new): pure fetch/normalize logic against Patreon API v2 (`GET /campaigns/{id}/posts`), filtered to `is_public === true` (Patreon's own "safe to show everyone" signal — `is_paid` is orthogonal, not a stronger gate),

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/139) · 2026-08-28 · closed · 0 comments

## Most recent

### The "Other agents" install tab scrolls the landing page sideways at 320px

At a 320px viewport the landing page scrolls horizontally. The single element crossing `x = 320` is `LABEL.seg-other` — the "Other agents" tab in the install card's segmented control.

**Measured** at 320px wide:

| page | `LABEL.seg-other` right edge | `documentElement.scrollWidth` | `clientWidth` |
|---|---|---|---|
| `/` | 325.9px | 326 | 320 |
| `/de/` | 329.8px | 330 | 320 |
| `/uk/` | 332.7px | 332 | 320 |
| `/ja/` | *no such label* | **320** | 320 |

Japanese isolates the cause: it render

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/134) · 2026-08-26 · closed · 0 comments

### Nav reserves badge space on every page, including those where the badge can never appear

`.nav-has-badge` reserves horizontal space for the live-stats notification badge in the header nav and the mobile sheet. That reservation exists so the badge's arrival mid-read never reflows the nav — a real concern, but only on the landing page, because that is the only page whose script ever fills the badge in. Everywhere else it ships `[hidden]` and stays that way.

So `/tools`, `/privacy`, `/terms` and every `/alternatives/*` page — × 9 locales — carry permanent dead space in the nav for som

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/130) · 2026-08-25 · closed · 0 comments

### Nutrition Facts odometer overflows the panel at 390px once a delta tag appears

On a narrow phone the calorie odometer in the `.facts-cal` row overflows its own panel as soon as a `.delta` tag is inserted beside it.

**Measured** at 390×844 on the landing page:

| state | odometer right edge | row right edge | viewport |
|---|---|---|---|
| delta present | **387.3px** | 349px | 390px |
| delta hidden | 349px | 349px | 390px |

`.facts-cal` reports `scrollWidth` 346 vs `clientWidth` 308.

**Cause:** `showDelta()` inserts the tag into the same flex row as the odometer (`host.

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/129) · 2026-08-25 · closed · 0 comments

### kg/lb toggle fails WCAG 2.5.3 (Label in Name) in every locale

The weight-unit toggle in the live-stats panel shows the symbol as its visible text (`kg` / `lb`) but carries the spelled-out word as its accessible name (`aria-label="Kilograms"` / `"Pounds"`, and each locale's equivalent).

WCAG 2.5.3 *Label in Name* requires the accessible name to contain the visible label text. It does not here, so a voice-control user saying **"click lb"** cannot reach the button — the control it matches against is named "Pounds".

**Where:** `scripts/gen-index.ts` (the `.f

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/128) · 2026-08-25 · closed · 0 comments

### Meal-logged widget labels a past day "Calories today" and never shows which day it is

Updating (or logging) a meal on a **past** date renders the meal-logged widget with the calorie ring labelled **"Calories today"**, so a backfilled day reads as if it were today's intake.

## Repro

1. Have nutrition goals set (otherwise the widget renders nothing by design).
2. `update_meal` (or `log_meal`) with a `logged_at` on an earlier date.
3. The widget paints the correct totals **for that past day** — but the ring says "Calories today" and nothing on the card names the date.

## Cause

T

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/114) · 2026-08-15 · open · 0 comments

### Export all tracked data (meals, water, weight, goals, profile) as a single ZIP

## Problem

`export_meals` is the only way out of the server, and it only covers the `meals` table. Everything else a user has entered — water, weight, goals, and profile settings — has no export path at all. Someone who asks "give me all my data" (a backup before switching devices, a GDPR-style takeout, or just a spreadsheet of their weight history) cannot get it, and `delete_account` is destructive with no way to save anything but meals first.

## Proposal

Add a full-account export that bundl

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/112) · 2026-08-15 · closed · 0 comments

### Desktop clients have no way to get the current time, so logging a meal stalls or lands on the wrong day

## Symptom

Logging a meal from the Claude **mobile** app works: the model knows the current date and time and fills `logged_at` (or knowingly omits it). From **desktop** (and other hosts that don't inject the wall clock into the system prompt) the same request stalls — the model says it can't determine the current time and asks the user what time it is, or guesses a time/date and files the entry on the wrong day.

The difference is entirely host-side: some clients put "current date/time" into t

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/102) · 2026-08-09 · closed · 0 comments

### Track caffeine per meal (caffeine_mg), with a daily goal

Caffeine is the one thing people most often want alongside their macros that we cannot represent at all today: `lookup_barcode` can read an energy drink's label, `log_meal` can log the coffee, and neither can record the milligram that was the reason for logging it. Users end up stuffing "180 mg caffeine" into `notes`, where nothing sums it, nothing charts it, and no goal can be set against it.

The work is a fourth pass of the same shape as the fiber/sugar/alcohol pass (`supabase/migrations/2026

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/101) · 2026-08-09 · closed · 0 comments

### "Timezone never set" is unrepresentable: any other set_* tool silently defeats the UTC-fallback warning

**Follow-up from #68** (flagged during review of #98, deliberately not fixed there — it needs a schema change).

Every place the server warns "your timezone is unset, so this was read as UTC" derives that signal from `getProfile(userId) === null`. But a profile row can be created by tools that have nothing to do with timezones, and the column defaults to UTC, so the row's existence stops being evidence that the user ever chose a zone.

## Why the signal is unreliable

`profiles.timezone` cannot 

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/99) · 2026-08-07 · closed · 0 comments

### update_meal leaves the content-derived idempotency key stale

**Found by logic audit. Possibly by design — filing to settle the intended semantics.**

`updateMeal` (`src/supabase.ts:405-440`) never recomputes `idempotency_key`. After `update_meal` corrects calories 500→600:
- a replay of the *original* `log_meal` call (same explicit `logged_at`) dedupes onto the corrected row and reports "Meal already logged";
- re-logging the *corrected* content creates a duplicate row.

This is consistent with request-level (not content-level) idempotency, so it may be i

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/84) · 2026-08-04 · closed · 0 comments

### Summary widget ignores recorded_days and fabricates '0 g vs goal' for never-recorded nutrients

**Found by logic audit.**

`public/widgets/src/templates/nutrition-summary.html:326-335` renders `data.averages` directly; no widget reads `recorded_days`. `shared/macros.js:207-215` shows the goal sub-line whenever a goal is set. The schema's own contract (`src/mcp.ts:1781-1791`) says `recorded_days` of 0 means "the window has no data for it at all and its average is not a figure".

**Failure scenario:** user with `daily_fiber_g: 30` whose whole history predates the fiber column. The tool text 

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/78) · 2026-08-04 · open · 0 comments

### Short-window get_trends / get_weight_trends print '14d avg' and '30d avg' computed from the short window

**Found by logic audit (both tools, same pattern).**

- `get_trends`: `src/mcp.ts:3484` slices buckets to `windowDays` (min 2) before `computeTrends`; `src/insights.ts:174-184` then computes each trailing window as `daily.slice(-n)` and sets both `days` and `window` to `slice.length`, so the "(x of y days with data)" disclaimer (`insights.ts:289-292`) can never fire for a short window. `get_trends(days: 2)` prints "7d avg", "14d avg" and "30d avg" as three identical numbers, presented as distinc

[Read the thread](https://github.com/akutishevsky/nutrition-mcp/issues/77) · 2026-08-04 · open · 0 comments

The remaining reports are on [the project's issue tracker](https://github.com/akutishevsky/nutrition-mcp/issues).
