🍲 Canada's Food Guide: CLI and MCP server
foodguide is a command-line tool and an MCP server. It gives you Canada's Food Guide data:
- nutrients for any food in the Canadian Nutrient File (CNF) 2026,
- the 141 Food Guide recipes,
- Dietary Reference Intake (DRI) macronutrient tables,
- Estimated Energy Requirement (EER) equations.
All data sits in local files. At run time the tool makes no network calls. You fetch or build the data once, then work offline.
Version 3.0.0. See CHANGELOG.md for what changed.
See it in action
Watch the trailer on YouTube. Each example below jumps to its part of the video.
| Example | Video |
|---|---|
| Find themed recipes for a week | |
| Suggest recipes from an image of your groceries | |
| Calculate your estimated macros intake and energy requirements | |
| Calculate macros for a recipe |
The trailer was recorded with version 2.0, which fetched recipes and nutrients from the Health Canada websites while you chatted. Version 3.0 reads the same data from local files, so the answers come back faster and work offline. A few recipe tool arguments changed (see docs/mcp.md).
You can use this Google Sheet to check the EER and CNF calculations shown in the trailer.
Install
The PyPI package is named foodguidecanada. The import package and the commands are foodguide and foodguide-mcp. It needs Python 3.12 or newer.
The package is not published yet. The first release will be the tag v3.0.0. Once it is on PyPI:
pip install foodguidecanada # light CLI install (typer, httpx, beautifulsoup4, pydantic, requests)
pip install 'foodguidecanada[mcp]' # adds the MCP server (fastmcp, pandas, uvicorn)
uv tool install foodguidecanada # or install the CLI as a uv tool
Once v3.0.0 is tagged, you can install straight from Git:
pip install git+https://github.com/Aryan-Jhaveri/mcp-foodguidecanada.git@v3.0.0
pip install 'foodguidecanada[mcp] @ git+https://github.com/Aryan-Jhaveri/mcp-foodguidecanada.git@v3.0.0'
From a wheel you built yourself:
uv build
pip install dist/foodguidecanada-3.0.0-py3-none-any.whl
From a source checkout:
uv sync # add --extra mcp for the MCP server
uv run foodguide version
Check it:
$ foodguide version
foodguide 3.0.0
The examples below use foodguide. In a checkout, put uv run in front.
Get the data
Data lives in ~/.local/share/foodguide. Set FOODGUIDE_DATA_DIR to use another directory.
Install the published data. This downloads from the data-latest GitHub release over plain HTTPS. It checks every file against manifest.json before it writes anything, and unpacks cnf.sqlite.gz to cnf.sqlite. Files that already match are skipped.
foodguide data fetch
Options: --tag, --repo, --from-dir <dir>, --dest <dir>, --only cnf|recipes|dri|eer.
Or build the data yourself. Download the CNF 2026 zip from open.canada.ca first (see docs/data.md):
foodguide data build all --cnf-zip cnf_fcen_all-files-data_2026.zip --out-dir ./data
export FOODGUIDE_DATA_DIR=$PWD/data
data build recipes, dri and eer read canada.ca pages, send an identifying User-Agent and wait 1 second between requests. data build cnf --zip <zip> --no-fetch-metadata works fully offline. Details are in docs/data.md.
Quick tour
Command groups: cnf, recipes, dri, eer, data, plus version. Add --help to any command. Most list commands take --format table|csv|json.
cnf: nutrients for foods
Search matches whole food names (full-text search). A multi-word query such as "red lentils" finds nothing. Search one word.
$ foodguide cnf search lentils --limit 3
2113 Lentils, sprouted, raw / Lentilles, germées, crues
3392 Lentils, mature seeds, dry / Lentilles, grains mûrs, secs
6183 Lentils, flour / Lentilles, farine
Other commands: cnf food <code>, cnf measures <code>, cnf nutrients <code>.
$ foodguide cnf measures 3393 | head -4
Measure code EN FR grams
341 100 ml 100 ml 83.686
383 125 ml 125 ml 104.607
389 175 ml 175 ml 146.45
$ foodguide cnf nutrients 3393 --measure "125 ml" | head -5
Nutrients per 125 ml (104.607 g) — Lentils, mature seeds, boiled
Code Symbol Name Unit Amount
203 PROT Protein Gram 9.43555 Gram
204 FAT Fat (total lipids) Gram 0.397507 Gram
205 CARB Carbohydrate, total (by difference) Gram 21.0574 Gram
The --measure value must be one of the measures listed for that food. If it is not, the command says so and exits with an error.
recipes: Food Guide recipes
$ foodguide recipes search lentil --limit 3
Braised lentils with greens braised-lentils-greens collection__10_ingredients_less, collection__vegetarian, meal__lunch_dinner
Cajun lentil soup cajun-lentil-soup collection__10_ingredients_less, collection__freezer_friendly, collection__vegetarian, meal__lunch_dinner
Carrot ginger lentil soup carrot-ginger-lentil-soup collection__10_ingredients_less, collection__freezer_friendly, collection__vegetarian, meal__lunch_dinner
$ foodguide recipes filters | head -3
collection__10_ingredients_less 10 ingredients or less
collection__30_minutes_less 30 minutes or less
collection__freezer_friendly Freezer-friendly
$ foodguide recipes show braised-lentils-greens | head -4
Title: Braised lentils with greens
URL: https://www.canada.ca/en/health-canada/services/food-guide/eating-support/kitchen/recipes/braised-lentils-greens.html
Tags: collection__10_ingredients_less, collection__vegetarian, meal__lunch_dinner
Prep time: 20 min / Cook time: 45 min / Servings: 6
dri: Dietary Reference Intakes
dri tables lists macronutrient values per sex and age group. dri amdr shows Acceptable Macronutrient Distribution Ranges. dri lookup gets one nutrient.
$ foodguide dri tables --age-range "19-30 y" | head -8
Males — 19–30 y
carbohydrate: EAR (g/day) 100, RDA/AI (g/day) 130
protein: EAR (g/kg/day) 0.66, RDA/AI (g/kg/day) 0.8, RDA/AI (g/day) 56
total_fat: no values recorded
linoleic_acid: AI (g/day) 17 (AI)
alpha_linolenic_acid: AI (g/day) 1.6 (AI)
total_fibre: AI (g/day) 38 (AI)
total_water: AI (L/day) 3.7 (AI)
foodguide dri lookup --age-range "19-30 y" --nutrient protein
foodguide dri amdr --age-range "19 years and over"
eer: energy requirements
--pal is one of inactive, low_active, active (default) or very_active.
$ foodguide eer calc --sex male --age 30 --weight-kg 70 --height-cm 175 --pal low_active
EER (male, 30 y, 70.0 kg, 175.0 cm, low_active): 2754.9 kcal/day
formula: EER = 581.47 + (-10.83 * age) + (8.30 * height_cm) + (14.94 * weight_kg)
foodguide eer equations prints every equation.
data: manage the data files
data status shows where each dataset is read from, its size, and its provenance. It reads the bundled DRI and EER files when the data folder has none.
$ foodguide data status | head -8
file size_bytes provenance
dri_macronutrients.json 25360 Health Canada DRI Tables
eer_equations.json 12461 Health Canada DRI Tables
DRI data: foodguide/data/dri_macronutrients.json (25360 bytes, source: bundled_snapshot)
provenance: -
EER data: foodguide/data/eer_equations.json (12461 bytes, source: bundled_snapshot)
provenance: -
CNF database: /home/you/.local/share/foodguide/cnf.sqlite (38559744 bytes)
data manifest <dir>writesmanifest.jsonfor a data directory. It needs DRI and EER files that carry build provenance, so run it on a directory made bydata build, not on the bundled files.data changed old.json new.jsonprints the datasets that differ. It exits 0 when they are equivalent and 10 when not.
MCP server
foodguide-mcp serves the same data to AI clients such as Claude Desktop, Claude Code, Cursor and VS Code. Install it with the mcp extra (pip install 'foodguidecanada[mcp]'), and get the data first (see Get the data).
| Mode | Tools | Session database | Best for |
|---|---|---|---|
| stdio (default) | 46 | yes | Most users: recipe search, nutrients, EER and DRI, recipe macros, favourites, profiles |
| HTTP | 24 | no | A shared or remote server: lookups and calculations only |
The tools are listed in docs/mcp.md.
Set up by client
Claude Desktop: Settings (⌘,) → Developer → Edit Config, then restart the app.
{
"mcpServers": {
"foodguide": { "command": "foodguide-mcp" }
}
}
Claude Code
claude mcp add foodguide -- foodguide-mcp
Cursor: .cursor/mcp.json in a project, or ~/.cursor/mcp.json for all projects.
{
"mcpServers": {
"foodguide": { "command": "foodguide-mcp" }
}
}
VS Code (GitHub Copilot): .vscode/mcp.json
{
"servers": {
"foodguide": { "type": "stdio", "command": "foodguide-mcp" }
}
}
If the client cannot find foodguide-mcp, give the full path (which foodguide-mcp). From a source checkout use "command": "uv", "args": ["run", "--directory", "/path/to/checkout", "foodguide-mcp"]. Set FOODGUIDE_DATA_DIR in the client's env if the data is not in the default folder.
HTTP mode
Start the server in its own terminal and leave it running:
foodguide-mcp --transport http --port 8000 # endpoint: http://127.0.0.1:8000/mcp
It listens on 127.0.0.1 only and has no authentication. Do not expose it without something in front of it (--host or HOST changes the address).
claude mcp add foodguide --transport http http://127.0.0.1:8000/mcp # Claude Code
Claude Desktop and most other clients bridge stdio to HTTP with mcp-proxy:
{
"mcpServers": {
"foodguide": {
"command": "uvx",
"args": ["mcp-proxy", "--transport", "streamablehttp", "http://127.0.0.1:8000/mcp"]
}
}
}
Environment variables instead of flags: MCP_TRANSPORT=http PORT=8000 foodguide-mcp.
To serve it to other people, use the Docker image and put TLS and a token in front: see Serving it to others.
Troubleshooting
- The server does not appear in the client: check the client's logs (for Claude Desktop, the MCP log files) and run
foodguide-mcpin a terminal to see the error. - "needs the MCP extra": install
foodguidecanada[mcp]. - Tools answer "no data": run
foodguide data fetchand checkfoodguide data status. - HTTP mode: check that the server is up with
curl http://127.0.0.1:8000/mcp/. If the port is taken (Anki's AnkiConnect uses 8765), pick another with--port.
Data sources and licences
- Canadian Nutrient File 2026, Health Canada, from open.canada.ca. Licence: Open Government Licence – Canada.
- Food Guide recipes, Crown copyright, Health Canada (141 recipe pages on canada.ca).
- DRI tables (reference values for macronutrients) and EER equations, Health Canada (canada.ca pages, dated 2025-11-19).
Source URLs and build steps are in docs/data.md. The code is MIT licensed (see LICENSE).
How the data stays fresh
A GitHub Actions workflow (.github/workflows/data-refresh.yml) runs every Monday. It runs the live tests (pytest -m live), rebuilds all datasets, and compares the new manifest.json with the published one using the same logic as foodguide data changed. It publishes a new data-latest release only when the content changed. Run foodguide data fetch to pick it up.
More
- docs/data.md: the four datasets, sources, builds, sizes.
- docs/mcp.md: MCP server and tool list.
- CONTRIBUTING.md: development and tests.
- docs/RELEASING.md: how a release is cut.
- CHANGELOG.md: release notes.
- IMPLEMENTATIONS.MD: how the code is put together.
Made with ❤️ for Canada's Food Guide
Canada's Food Guide · Canadian Nutrient File · Dietary Reference Intakes
Built with FastMCP
Metadata
Release files for foodguidecanada 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| foodguidecanada-3.0.0.tar.gz | 1.1 MB | With provenance | Details for foodguidecanada-3.0.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| foodguidecanada-3.0.0-py3-none-any.whl | Python 3 | none | any | Details for foodguidecanada-3.0.0-py3-none-any.whl |
Total release size: 1.3 MB
Release files / foodguidecanada-3.0.0.tar.gz
| Download URL | foodguidecanada-3.0.0.tar.gz |
|---|---|
| Size | 1.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
80815d60be3cd7e56bd2d0fd2a5407e8cc140a4c2f135b6b6a2b418d50679038
|
|
BLAKE2b-256 checksum How to use checksums |
7036e9fc17d177b1ff1132a4d55547ae7b4256ad8b09b37ffb1f4ba8c0546edc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logRelease files / foodguidecanada-3.0.0-py3-none-any.whl
| Download URL | foodguidecanada-3.0.0-py3-none-any.whl |
|---|---|
| Size | 180.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
5e98a3f0181393e6620bb00a36eb54f542b37dbc1c117d29027829691cd07237
|
|
BLAKE2b-256 checksum How to use checksums |
6971cf693a46c422a800e1b0ec2bf45d46b3d7d6f16190978207109435cda6e2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logSecurity for foodguidecanada 3.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for foodguidecanada-3.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 2, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.