NutriTrace logo

NutriTrace

Self-hosted personal nutrition and calorie tracker

Alternative to: myfitnesspal, cronometer, lose it, waistline

NutriTrace screenshotNutriTrace screenshot

About Versions (95)

v1.2.0-dev01

2026-08-09

First dev pre-release of the 1.2.0 minor. Introduces the Model Context Protocol (MCP) server so external AI clients (Claude Desktop, Cursor, Codex, VS Code) can talk to a running NutriTrace instance. Off by default; opt in with env flags.

Added

  • Model Context Protocol server (#103, thanks @javydekoning). 12 tools across three tiers, each gated by its own env flag AND its own token scope, so admins can dial the surface area precisely. Read tools (5): get_goals, get_daily_totals, list_diary_entries, search_foods, get_recent_foods. Enabled with MCP_ENABLED=1 on the server and a token holding mcp:read. Write tools (4): log_food, log_water, log_meal, log_body_stat. Adds MCP_WRITE_ENABLED=1 and mcp:write. All additive; everything lands as normal editable entries in the diary UI. Destructive tools (3): delete_diary_entry, edit_diary_entry, create_food. Adds MCP_DESTROY_ENABLED=1, mcp:destroy, AND every call must include confirm: true (belt-and-suspenders: your MCP client already prompts per action, but the tool also refuses without the arg so a hallucinated call from a client that skips prompts still gets rejected). Tombstoned diary days are protected: writes refuse rather than silently resurrect an erased day. Every tool query is scoped on user_id (static test enforces this on every future change). Full setup + Claude Desktop config: docs/nutritrace/mcp/. Tool reference: reference/mcp-tools/.

Changed

  • Settings → API Tokens picker now shows a human-readable description under each scope. Previously the picker rendered only the raw scope name (mcp:read, mcp:write, read:foods, etc.) with no hint what each grants. Admins had to cross-reference the federation / MCP docs to pick correctly. Descriptions load from the server so any future scope addition automatically explains itself.
  • Settings → API Tokens picker also shows a live MCP status indicator. When any of MCP_ENABLED / MCP_WRITE_ENABLED / MCP_DESTROY_ENABLED is set on the server, a pill above the scope grid displays which tiers are actually active. Prevents the pit where an admin mints a token with mcp:write on a server that doesn’t have MCP_WRITE_ENABLED=1 and can’t figure out why the tool never appears.

Testing notes

  • Everything MCP-related is opt-in. Leaving the env flags unset means zero change from v1.1.2.
  • Repo ships scripts/mcp-smoke.mjs which hits a running instance end-to-end (handshake, tools/list, invoke each tool, verify auth + origin gates). Add --writes and --destroy to exercise those tiers too.
  • Static wiring test (scripts/mcp-wiring.test.js, 17 checks) + integration test against a real temp SQLite (scripts/mcp-integration.test.js, ~20 assertions covering LIKE-escape, portion scaling, alt_units refusal, tombstone protection, source preservation, legacy body_stats refusal, confirm=true gating, dedup, per-nutriment value cap) both pass on dev.
  • 11 code-review passes across the three phases surfaced 66 static-analysis findings, all resolved before release. Real-world usage will surface a different class of bugs; please file issues for anything odd.

Signed APK on this release page. Docker image is multi-arch (amd64 + arm64):

docker compose pull && docker compose up -d

To turn MCP on, add to your docker-compose.yml under the nutritrace service environment: list:

- MCP_ENABLED=1
# - MCP_WRITE_ENABLED=1    # optional, unlocks the 4 log tools
# - MCP_DESTROY_ENABLED=1  # optional, unlocks the 3 destructive tools