Faostat Mcp

by berba-q

15 stars
1k downloads
Not rated
GitHub

About

MCP server that exposes the full FAOSTAT API as tools for AI assistants — query UNFAO Food & Agriculture Statistics in natural language via Claude, Cursor, or any MCP-compatible client.

Details

Author
berba-q
GitHub stars
15
Downloads
1,015
Categories
Developer Tools, AI

- 21 MCP tools covering all FAOSTAT endpoints
- 245 countries and territories across dozens of domains
- Built-in rate limiting (2 requests per second)
- Auto-retry with exponential backoff on transient errors
- 3-tier hybrid caching (memory, SQLite, optional Redis)
- Zero-config credential storage via faostat_setup tool
- Disambiguation via faostat_search_codes to avoid code confusion

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Faostat Mcp
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Install via pip install faostat-mcp or uvx faostat-mcp, configure FAOSTAT credentials using the faostat_setup tool or environment variables, then run the server with faostat-mcp. Connect any MCP-compatible client such as Claude Desktop, Cursor, or Windsurf.

faostat_ping

Check the FAOSTAT API health status. Returns a status message indicating if the API is online.

faostat_refresh_token

Force-refresh the FAOSTAT API authentication token. Use this tool when other FAOSTAT tools fail with 401 Unauthorized or token-expiry errors. It logs in with the configured credentials (FAOSTAT_USERNAME + FAOSTAT_PASSWORD) and obtains a fresh JWT token. Requires FAOSTAT_USERNAME and FAOSTAT_PASSWORD to be configured — either as environment variables or via faostat_setup.

faostat_setup

Configure FAOSTAT credentials — call this once to authenticate. After setup, all other tools work automatically across sessions without any manual config file editing. The tool validates your credentials against the FAOSTAT API before saving, then stores them securely for future use: - macOS / Windows: stored in the system keychain (if keyring package is installed) - Linux / Docker: stored in ~/.config/faostat-mcp/credentials.json (mode 600) You can register for a free FAOSTAT account at https://www.fao.org/faostat/ Args: username: Your FAOSTAT account email address. password: Your FAOSTAT account password. Returns confirmation of where credentials were saved, or an error with a clear message if authentication failed.

faostat_list_groups

List all top-level FAOSTAT data groups (e.g. Production, Trade, Food Security). Use this to discover what categories of data are available. Args: lang: Language code (default: 'en')

faostat_groups_and_domains

Get the full hierarchical tree of all FAOSTAT groups and their domains. Use this for a complete overview of all available datasets. Args: lang: Language code (default: 'en')

faostat_list_domains

List all datasets (domains) within a FAOSTAT group. Args: group_code: The group code (e.g. 'Q' for Production, 'T' for Trade, 'FS' for Food Security). Get codes from faostat_list_groups. lang: Language code (default: 'en')

faostat_get_dimensions

Get the structure of a domain — what dimensions (filters) are available, such as area (country), item (commodity), element (measure), and year. Args: domain_code: Domain code (e.g. 'QCL' for Crops and Livestock, 'TM' for Trade, 'FS' for Food Security) lang: Language code (default: 'en')

faostat_get_codes

Get the list of available FILTER codes for a specific dimension in a domain. You MUST call this before faostat_get_data to get the correct codes for filtering. IMPORTANT: For the 'element' dimension, filter codes differ from the display codes shown in data responses. For example in QCL, faostat_get_codes returns filter code '2510' for Production, but the data response shows '5510' in the Element Code column. Always use the codes from this tool when filtering. Args: dimension_id: Dimension identifier (e.g. 'area', 'item', 'element', 'year') domain_code: Domain code (e.g. 'QCL', 'TM', 'FS') lang: Language code (default: 'en') limit: Maximum number of codes to return (default: 0 = no limit). Useful for large dimensions like 'item' which can have 1000+ entries. Examples: faostat_get_codes(dimension_id='element', domain_code='QCL') → Returns element filter codes: 2510=Production, 2312=Area harvested, etc. faostat_get_codes(dimension_id='area', domain_code='QCL') → Returns country/area codes: 2=Afghanistan, 3=Albania, etc. TIP: To find a code by name (e.g. 'production', 'wheat', 'Nigeria'), use faostat_search_codes instead — it returns filtered results and signals whether the match is unambiguous before you proceed to faostat_get_data.

