cyanheads avatar

Faostat Mcp Server

cyanheads/faostat-mcp-server

If you've ever wanted an LLM to answer questions about world food production, trade, or land use without scraping the FAOSTAT site, this is the one to reach for. It serves the UN FAOSTAT bulk-download corpus from a local SQLite mirror, covering 245+ countries back to 1961. The tools walk you through the natural workflow: list domains, resolve human terms like "maize" or "Kenya" to codes, then query observations by area, item, element, and year range. There's also a commodity profile tool that bundles top producers, production trends, and trade flows for one crop in a single call. Large results spill into a staging table you can query with read-only SQL. It runs over STDIO or Streamable HTTP, and a public hosted instance is available if you'd rather not run it locally.

GitHub stars
3
tools
6
transport
STDIO, HTTP
env vars
12
last updated
Nov 3, 2026

Install

From registry metadata
$ npx add-mcp https://faostat.caseyjhand.com/mcp --name faostat

Run in your terminal. add-mcp asks which agents to add it to (Claude Code, Codex, Cursor and more). Add -g to install it for every project.

Review the command, arguments and environment values before installing. MCP servers run with your local permissions.

Other ways

Claude Code

$ claude mcp add --transport http faostat https://faostat.caseyjhand.com/mcp

Run in your terminal. Add --scope user to make it available in every project.

Tools

Verified live · 6 tools

Verified live against the running server on Nov 13, 2026.

faostat_list_domainsDiscover FAOSTAT statistical domains (production, trade, food balances, food security, land use, agri-emissions, prices, value) with their codes, descriptions, last-update date, upstream row count, and local index status. Every query keys on a domain code from here. The `index...5 params

Discover FAOSTAT statistical domains (production, trade, food balances, food security, land use, agri-emissions, prices, value) with their codes, descriptions, last-update date, upstream row count, and local index status. Every query keys on a domain code from here. The `index...

