foodlog
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@foodlogLog my lunch: 170g chicken breast, 100g rice, 50g avocado."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Food Log MCP
A personal food journal you use through an AI assistant, with a mobile-friendly nutrition dashboard. Log meals in conversation, save foods you eat regularly, and review calories, protein, carbs, fat, fiber, meal history, and eating patterns.
MCP (Model Context Protocol) lets a compatible assistant call this project's tools to read and write your journal. Use your connected assistant to add or correct foods, or log a saved staple directly from the dashboard with its serving count.
This is a self-hosted, single-person project. Each person should use their own checkout, database, profile, and deployment. There are no separate user accounts inside one instance.
What you get
Daily overview: calories against your target, current macro intake, and fiber progress.
Macro ranges: energy shares labeled under, within, or over your configured ranges.
Meal journal: expandable ingredients, nutrients, notes, and estimated-data indicators.
History: 7-day, 30-day, and available-history views, with charts and eating patterns.
Saved foods: searchable staples with serving controls and a “Log now” button, plus aliases such as “my usual oatmeal.”
Daily browsing: previous/next day buttons and a date picker show the full summary for any day in the loaded history.
Consistent grading: the server calculates grades from nutrients and processing level.
Your storage: a local SQLite database, or your own Turso database for remote hosting.
The included personal metrics and targets are example configuration, not universal goals. Replace them with your own information before interpreting your results.
Related MCP server: yes_chef_mcp
Quick start
These commands use a macOS/Linux shell. Use Python 3.10 or newer.
git clone https://github.com/lucia-urcuyo/food-log-mcp.git
cd food-log-mcp
python3 -m venv .venv
./.venv/bin/python -m pip install -r requirements.txt
cp .env.example .envEdit .env with your own body measurements and activity. Then load it into your shell:
set -a
. ./.env
set +aThe application does not automatically read .env. Load it before starting the server
or generating a dashboard. Reload the environment and restart running processes after changes.
Only source an environment file you created or reviewed: this command executes shell syntax.
Check the installation:
./.venv/bin/python test_server.pyThe tests use temporary databases and print all good and libsql backend: ok when successful.
A new checkout starts with an empty journal; the database is created automatically on first use.
Make it yours
1. Set your measurements and activity
The commented .env.example lists every supported environment setting.
Setting | Meaning |
| Inputs to the dashboard's resting-energy calculation; the formula uses |
| Metric body measurements; nonzero values take precedence over imperial inputs |
| Imperial inputs; keep them equivalent to the metric values for the profile explanation |
| Activity multiplier excluding the workouts below |
| Lifting sessions per week, minutes per session, and intensity factor |
| Other sport sessions, duration, and intensity factor |
|
|
| Width of the calorie window around the target |
| Factor for the calculated protein target |
Set workout days to 0 for activities you do not do. These inputs affect the dashboard's
calculated targets; saved targets can override those calculations.
2. Save your journal profile
Once an assistant is connected, ask it to set your Food Log profile using your chosen values.
For example, this is the JSON input to the profile tool—not a shell command:
{
"set_values": {
"kcal_target": 2200,
"protein_target_g": 120,
"weight_kg": 70,
"late_hour": 20
}
}Use your own numbers. Call profile without arguments to inspect saved settings.
Value | Where it is used |
| Stats and dashboard; overrides the dashboard's calculated calorie target |
| Stats and dashboard; overrides the dashboard's calculated protein target |
| Stats calculations; also set |
| Stats and dashboard; hour after which calories are counted as late |
Profile values are stored in the database. Changing .env does not clear saved overrides.
The stats tool does not inherit the dashboard's calculated targets: set the profile to make
its target comparisons available. Keep profile weight and environment weight in sync.
3. Choose macro and fiber ranges
The current dashboard ranges are:
Nutrient | Range |
Protein | 25–30% of macro energy |
Carbs | 40–45% of macro energy |
Fat | 25–30% of macro energy |
Dietary fiber | 25–28 g per day |
To use different ranges, edit these entries in targets() in dashboard.py:
"fiber_g": 25, # keep this equal to the lower end of your fiber range
"fiber_range_g": [25, 28],
"macro_ranges_pct": {"p": [25, 30], "c": [40, 45], "f": [25, 30]},These ranges currently have no environment-variable or profile override. Restart or redeploy the dashboard after editing them. Percentage ranges are separate from the daily protein goal in grams. Choose ranges that can accommodate a combined 100% macro split.
Connect an assistant
Local MCP client
A client that supports local MCP servers can launch server.py over stdio. Here is an
example MCP configuration; replace the absolute path with your checkout's location:
{
"mcpServers": {
"foodlog": {
"command": "/bin/sh",
"args": [
"-c",
"cd '/absolute/path/to/food-log-mcp' && set -a && . ./.env && set +a && exec ./.venv/bin/python server.py"
]
}
}
}The exact configuration location depends on your client. The wrapper loads your .env
every time the client starts the server. You can also use your client's environment-variable
settings and launch the Python executable directly.
Remote MCP client
Clients that cannot start local processes need a reachable HTTPS MCP endpoint. Run the ASGI entrypoint below behind your own HTTPS host or tunnel, then provide the client with:
https://YOUR-HOST/YOUR-FOODLOG-PATHUse your own database and secrets. The bundled entrypoint uses FOODLOG_PATH as its access
secret; it has no account login or OAuth implementation. Anyone with that URL can access the
journal's tools. Keep both the MCP and dashboard URLs private.
Open the dashboard
After loading .env, run the entrypoint that serves both MCP and the dashboard:
./.venv/bin/python -m uvicorn api.index:app --host 127.0.0.1 --port 8123With the example's local FOODLOG_PATH=/mcp, open:
Dashboard:
http://127.0.0.1:8123/mcp/dashboardMCP endpoint:
http://127.0.0.1:8123/mcp
If you change FOODLOG_PATH, replace /mcp in both URLs. Do not expose the example path
publicly. server.py alone serves MCP, not the dashboard.
For a standalone, private HTML snapshot:
./.venv/bin/python dashboard.py > /tmp/foodlog-dashboard.htmlOpen that file in a browser. It contains your meal data; regenerate it to see new entries. Live refresh is available through the hosted dashboard, not a saved file.
Start logging
Example requests to your connected assistant:
“Set my Food Log profile to my calorie target, protein target, weight, and late-meal hour.”
“Log this lunch. Break it into ingredients and include fiber for each one.”
“Save this labeled oatmeal serving as ‘my usual oatmeal,’ including its fiber.”
“Log two servings of my usual oatmeal.”
“Show my last seven days and compare them with my targets.”
“Correct the portion size in meal 12.”
Meals are ingredient lists. The assistant supplies nutrients and portions; the server adds them up and calculates the grade. For photos, the logging protocol asks for estimated weights, visual anchors in the notes, and a processing level for each ingredient.
Fiber is required for each new ingredient and saved food. Use explicit 0 for fiber-free
foods. If the value is unavailable, obtain it before logging. Sugar, saturated fat, and sodium
remain optional. Fiber cannot be cleared or set to a negative/non-finite value through edits.
For saved foods, fiber is entered once per serving and scaled automatically: a serving with 4 g of fiber contributes 8 g when you log two servings. Older saved foods missing fiber must be updated before reuse. Older meal records remain readable without invented fiber values.
Log a staple from the dashboard
Find a saved food under Your staples, choose a serving count (in quarter-serving steps), and tap Log now. This logs it using your browser’s current local date and time, scales all nutrients from the saved serving, and infers breakfast, lunch, dinner, or snack using the existing meal-time rules. The dashboard returns to Today after a successful save. Even when browsing a past day, Log now always records the food for now.
Staples missing fiber cannot be logged until corrected in chat. A saved HTML snapshot can show staples but cannot log them; use the served dashboard. If a connection error leaves save status uncertain, refresh and check your meals before adding the same serving again.
Understand your numbers
Macro percentages use 4 kcal/g for protein and carbs, and 9 kcal/g for fat, divided by their combined energy. They describe the food logged so far, not a percentage of your daily calorie target. Range boundaries are inclusive.
Fiber progress uses your daily gram range. If any meals lack fiber, the main summary shows the reported amount as a minimum and marks the data incomplete.
The dashboard’s 7-day and 30-day views end yesterday; All also excludes today. Their averages use logged days, excluding days without entries. Daily browsing includes today’s partial intake. The MCP stats tool retains its existing period definitions.
The dashboard loads up to 365 days of meals; its All view covers that loaded history. The daily chart shows at most the latest 60 days in the selected period. Older stored meals remain available through the journal tools.
Grades are a project-specific heuristic based on nutrient density per 100 kcal and NOVA processing levels. They describe the scoring model, not a clinical assessment.
estimated_fieldsidentifies missing nutrients filled by the scorer. Confidence describes nutrient completeness; it does not certify the accuracy of photo portions or supplied values.
Available tools
Tool | Purpose |
| Add ingredients as a meal and calculate its grade |
| Correct or delete an entry; corrections recalculate its grade |
| Filter meals by date, meal type, search text, or grade |
| Look up saved foods and previously logged ingredients |
| Save a reusable serving, nutrients including fiber, and aliases |
| Review energy, macros, quality, timing, and habits |
| Read or update saved personal targets |
Storage, backups, and hosting
Local storage defaults to foodlog.db beside server.py. Use FOODLOG_DB to select another
file, preferably an absolute path. Stop local writers before copying the database for a simple
backup. Keep databases, HTML exports, tokens, and .env private; .env.example contains only
sample values and is safe to commit.
Dates and times are stored as local, timezone-naive values. Use a consistent server timezone and supply explicit meal dates/times if the server runs in a different timezone from you. The dashboard determines Today from the browser's local date.
For a persistent host, run the ASGI app with durable storage. For Vercel, this repository
includes api/index.py and vercel.json; use your own Turso database because local files do
not provide persistent storage across serverless requests. Configure these variables in the
hosting platform, not just in your laptop's .env:
TURSO_DATABASE_URL: your database URL.TURSO_AUTH_TOKEN: your database access token.FOODLOG_PATH: a private, unpredictable path beginning with/.Your
FOODLOG_*personal metrics and activity settings.
When TURSO_DATABASE_URL is nonempty, it takes precedence over local SQLite. Switching to it
does not migrate your existing local meals. A new database starts empty. Create the saved
profile in the database your deployed instance uses, and use your provider's backup facilities.
Troubleshooting
Problem | Check |
Dashboard targets look wrong | Load |
Stats and dashboard disagree about weight | Update both profile |
Fiber is incomplete | Older meals may lack values; correct them using actual nutrition information |
Saved-food logging rejects missing fiber | Re-save that food with its complete serving information and fiber |
Dashboard returns 404 or 405 | Start |
Refresh cannot update a file | Open the served dashboard or regenerate the HTML snapshot |
A different client shows an empty journal | Check that both processes use the same database configuration |
Import or command not found | Use the checkout's |
Project files
File | Purpose |
| MCP tools, database schema, scoring, and statistics |
| Self-contained dashboard, aggregation, and calculated targets |
| Regression tests using temporary SQLite and libSQL databases |
| Commented sample configuration |
| ASGI hosting entrypoint and Vercel routing |
| Product background |
| Contributor instructions and invariants |
Contributors: keep grading server-side, preserve ingredient-level data, and never silently
turn missing nutrients into zero. Run ./.venv/bin/python test_server.py before sharing changes.
Scoring reference for contributors
Scoring constants live in SCORING and NOVA_DEFAULTS in server.py. The current model starts
at 65 points, adds capped protein and fiber density contributions, subtracts sugar, saturated
fat, and sodium penalties, and applies a processing adjustment. Fiber offsets part of the sugar
penalty. Grades use thresholds A ≥ 80, B ≥ 65, C ≥ 50, D ≥ 35, otherwise F.
The existing calibration examples are retained here for changes to that model:
A 88.8 chicken + broccoli + rice C 62.4 sourdough toast + butter
A 80.0 plain greek yogurt C 54.2 croissant
B 76.5 banana D 39.8 orange juice
B 74.2 turkish eggs + bread F 23.0 coke
B 72.5 protein barThese examples describe the project's scoring calibration. The test suite checks selected fixtures and relative ordering; update the applicable assertions and this reference together when deliberately changing the scoring model.
This server cannot be deployed
Maintenance
Related MCP Connectors
Food logging, nutrition summaries, and meal photo calorie and macro estimates.
Manage your Health Partner account, log food, water, workouts, body using agent
Log meals, check calories and macros, set up a nutrition plan, and search foods.
Use TrueCal from AI agents to review progress, meals, targets, trends, and supported updates.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables querying food nutritional information, discovering recipes by ingredients or diet type, getting ingredient substitutions, and receiving personalized food recommendations based on mood and season.-
- FlicenseNot gradedqualityDmaintenanceEnables AI assistants to search recipes, compose nutritionally balanced meals, optimize weekly meal plans based on macro targets for family members, and generate consolidated grocery lists from a personal recipe database.-
- FlicenseNot gradedqualityCmaintenanceEnables logging food into MyFitnessPal diary via natural language, supporting search, log, quick add, and diary retrieval.-
- AlicenseNot gradedqualityBmaintenanceEnables ChatGPT to record, correct, and query meal nutrition and nutrition goals, with durable and auditable data storage.MIT