faostat_search_codes

Search codes in a dimension by name — use this BEFORE faostat_get_data when you have a partial or uncertain code name (e.g. 'production', 'wheat', 'Nigeria'). This tool prevents wrong-code errors by making ambiguity explicit: - Exactly 1 match → safe to proceed (requires_confirmation=False) - Multiple matches → STOP and ask the user to choose (requires_confirmation=True) - No matches → broaden your search term AGENT INSTRUCTION: When the response contains "requires_confirmation": true, you MUST present ALL entries in the "matches" list to the user and ask them to select one before calling faostat_get_data, faostat_get_rankings, or any other data tool. Do NOT guess or automatically pick the first match. Args: domain_code: Domain code to search within (e.g. 'QCL', 'TM', 'FS'). dimension_id: Dimension to search ('element', 'item', 'area', 'year'). query: Partial or full name to search for (case-insensitive substring). Examples: 'production', 'wheat', 'gross production index'. lang: Language code (default: 'en'). Returns a JSON object with one of these shapes: Single match — safe to proceed: {"match": {"code": "2510", "label": "Production"}, "requires_confirmation": false, "message": "Unique match found. Use code '2510' as the element filter."} Multiple matches — MUST ask user before proceeding: {"matches": [{"code": "2510", "label": "Production"}, {"code": "2512", "label": "Gross Production Index Number"}], "requires_confirmation": true, "message": "Multiple matches for 'production' in element/QCL. Ask the user."} No matches: {"matches": [], "requires_confirmation": false, "message": "No codes match '...'. Use faostat_get_codes to browse all codes."} Examples: faostat_search_codes('QCL', 'element', 'production') → Multiple matches (Production, Gross Production Index) — ask user. faostat_search_codes('QCL', 'area', 'nigeria') → Single match for Nigeria — safe to proceed with code '231'.

faostat_get_data

Fetch statistical data from a FAOSTAT domain. This is the primary tool for retrieving actual data values. When you do not have an exact item, element, or area code, call faostat_search_codes first. If it returns requires_confirmation=True, you MUST ask the user to choose from the listed options before calling this tool. IMPORTANT: For large domains, always filter by area/item/year to avoid very large responses. Check query size first with faostat_get_datasize. IMPORTANT: Element codes used for filtering differ from the display codes returned in the response. Always use faostat_get_codes(dimension_id='element', domain_code=...) to get the correct filter codes. For example, in QCL: - Filter with element='2510' → response shows Element Code '5510' (Production) - Filter with element='2312' → response shows Element Code '5312' (Area harvested) Args: domain_code: Domain code (e.g. 'QCL' for Crops and Livestock Products) lang: Language code (default: 'en') area: Country/area codes, comma-separated (e.g. '2' for Afghanistan). Use faostat_get_codes(dimension_id='area', domain_code=...) to find codes. element: Element FILTER codes, comma-separated (e.g. '2510' for Production, '2312' for Area harvested in QCL). These differ from the display codes in the response. Always look up via faostat_get_codes first. item: Item/commodity codes, comma-separated (e.g. '515' for Apples, '15' for Wheat) year: Year codes, comma-separated (e.g. '2020' or '2018,2019,2020') area_cs: Area code set name (alternative to individual area codes) element_cs: Element code set name item_cs: Item code set name year_cs: Year code set name (e.g. 'FAO_YEAR_RECENT' for recent years) show_codes: Include code columns in response (default: False — names are more useful for interpretation; codes are for filtering) show_unit: Include unit column in response (default: True) show_flags: Include data quality flags (default: False — rarely needed) null_values: Include rows with null values (default: False) limit: Maximum number of rows to return (default: 50). Set to 0 for no limit. Use faostat_get_datasize first if you expect a large result set. response_format: Output format (default: 'objects'). - 'objects': Array of self-describing JSON objects (best LLM comprehension) - 'compact': Columnar {"columns": [...], "rows": [[...]]} (~3x smaller) - 'csv': Plain CSV text with header row (~4x smaller) Use 'compact' or 'csv' when retrieving larger datasets to reduce token usage. fields: Comma-separated column names to include (e.g. 'Area,Year,Value'). Omit to include all columns. Use to reduce response size further. Examples: # Apple production in Afghanistan 2024 (element 2510 = Production filter code) faostat_get_data('QCL', area='2', item='515', element='2510', year='2024') # Food security indicators for all African countries faostat_get_data('FS', area_cs='AFRICA') # Minimal response — only area, year and value in CSV format faostat_get_data('QCL', area='231', item='15', element='2510', year='2024', response_format='csv', fields='Area,Year,Value')