Parameters* required
codestring
Exact domain code lookup (e.g. "RL"), case-insensitive. Returns that one domain's full record on a single page. Takes precedence over `topic` / `indexed_only` when provided.
indexed_onlyboolean
When true, return only domains indexed in the local mirror (queryable now).default: false
limitinteger
Maximum domains to return on this page (max 200 — above the catalog size, so raise it to fetch everything at once). Domain descriptions are long; the default keeps a browse call small.default: 20
offsetinteger
Zero-based pagination offset into the matching domains (code-sorted). When the response reports truncated, pass the returned nextOffset here to fetch the next page. Ignored for exact-code lookups (...default: 0
topicstring
Case-insensitive substring filter over domain code, name, and topic (e.g. "trade", "emissions", "QCL"). Omit to list the full catalog.
faostat_resolve_codesResolve labels to the numeric codes or exact alphanumeric item identities faostat_query_observations needs: areas (countries/regions), items (commodities), and elements (metrics). Use query for full-text matching, name_contains for substring matching, code or code_text for exa...10 params

Resolve labels to the numeric codes or exact alphanumeric item identities faostat_query_observations needs: areas (countries/regions), items (commodities), and elements (metrics). Use query for full-text matching, name_contains for substring matching, code or code_text for exa...

Parameters* required
codeinteger
Exact code lookup. Takes precedence over `query`/`name_contains` when provided.
code_textstring
Exact alphanumeric item code. Only for dimension item; mutually exclusive with code. Numeric identities use code.
dimension*string
Which dimension to resolve: "area" (countries/regions), "item" (commodities), or "element" (metrics).one of area · item · element
domain*string
FAOSTAT domain code (e.g. "QCL"). Item and element resolution is scoped to the codes present in this domain's data; area code lists are shared across all indexed domains.
item_codesarray
For element resolution only: restrict elements and units to these items. Empty matches nothing; omit for domain-wide elements. Mutually exclusive with item_codes_text.
item_codes_textarray
For element resolution only: restrict elements and units to these exact text items. Empty matches nothing; mutually exclusive with item_codes.
limitinteger
Maximum matches to return (max 200).default: 50
name_containsstring
Case-insensitive substring filter over the label. Used only when `query` is omitted.
offsetinteger
Zero-based pagination offset into the match set. When the response reports truncated, pass the returned nextOffset here to fetch the next page. Ignored for exact-code lookups (always single-page).default: 0
querystring
Full-text search term, FTS5-matched against the dimension labels with prefix matching (e.g. "wheat", "import quantity"). Relevance-ranked.
faostat_query_observationsQuery a FAOSTAT domain's data cube by area(s), item(s), element(s), sources, and year range, returning values with units and data-quality flags. Resolve numeric codes or exact alphanumeric item identities with faostat_resolve_codes; element resolution accepts item selectors an...11 params

Query a FAOSTAT domain's data cube by area(s), item(s), element(s), sources, and year range, returning values with units and data-quality flags. Resolve numeric codes or exact alphanumeric item identities with faostat_resolve_codes; element resolution accepts item selectors an...

Parameters* required
area_codesarray
Area codes from faostat_resolve_codes. When set, aggregates are NOT auto-excluded — the codes are honored verbatim.
canvas_idstring
Canvas ID to stage onto, as returned by a prior faostat_query_observations / faostat_commodity_profile call — exactly 10 characters of letters, digits, hyphens, and underscores. Omit to stage onto...
domain*string
FAOSTAT domain code (e.g. "QCL"). Must be indexed locally.
element_codesarray
Element codes from faostat_resolve_codes (e.g. 5510 Production).
include_aggregatesboolean
When false (default), exclude aggregate-region rows (codes ≥ 5000 plus a few curated sub-threshold roll-ups such as China=351) so sums are not double-counted. Set true for World/continent/grouping...default: false
item_codesarray
Item codes from faostat_resolve_codes.
item_codes_textarray
Exact alphanumeric item identities from resolver code_text; mutually exclusive with item_codes. Numeric codes use item_codes.
limitinteger
Max observations returned inline — also the preview size when the result stages to a canvas table. Rows past it are never dropped silently: a match larger than limit stages in full to a DataCanvas...default: 200
source_codesarray
Exact source codes, such as 3050 or 3051 in GLE. Omit to return every methodology; choose or group sources before summing.
year_endinteger
Inclusive end year (e.g. 2022).
year_startinteger
Inclusive start year (e.g. 2000).
faostat_commodity_profileAssemble a global profile for one QCL item in a single call: top-producing countries, the annual production trend, and trade flows (top exporters and importers). Supply item_code or item_query; code wins when both are supplied. A query selects a unique normalized exact label,...6 params

Assemble a global profile for one QCL item in a single call: top-producing countries, the annual production trend, and trade flows (top exporters and importers). Supply item_code or item_query; code wins when both are supplied. A query selects a unique normalized exact label,...

Parameters* required
canvas_idstring
Canvas ID to stage onto, as returned by a prior faostat_query_observations / faostat_commodity_profile call — exactly 10 characters of letters, digits, hyphens, and underscores. Omit to stage onto...
item_codeinteger
Exact item code present in QCL; takes precedence over item_query. Obtain it from faostat_resolve_codes with domain QCL and dimension item.
item_querystring
Commodity label or search term (e.g. "Wheat"). A unique normalized exact QCL label wins, otherwise the relevance search must match exactly one item. Broad queries such as "maize" or "milk" require...
top_ninteger
Number of top producers / exporters / importers to return. Max 50.default: 10
year_endinteger
Inclusive end year for the trend (e.g. 2022).
year_startinteger
Inclusive start year for the trend (e.g. 1990).
faostat_dataframe_queryRun a single-statement SELECT against canvas tables staged by faostat_query_observations and faostat_commodity_profile (faostat_xxxxxxxx). Use DuckDB joins, aggregates, window functions, and CTEs for rankings and time-series analysis. Item groups can overlap their members even...3 params

Run a single-statement SELECT against canvas tables staged by faostat_query_observations and faostat_commodity_profile (faostat_xxxxxxxx). Use DuckDB joins, aggregates, window functions, and CTEs for rankings and time-series analysis. Item groups can overlap their members even...

Parameters* required
canvas_idstring
Optional canvas ID as returned by a prior faostat_query_observations / faostat_commodity_profile call — exactly 10 characters of letters, digits, hyphens, and underscores. Omit to query the tables...
row_limitinteger
Hard cap on rows in the response. Default 1000, max 10000.default: 1000
sql*string
Single-statement read-only SELECT against staged faostat_<id> tables. Columns: area_code, area, item_code, item, element_code, element, year, unit, value, flag — plus domain (QCL or TCL) on tables...
faostat_dataframe_describeList the canvas tables (faostat_xxxxxxxx) staged by faostat_query_observations and faostat_commodity_profile, each with its source tool, the query parameters that produced it, creation/expiry timestamps, row count, and column schema. Call this before faostat_dataframe_query to...4 params

List the canvas tables (faostat_xxxxxxxx) staged by faostat_query_observations and faostat_commodity_profile, each with its source tool, the query parameters that produced it, creation/expiry timestamps, row count, and column schema. Call this before faostat_dataframe_query to...

Parameters* required
canvas_idstring
Optional canvas ID as returned by a prior faostat_query_observations / faostat_commodity_profile call — exactly 10 characters of letters, digits, hyphens, and underscores. Omit to list the tables s...
limitinteger
Maximum staged tables to return on this page (max 100). Each entry carries a full column schema, so the default keeps a discovery call small.default: 20
namestring
Optional table name (faostat_xxxxxxxx) to describe a single staged table. Takes precedence over `offset` / `limit`, which are ignored for a name lookup (always single-page).
offsetinteger
Zero-based pagination offset into the staged tables (newest first). When the response reports truncated, pass the returned nextOffset here to fetch the next page. Ignored for `name` lookups.default: 0

Sponsors

Configuration

FAOSTAT_DOMAINSdefault: QCL,TCL,FBS,FS,RL,GLE,RFN,QV

Comma-separated FAOSTAT domain codes to index into the local mirror.

FAOSTAT_MIRROR_PATHdefault: ./.faostat-mirror

Directory holding the per-domain SQLite mirror databases and the shared dimension database.

FAOSTAT_BULK_BASE_URLdefault: https://bulks-faostat.fao.org/production

FAOSTAT bulk-download service base URL (manifest + per-domain ZIPs).

CANVAS_PROVIDER_TYPEdefault: duckdb

DataCanvas engine for SQL over large result sets. Defaults to 'duckdb'; set 'none' to disable analytical staging.

FAOSTAT_DATAFRAME_DROP_ENABLEDdefault: false

Set to 'true' to make faostat_dataframe_drop callable, so a staged table can be dropped before its 2-hour TTL. Off by default: the tool is registered disabled.

MCP_LOG_LEVELdefault: info

Sets the minimum log level for output (e.g., 'debug', 'info', 'warn').

MCP_TRANSPORT_TYPEdefault: http

Selects the HTTP transport.

MCP_HTTP_HOSTdefault: 127.0.0.1

The hostname for the HTTP server.

MCP_HTTP_PORTdefault: 3010

The port to run the HTTP server on.

MCP_HTTP_ENDPOINT_PATHdefault: /mcp

The endpoint path for the MCP server.

MCP_AUTH_MODEdefault: none

Authentication mode to use: 'none', 'jwt', or 'oauth'.

FAOSTAT_REFRESH_CRON

Cron expression for the in-process incremental mirror refresh (HTTP transport only). Omit to disable.

Readme

@cyanheads/faostat-mcp-server

Global food & agriculture statistics from the UN FAOSTAT bulk-download corpus, served from a local SQLite mirror with a DataCanvas SQL surface, via MCP. STDIO or Streamable HTTP.

7 Tools • 1 Skill Resource • 0 Prompts

Details

Repository
github.com/cyanheads/faostat-mcp-server
Category
Databases
Package
@cyanheads/faostat-mcp-server
Transport
STDIO, HTTP
Registry
MCP registry, active
Resources
1
Tools verified
Nov 13, 2026

More from cyanheads

Related Databases MCP servers

View all
1madezmedia avatarAcmi Mcpmadezmedia/acmiPersistent agent memory via ACMI — Profile/Signals/Timeline. 16 tools on Upstash Redis.3stars
2nikitacometa avatarMnemon Mcpnikitacometa/mnemon-mcpPersistent layered memory for AI agents. SQLite FTS5, fact versioning, zero-cloud.3stars
3agentic-eng avatarA2dbagentic-eng/a2dbSafe, read-only database access for AI agents. 5 databases, batch queries, SQLGlot.2stars
4lu-zhengda avatarVirtual Filesystemlu-zhengda/mcp-virtual-fsPostgreSQL-backed virtual filesystem for agents: session isolation, shared stores, POSIX ops, RLS.2stars
5shrike-security avatarShrikeshrike-security/shrike-mcpGoverns what AI agents do: tool calls, SQL, commands, files checked against policy before they run.2stars
6alyiox avatarClickHousealyiox/mcp-clickhousexRead-only MCP server for ClickHouse metadata, parameterized queries, and plan analysis.1stars