USDA FoodData Central MCP Server
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., "@USDA FoodData Central MCP Server Search for 'quinoa' and show its macros per 100g"
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.
USDA FoodData Central MCP Server
Model Context Protocol (MCP) server that exposes USDA FoodData Central search and lookup tools. Plug it into Codex CLI, Claude Desktop, or any MCP-aware client to explore nutrition data without writing HTTP calls by hand.
Last README sync: base commit 7dede6c (update after next commit).
Highlights
Four ready-to-use tools wrapping FoodData Central search, single-record lookup, bulk lookup, and paginated listing.
Strict validation with Zod schemas for inputs and outputs so LLMs can rely on structured results.
Cursor-aware previews let you dry-run calls, request compact summaries, and opt into raw payloads only when needed.
Lean nutrient lookups surface per-100 g calories, macros, saturated fat, and fiber through focused tools that accept just an FDC ID.
Resilient HTTP client with throttling, timeouts, and exponential backoff retries for USDA rate limits.
Built-in environment resource that describes the server configuration from inside your MCP client.
Related MCP server: nutrition-mcp-server
Requirements
Node.js 18.19 or newer (Claude Desktop’s bundled Node works).
USDA FoodData Central API key — request one at https://fdc.nal.usda.gov/api-key-signup.html and provide it via
USDA_API_KEY.
Quick Start
git clone <repo-url>
cd USDA-mcp
npm install
cp .env.example .env
echo "USDA_API_KEY=your-key" >> .env
npm run start # runs via tsx with stdio transportThe server exits immediately if USDA_API_KEY is missing or blank. When you hand the server off to an MCP client, have that client supply the variable instead of relying on .env.
To run the compiled CLI (needed for Codex autostart):
npm run build
npx usda-mcp # assumes USDA_API_KEY is exported or supplied by the client
# Optional: install the CLI globally so `usda-mcp` is on your PATH
# npm install --global .
# (or run `npm link` inside the repo)Configuration
Environment variables read at startup:
Variable | Required | Default | Purpose |
| Yes | — | FoodData Central API key; server exits if unset. |
| No |
| Override when routing through a proxy or staging host. |
You can provide these through .env, your shell, or the MCP client configuration. Use the config://usda-fooddata/environment resource to inspect the active settings from inside the client.
Running Under MCP Clients
Most MCP clients let you attach environment variables directly to a server definition. Provide USDA_API_KEY there so the USDA server runs regardless of your working directory. Only set USDA_API_BASE_URL when you need to hit a non-default endpoint.
Codex CLI (~/.config/codex/config.toml)
Codex profiles accept per-server environment variables in TOML (Codex configuration guide).
Use whichever command style matches your setup:
command = "usda-mcp"if you rannpm install --global .(ornpm link) so the CLI is on yourPATH.command = "node"withargs = ["/absolute/path/to/dist/server.js"]if you prefer not to install the package globally.
experimental_use_rmcp_client = true
[mcp_servers.usda_fooddata]
command = "usda-mcp"
startup_timeout_sec = 20
tool_timeout_sec = 60
# If the CLI is not on your PATH:
# command = "node"
# args = ["/Users/you/projects/USDA-mcp/dist/server.js"]
[mcp_servers.usda_fooddata.env]
USDA_API_KEY = "your-fooddata-central-key"
# Optional override if you proxy the API:
# USDA_API_BASE_URL = "https://api.nal.usda.gov/fdc/v1/"Claude Desktop (claude_desktop_config.json)
Claude Desktop reads server definitions from ~/Library/Application Support/Claude/claude_desktop_config.json on macOS (see the MCP introductory docs for the format). Point to your built entry point and inject the key via env.
{
"mcpServers": {
"usda": {
"command": "node",
"args": ["/Users/you/projects/USDA-mcp/dist/server.js"],
"env": {
"USDA_API_KEY": "your-fooddata-central-key"
// "USDA_API_BASE_URL": "https://api.nal.usda.gov/fdc/v1/"
}
}
}
}Re-run npm run build whenever you change the server so dist/server.js stays in sync.
Cursor IDE (~/.cursor/mcp.json)
Cursor keeps MCP definitions in ~/.cursor/mcp.json. Any server listed under mcpServers can set env (many server READMEs, including Yandex Search, use the same layout).
{
"mcpServers": {
"usda-fooddata": {
"type": "stdio",
"command": "node",
"args": ["/Users/you/projects/USDA-mcp/dist/server.js"],
"env": {
"USDA_API_KEY": "your-fooddata-central-key"
},
"startupTimeoutMs": 20000,
"toolTimeoutMs": 60000
}
}
}Claude Code (settings.json)
{
"mcpServers": {
"usda-fooddata": {
"command": "node",
"args": ["/Users/you/projects/USDA-mcp/dist/server.js"],
"env": {
"USDA_API_KEY": "your-fooddata-central-key"
},
"timeout": 20000
}
}
}Gemini CLI (settings.json)
Gemini CLI merges MCP servers from system, user, and workspace settings (Gemini CLI configuration).
{
"mcpServers": {
"usda-fooddata": {
"command": "node",
"args": ["/Users/you/projects/USDA-mcp/dist/server.js"],
"env": {
"USDA_API_KEY": "your-fooddata-central-key"
},
"timeout": 30000
}
},
"mcp": {
"allowed": ["usda-fooddata"]
}
}Tools
All tools return a plain-text summary plus a structuredContent payload with a summary object, compact previews, and (when requested) the raw USDA response. Use the preview and dry-run switches to conserve context until you know you need the full payload.
search-foods– Full-text search that only surfaces the food description, optional brand/data type, andfdcIdso agents can pick an entry without excessive detail. Filters, cursor pagination, sort controls, and dry-run previews help shrink context impact.get-food– Fetch a single FoodData Central (FDC) record by ID with optionalformatandnutrientsfilters. Requests default to the faster USDA “abridged” view; the summary highlights macros (when present) and any notable gaps in the response. When USDA retires a known legacy identifier (e.g., SR Legacy 4053 for olive oil), the tool automatically substitutes the documented replacement (Foundation 748608 in this case) and adds a note so you know why the ID changed.get_categories– Return category tags for a single FDC entry, includingfoodCategory(Foundation/SR Legacy),brandedFoodCategory(Branded), andwweiaFoodCategory(Survey/FNDDS) when present. The structured payload lists each category with its source and any available IDs/codes so you can cluster or filter foods by USDA taxonomy instead of text search alone.get_macros– Return per-100 g calories, protein, fat, and carbohydrates for a single FDC entry with structured nutrient metadata. The helper first issues an abridged request scoped to the macro nutrient IDs, escalates toformat=full, retries again without any nutrient filter, and finally consultslabelNutrients(including Foundation-style labels such asEnergy,Total fat (NLEA), andTotal carbohydrate (NLEA)). If a Foundation record still withholds even one macro after that sequence, the tool now errors with guidance so you can pick a different FDC entry or compute the numbers manually (e.g., 1 g fat ≈ 9 kcal).get_micros– Surfaces per-100 g vitamins and minerals (Calcium, Iron, Potassium, Sodium, Magnesium, Zinc, Vitamins A/C/D/E/K, Folate, Vitamins B6/B12). The helper runs through the same nutrient escalation/label parsing path, so most USDA foods return micronutrients without extra work.get_macro_micros– Combines both panels so you can fetch calories, macros, and the vitamin/mineral set in one call (useful when you would otherwise chainget_macros+get_microsback-to-back).get_fats,get_protein,get_carbs,get_kcal,get_satfats,get_fiber– Single-nutrient lookups that emit just the requested per-100 g value (or note that it is unavailable) to keep tool output distinct.get-foods– Bulk lookup for up to 50 FDC IDs in one call. SupportspreviewOnly,includeRaw,sampleSize, andestimateOnlyso you can review lightweight previews before retrieving the full objects, defaults to the faster USDA “abridged” format, and flags any requested IDs the USDA API omits. Known legacy → replacement mappings (e.g., 4053 → 748608) are applied automatically and noted in the summary.list-foods– Deterministic paginated listing that accepts optionalfilters(data types, brand owner), cursor-basedpagination,sort, and the same preview/dry-run switches assearch-foods. The summary returns the next cursor only when another page is likely available.list_portions– List USDA-defined portions for a single FDC entry (when available), including the human-readableportionDescription(for example “1 cup”),amount,gramWeight, and the associatedmeasureUnit. Use this to translate per-100 g nutrient panels into serving-based numbers without re-parsing the rawfoodPortionsarray yourself.macros_for_portion– Given anfdcIdand either aportionIdor zero-basedportionIndex(as returned bylist_portions), compute calories, protein, fat, and carbohydrates for that USDA-defined portion. The tool enforces the same Foundation safeguards asget_macros(errors when macros are hidden), notes when a portion is missinggramWeight, and returns both per-100 g values andvaluePerPortionin the structured nutrient list.
Handling Foundation entries without USDA macros
Foundation datasets sometimes omit energy, protein, or carbohydrate rows entirely (pure oils often only list lipid chemistry). The macro helper therefore:
Requests the abridged payload scoped to the calorie/protein/fat/carbohydrate nutrient IDs.
Falls back to
format=fullso USDA can include “analysis only” nutrients.Retries the abridged call without nutrient filters so the API can decide which nutrients to include.
Reads
labelNutrients, including Foundation label names such asEnergy (kcal),Total fat (NLEA),Protein (NLEA), andTotal carbohydrate (NLEA)even when USDA exposes those values only under display-friendly keys.
If any macro is still missing and the entry’s dataType is Foundation, get_macros stops with an error that lists the missing fields and suggests either switching to a record that publishes macros (e.g., SR Legacy or Survey entries) or deriving them yourself. A quick rule of thumb: calories ≈ (fat_g * 9) + (protein_g * 4) + (carbs_g * 4). Some oils (including FDC 748608) still omit USDA-provided calories/protein/carbs entirely across abridged/full/label payloads—this is a USDA database gap, not an MCP parsing bug—so keep the manual derivation handy for edge cases that never expose those fields.
Need both macro and micronutrient panels simultaneously? Call get_macro_micros to collapse the workflow into a single USDA request. It enforces the same Foundation guard for missing macros, surfaces micronutrient gaps in the summary, and automatically falls back to an unfiltered USDA fetch if the combined nutrient filter list exceeds USDA’s request limit (so you still get data, just with a slightly larger payload).
Micronutrient coverage (get_micros)
USDA keeps dozens of micronutrients in FoodData Central. The get_micros tool focuses on the vitamins and minerals that appear on standard nutrition labels so agents can request them in one call. Each value is per 100 g and travels through the same abridged/full/label fallback path used by get_macros.
Nutrient | Unit | USDA nutrient IDs (abridged/full) | Label aliases |
Calcium | mg | 1087, 301 |
|
Iron | mg | 1089, 303 |
|
Potassium | mg | 1092, 306 |
|
Sodium | mg | 1093, 307 |
|
Magnesium | mg | 1090, 304 |
|
Zinc | mg | 1095, 309 |
|
Vitamin A (RAE) | mcg | 1104, 318 |
|
Vitamin C | mg | 1162, 401 |
|
Vitamin D (D2 + D3) | mcg | 1114, 324, 328 |
|
Vitamin E (alpha-tocopherol) | mg | 1109, 323 |
|
Vitamin K (phylloquinone) | mcg | 1185, 430 |
|
Folate, total | mcg | 1186, 417 |
|
Vitamin B6 | mg | 1175, 415 |
|
Vitamin B12 | mcg | 1178, 418 |
|
If a micronutrient is absent from both the nutrient list and labelNutrients, the response lists it under summary.notes so downstream automation can decide whether to fall back to manual data.
get_macro_micros returns this entire table plus the macro set in one result, so you can minimize USDA round-trips when you know you need the full panel.
Resources
config://usda-fooddata/environment– Markdown overview showing the active base URL, whether a key is detected, retry/throttle policies, and guidance for overrides.usda_rebuild_progress.md– Workspace log for ingredient coverage. Record every “no USDA equivalent” decision (for example, ground sumac lacks a generic record, so we either keep the branded FDC 2630657 macros or stay with the manual rollup) to prevent repeated lookups.
Operational Notes
Requests time out after 30 seconds, use up to two retries with jittered exponential backoff on HTTP 429 or 5xx, and throttle to one concurrent call with ≥400 ms spacing so we stay under the 3 requests/second USDA ceiling. When USDA asks for a longer pause (via
Retry-After), that guidance is surfaced in the error text.Handle USDA rate limits responsibly: use narrow filters, reuse previous results, and avoid large bulk queries unless necessary.
Missing or invalid API keys cause the server to log the issue and exit immediately so MCP clients can surface the error.
Nutrient helpers follow a strict escalation path (scoped abridged →
format=full→ unfiltered abridged →labelNutrients) and recognise alternate labels such asTotal fat (NLEA)so oils and other sparse entries still return macro values. When a Foundation record still hides any macro after those retries,get_macrosintentionally errors and points you to alternate FDC IDs or the calorie conversion formula so downstream automations do not ingest partial data unknowingly.Legacy SR Legacy identifiers that USDA has retired (currently 4053 for olive oil) are automatically mapped to their documented replacement IDs, and every substitution is called out in the tool summaries (plus
requestedFdcIdsin the preview payload) so downstream automations can update their catalogs.
Handling Missing USDA Equivalents
Some pantry staples still lack a generic SR Legacy or Foundation record. To avoid thrashing the USDA API:
Search for the closest USDA record and document the FDC ID you plan to use (even if it is branded). Ground sumac does have a viable entry—use FDC 2630657 (branded) and record that choice in
usda_rebuild_progress.mdso other contributors know it is the canonical pick until USDA publishes a generic version.When no acceptable record exists (for example, composite spice mixes that include salt), log the ingredient in
usda_rebuild_progress.mdunder “No USDA equivalent” with the reasoning and the manual macro source. That file now serves as the go/no-go list before you spend time retrying lookups.If you later discover a matching USDA record, update the log with the new ID and remove the “no equivalent” flag so future rebuilds revisit the ingredient.
Development Workflow
npm run start– Launch withtsxfor local development.npm run lint– Type-check the TypeScript sources (tsc --noEmit).npm run build– Emit the compiled bundle todist/for the CLI or packaging.
Run npm run build whenever you change server code and want Codex or other clients that call usda-mcp to pick up the new build.
Troubleshooting
Startup fails: missing API key – Ensure
USDA_API_KEYis exported in your shell or supplied through the MCP client config.Client connects but requests fail with 401/403 – Verify the key is active and not rate-limited on the USDA side.
Repeated 429 Too Many Requests – Each tool already slows calls to one at a time; if you still get 429 responses, wait for the
Retry-Afterduration shown in the error text or batch IDs into fewer round-trips.Legacy FDC ID returns “not found” – USDA periodically retires SR Legacy entries. Known substitutions (currently 4053 → 748608 for olive oil) are applied automatically and annotated in the tool response; otherwise, use
search-foodsto locate the modern FDC ID.Foundation macros come back empty –
get_macrosescalates through full/unfiltered calls pluslabelNutrients, including Foundation display labels such asEnergy (kcal)andTotal fat (NLEA). When a record still hides macros after that sweep, the tool errors with the missing fields. Pick another FDC ID that exposes macros (SR Legacy or Survey datasets usually do) or estimate calories via(fat_g * 9) + (protein_g * 4) + (carbs_g * 4)(oils generally have protein/carbs = 0). FDC 748608 is a known USDA data gap: only the fat numbers are published, so manual macros are required.Micronutrients missing –
get_microsreports which vitamins/minerals are unavailable insummary.notes. That usually means the USDA record never published the nutrient; checkget-foodfor the raw payload or substitute a richer FDC ID if you need the value.No generic entry for an ingredient (e.g., ground sumac) – Document the decision in
usda_rebuild_progress.md. Ground sumac uses branded FDC 2630657 as the accepted entry today; for other ingredients without an acceptable record, note the manual macros and rationale so contributors avoid duplicate searches.CLI warns about missing
dist/server.js– Runnpm run buildbefore invokingnpx usda-mcp.
For API reference, see the official FoodData Central guide: https://fdc.nal.usda.gov/api-guide.html
Available Tools
16 toolsget_carbsGet CarbohydratesARead-onlyIdempotent
Return per 100 g carbohydrates for a FoodData Central entry. Returns a single value per 100 g to minimize context usage.
Inputs: fdcId (required). Returns: summary, nutrient
get_categoriesGet Food CategoriesARead-onlyIdempotent
Return category tags for a FoodData Central entry, including FoodCategory, brandedFoodCategory, and WweiaFoodCategory when available.
Inputs: fdcId (required). Returns: summary, categories
get_fatsGet Total FatARead-onlyIdempotent
Return per 100 g total fat for a FoodData Central entry. Returns a single value per 100 g to minimize context usage.
Inputs: fdcId (required). Returns: summary, nutrient
get_fiberGet Dietary FiberARead-onlyIdempotent
Return per 100 g dietary fiber for a FoodData Central entry. Returns a single value per 100 g to minimize context usage.
Inputs: fdcId (required). Returns: summary, nutrient
get-foodGet Food DetailsARead-onlyIdempotent
Look up a single FoodData Central (FDC) record by numeric ID. Supports abridged/full detail toggles and nutrient ID subsets to trim responses. Ideal once you already know the identifier.
Inputs: fdcId (required), format, nutrients. Returns: food, macros, summary
get-foodsGet Multiple FoodsARead-onlyIdempotent
Batch lookup for multiple FDC IDs via the USDA bulk endpoint. Provide up to 50 IDs to reduce repeated network calls. Supports abridged/full detail and nutrient filters per the API.
Inputs: fdcIds (required), format, nutrients, includeRaw, +3 more. Returns: foods, summary, previews
get_kcalGet CaloriesARead-onlyIdempotent
Return per 100 g calories for a FoodData Central entry. Returns a single value per 100 g to minimize context usage.
Inputs: fdcId (required). Returns: summary, nutrient
get_macro_microsGet Macros + MicrosARead-onlyIdempotent
Return per 100 g macro plus vitamin/mineral panels for a FoodData Central entry.
Inputs: fdcId (required). Returns: summary, nutrients
get_macrosGet MacrosARead-onlyIdempotent
Return per 100 g calories, protein, total fat, and carbohydrates for a FoodData Central entry.
Inputs: fdcId (required). Returns: summary, nutrients
get_microsGet MicronutrientsARead-onlyIdempotent
Return per 100 g vitamins and minerals for a FoodData Central entry (Calcium through B vitamins).
Inputs: fdcId (required). Returns: summary, nutrients
get_proteinGet ProteinARead-onlyIdempotent
Return per 100 g protein for a FoodData Central entry. Returns a single value per 100 g to minimize context usage.
Inputs: fdcId (required). Returns: summary, nutrient
get_satfatsGet Saturated FatARead-onlyIdempotent
Return per 100 g saturated fat for a FoodData Central entry. Returns a single value per 100 g to minimize context usage.
Inputs: fdcId (required). Returns: summary, nutrient
list-foodsList FoodsARead-only
Page-oriented listing endpoint for predictable iteration when you already know the data type or brand. Supports pagination, sorting, and brand filters, returning summaries for quick scanning.
Inputs: sort, filters, includeRaw, pagination, +3 more. Returns: foods, summary, previews
list_portionsList PortionsARead-onlyIdempotent
Return labeled portion sizes for a FoodData Central entry, including gram weights when available.
Inputs: fdcId (required). Returns: summary, portions
macros_for_portionMacros for PortionARead-onlyIdempotent
Return calories, protein, fat, and carbohydrates for a specific USDA-defined portion of a FoodData Central entry.
Inputs: fdcId (required), portionId, portionIndex. Returns: summary, nutrients
search-foodsSearch FoodsBRead-only
Full-text search of USDA FoodData Central with structured filters, pagination cursors, preview mode, and dry-run estimation to conserve context.
Inputs: query (required), sort, filters, includeRaw, +4 more. Returns: raw, summary, previews
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 16 tools
Several tools return overlapping nutrient data (e.g., get_macros, get_macro_micros, and individual get_kcal/get_protein/get_carbs/get_fats), which could lead an agent to select a broader or narrower result than needed. Descriptions are specific enough to disambiguate most cases, but the set is not fully distinct.
Tool names mix kebab-case (list-foods, search-foods, get-food, get-foods) with snake_case (get_macros, list_portions, macros_for_portion), violating the consistency rule. All use a verb_noun structure, but the hyphen/underscore split is unpredictable.
16 tools is at the edge of the comfortable range, and the many single-nutrient getters (get_kcal, get_protein, get_carbs, etc.) inflate the count without adding truly distinct capabilities. Still, the core search/lookup/portion workflows justify most of the tools.
For a read-only food database, the server covers discovery (search/list), retrieval (get-food/get-foods), nutrient breakdowns, and portions. No obvious dead ends; minor gaps like per-food-specific nutrient filtering for raw values are not needed since get-food supports nutrient subsets.
Maintenance
Related MCP Connectors
Search foods, compare nutrients, and look up the full USDA FoodData Central database.
USDA FoodData Central nutrient lookup, FDA recall watch, EU FMCG labelling via remote MCP
Food and nutrition data: search, macros, and comparisons
USDA FoodData Central nutrition data: search foods, compare macros, and analyze meals.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to search the USDA's FoodData Central database and retrieve detailed nutritional information and ingredient lists. It supports comprehensive food data access through keyword searches and structured queries for specific food items.3MIT
- AlicenseAqualityDmaintenanceEnables natural language access to USDA's FoodData Central database with 1M+ foods, supporting search, nutrition facts, food comparison, and daily value calculations.814 PyPIMIT
- AlicenseNot gradedqualityCmaintenanceProvides tools to search and retrieve USDA Food Data Central information, including food items, nutrients, and food groups, enabling AI agents to query food data through natural language.295 npmMIT
- AlicenseNot gradedqualityDmaintenanceProvides access to USDA FoodData Central database, enabling food search, nutrition details, and comparison for dietary analysis via MCP.5MIT