faostat_get_datasize

Estimate the number of rows a data query will return BEFORE fetching. Use this to check if a query is too large before calling faostat_get_data. Accepts the same filter parameters as faostat_get_data. Args: domain_code: Domain code (e.g. 'QCL', 'TM', 'FS') lang: Language code (default: 'en') area: Country/area codes, comma-separated element: Element filter codes, comma-separated item: Item/commodity codes, comma-separated year: Year codes, comma-separated area_cs: Area code set name element_cs: Element code set name item_cs: Item code set name year_cs: Year code set name

faostat_get_definitions

Get all definitions (descriptions of items, elements, flags) for a domain. Args: domain_code: Domain code (e.g. 'QCL', 'FS', 'TM') lang: Language code (default: 'en')

faostat_get_definitions_by_type

Get definitions for a domain filtered by type (e.g. items, elements, flags). Args: domain_code: Domain code (e.g. 'QCL') definition_type: Type of definition. Use faostat_definition_types to see options. lang: Language code (default: 'en')

faostat_definition_types

List all available definition types (used with faostat_get_definitions_by_type). Args: lang: Language code (default: 'en')

faostat_get_metadata

Get full methodology and metadata for a domain — including data sources, collection methods, coverage, and limitations. Args: domain_code: Domain code (e.g. 'QCL', 'FS', 'GCE') lang: Language code (default: 'en')

faostat_get_metadata_print

Get metadata for a domain in a printable/simplified format. Args: domain_code: Domain code (e.g. 'QCL', 'FS') lang: Language code (default: 'en')

faostat_list_bulk_downloads

List available bulk download files for a domain (ZIP/CSV archives). These contain the full domain dataset and can be very large. Args: domain_code: Domain code (e.g. 'QCL', 'TM') lang: Language code (default: 'en')

faostat_list_documents

List related documents (methodology papers, questionnaires) for a domain. Args: domain_code: Domain code (e.g. 'QCL', 'FS') lang: Language code (default: 'en')

faostat_get_rankings

Get rankings — e.g. top countries by production, yield, or trade value. Use this to answer "which country produces the most X?" questions. NOTE: element_code here is the DISPLAY code (e.g. '5510'), not the filter code used in faostat_get_data. Rankings use the same codes shown in data responses. Args: domain_code: Domain to rank within (e.g. 'QCL') element_code: Display element code to rank by (e.g. '5510' for Production in QCL) item_code: Commodity code (e.g. '56' for Maize, '15' for Wheat) year: The year to rank for (e.g. '2022') lang: Language code (default: 'en') limit: Number of top results to return (default: 10) response_format: Output format: 'objects' (default), 'compact', or 'csv' Example: faostat_get_rankings(domain_code='QCL', element_code='5510', item_code='56', year='2022', limit=10) → Top 10 maize-producing countries in 2022

faostat_get_report_data

Get structured report data from FAOSTAT. Args: payload: Report query parameters (structure depends on report type) lang: Language code (default: 'en')

faostat_get_report_headers

