- README: human-facing with tech stack, 14 nutrient table, 13 tools, env vars, build/run/deploy instructions, Hermes integration - AGENTS/CLAUDE: build commands, architecture, module map, SQLite schema, conventions, tracked nutrients, session protocol Closes nutrition-mcp-yd5, nutrition-mcp-4lv
111 lines
No EOL
4.1 KiB
Markdown
111 lines
No EOL
4.1 KiB
Markdown
# Agent Instructions
|
||
|
||
This project uses **bd** (beads) for issue tracking. Run `bd prime` for full workflow context.
|
||
|
||
## Build & Test
|
||
|
||
```bash
|
||
cargo build --release # Build binary
|
||
cargo test # Run unit tests
|
||
./target/release/nutrition-mcp # Run server (needs env vars)
|
||
```
|
||
|
||
### Smoke Test
|
||
|
||
```bash
|
||
# Start server
|
||
NUTRITION_MCP_BIND=127.0.0.1:9432 NUTRITION_MCP_API_KEY=test \
|
||
NUTRITION_MCP_DB_PATH=/tmp/test.db ./target/release/nutrition-mcp &
|
||
|
||
# Health check
|
||
curl http://127.0.0.1:9432/health
|
||
|
||
# MCP initialize
|
||
curl -X POST http://127.0.0.1:9432/mcp \
|
||
-H "Authorization: Bearer test" \
|
||
-H "Content-Type: application/json" \
|
||
-H "Accept: application/json, text/event-stream" \
|
||
-d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}},"id":1}'
|
||
```
|
||
|
||
## Architecture Overview
|
||
|
||
MCP server exposing 13 tools for personal nutrition tracking. Streamable HTTP transport with Bearer token auth.
|
||
|
||
### Module Map
|
||
|
||
```
|
||
src/
|
||
├── main.rs — Entry point: axum server, auth middleware, /health endpoint
|
||
├── config.rs — Config struct from env vars (bind, api_key, db_path, user_agent)
|
||
├── db.rs — SQLite schema, migrations, DbPool type, TRACKED_NUTRIENTS const, DEFAULT_GOALS_JSON
|
||
├── api.rs — OffClient: Search-a-licious + v3 barcode + SQLite cache (FTS5)
|
||
└── tools.rs — NutritionServer: 13 MCP tools via #[tool_router] + ServerHandler impl
|
||
```
|
||
|
||
### SQLite Schema
|
||
|
||
- **products** — OFF cache: code (PK), product_name, brands, nutriments (JSON), serving_quantity, serving_size, image_url
|
||
- **products_fts** — FTS5 virtual table on product_name (synced via triggers)
|
||
- **entries** — Food log: id, date, meal, product_code, food_name, grams, servings, nutriments (JSON, scaled to portion)
|
||
- **daily_goal** — Single row (id=1), goals JSON with 14 nutrient targets
|
||
- **weight_log** — id, date, weight_kg
|
||
|
||
### Nutrient Storage
|
||
|
||
All nutrients stored as JSON blob in `nutriments` TEXT column (verbatim from OFF API). Daily summaries use `json_extract()` or Rust-side parsing to aggregate the 14 tracked nutrients.
|
||
|
||
### Portion Scaling
|
||
|
||
Nutrients are stored per-100g in OFF data. When logging, `scale_nutriments()` multiplies each value by `grams / 100.0`. For servings, grams = `servings * serving_quantity`.
|
||
|
||
### Meal Auto-Detection
|
||
|
||
- breakfast: before 11:00
|
||
- lunch: 11:00–15:00
|
||
- dinner: 15:00–21:00
|
||
- snack: after 21:00
|
||
|
||
## Conventions & Patterns
|
||
|
||
- **JSON nutriments** — Never hardcode nutrient columns. Store OFF nutriments verbatim as JSON, query at runtime.
|
||
- **"no data" vs 0** — Micronutrients (potassium, calcium, magnesium) are sparse in OFF. Summary shows `"no data"` when no entries have the nutrient, not 0.
|
||
- **Env vars only** — No config files. All settings via environment variables.
|
||
- **API-first** — Always check SQLite cache first, fall back to OFF API, cache results.
|
||
- **User-Agent** — Always send custom User-Agent to OFF API (good citizenship).
|
||
|
||
## Tracked Nutrients (14)
|
||
|
||
```
|
||
energy_kcal → energy-kcal_100g
|
||
protein → proteins_100g
|
||
carbohydrates → carbohydrates_100g
|
||
fat → fat_100g
|
||
fiber → fiber_100g
|
||
sugars → sugars_100g
|
||
saturated_fat → saturated-fat_100g
|
||
salt → salt_100g
|
||
fructose → fructose_100g (gout)
|
||
alcohol → alcohol_100g (gout)
|
||
potassium → potassium_100g (hypertension)
|
||
calcium → calcium_100g (hypertension)
|
||
magnesium → magnesium_100g (hypertension)
|
||
cholesterol → cholesterol_100g (hypertension)
|
||
```
|
||
|
||
## Non-Interactive Shell Commands
|
||
|
||
**ALWAYS use non-interactive flags** to avoid hanging on confirmation prompts.
|
||
|
||
```bash
|
||
cp -f source dest # NOT: cp source dest
|
||
rm -f file # NOT: rm file
|
||
```
|
||
|
||
## Session Completion
|
||
|
||
1. **File issues for remaining work** - `bd create` for follow-up items
|
||
2. **Run quality gates** - `cargo build --release && cargo test`
|
||
3. **Close completed issues** - `bd close <id1> <id2> ...`
|
||
4. **PUSH** - `git add -A && git commit -m "..." && git push`
|
||
5. **Verify** - `git status` must show clean working tree |