Get the column headers/schema for a report before fetching its data. Args: payload: Report query parameters lang: Language code (default: 'en')

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "faostat mcp": {
            "faostat": {
                "command": "uvx",
                "args": [
                    "faostat-mcp"
                ],
                "env": {
                    "FAOSTAT_API_TOKEN": "your_token_here",
                    "FAOSTAT_BASE_URL": "https://faostatservices.fao.org/api/v1",
                    "FAOSTAT_DEFAULT_LANG": "en"
                }
            }
        }
    }
}

McpServers

{
    "faostat": {
        "command": "uvx",
        "args": [
            "faostat-mcp"
        ],
        "env": {
            "FAOSTAT_API_TOKEN": "your_token_here",
            "FAOSTAT_BASE_URL": "https://faostatservices.fao.org/api/v1",
            "FAOSTAT_DEFAULT_LANG": "en"
        }
    }
}

FAOSTAT MCP Server

> Query UN food and agriculture statistics with AI — powered by the Model Context Protocol

Version
PyPI
MCP Registry
Python 3.10+
MCP Compatible
License: MIT

An MCP (Model Context Protocol) server that exposes the full FAOSTAT API as tools for AI assistants. Connect any MCP-compatible client — Claude, Cursor, Windsurf, Zed, or your own agent — to the world's most comprehensive database of food, agriculture, fisheries, forestry, and nutrition statistics, covering 245 countries and territories from the United Nations Food and Agriculture Organization (FAO).

Keywords: FAOSTAT, MCP server, Model Context Protocol, AI agriculture data, FAO statistics, food security AI, agricultural data Python, UN data, crop production statistics, Claude, Cursor, Windsurf

---

Why Use This?

Researchers, data journalists, policy analysts, and developers can ask natural-language questions and get answers directly from FAOSTAT — without writing a single API call. Your AI assistant handles domain discovery, filtering, and interpretation automatically.

Who is this for?
- Agricultural economists and food security researchers
- Journalists and policy analysts working with FAO data
- Developers building AI pipelines on top of FAOSTAT
- Anyone who wants to explore crop, trade, nutrition, or emissions data conversationally

---

What is FAOSTAT?

FAOSTAT is the statistical database of the United Nations Food and Agriculture Organization (FAO). It is the world's most comprehensive freely available source of data on food and agriculture, covering:

- Crop and livestock production — yields, harvested area, and quantities for hundreds of commodities
- Trade — import/export volumes and values between countries
- Food security — prevalence of undernourishment, dietary energy supply, and access indicators
- Emissions — greenhouse gas emissions from agriculture, land use, and food systems
- Forestry and fisheries — production and trade data
- Prices, inputs, and population — producer prices, fertilizer use, and demographic context

Data spans from 1961 to the present, across 245 countries and territories, in multiple languages.

What is MCP?

The Model Context Protocol is an open standard that lets AI assistants call external tools at runtime. This server registers all FAOSTAT API endpoints as discoverable tools — your AI assistant automatically selects and chains the right calls when you ask a question.

---

Features

- 21 MCP tools covering every FAOSTAT endpoint (data, metadata, rankings, bulk downloads, reports)
- 245 countries and territories across dozens of domains: crops, livestock, trade, food security, emissions, forestry, fisheries, and more
- Built-in rate limiting (2 req/s) — safe for the FAOSTAT production API out of the box
- Auto-retry with exponential backoff on transient network errors
- Rich tool descriptions so the AI knows exactly when and how to call each tool
- 3-tier hybrid caching — in-memory (20 min) → SQLite disk (24 h, cross-session) → Redis (optional, 30 min)
- Zero-config auth via faostat_setup — store credentials once, never touch a config file again
- Disambiguation via faostat_search_codes — agents ask before guessing ambiguous codes
- Works with Claude Desktop, Claude Code, Cursor, Windsurf, Zed, and any MCP-compatible client

---

Quick Start

Prerequisites

- Python 3.10+
- Any MCP-compatible client (Claude Desktop, Cursor, Windsurf, Zed, or a custom agent)

Option A — Install via MCP Registry (recommended)

Listed on the official MCP Registry — discoverable directly from Claude Desktop, Cursor, and any MCP-compatible client.

```bash

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.