Install
$ agentstack add skill-berba-q-faostat-skills-export-dataset ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
FAOSTAT Data Export
Ship clean, documented FAOSTAT data. The user wants the numbers, not the story. Deliver a three-file bundle: one multi-sheet .xlsx, one tidy-long .csv, and a data-dictionary .md. Every row traces back to the FAOSTAT API call that produced it.
Prerequisites
FAOSTAT MCP tools: faostat_get_data, faostat_search_codes, faostat_list_domains, faostat_get_metadata. If any are missing, stop and tell the user the skill requires the FAOSTAT MCP server.
Python packages: openpyxl, pandas. Install with --break-system-packages in the sandbox.
Invariants
Cross-skill invariants (all six — violations are skill bugs):
- FILTER vs DISPLAY codes.
faostat_get_datatakes FILTER codes (e.g.,2510Production).faostat_get_rankingstakes DISPLAY codes (e.g.,5510). Never invert. - Year syntax. Comma-separated lists only (
'2010,2011,...,2023'). Colon ranges return empty in practice. - Element filter required on every
faostat_get_datacall. Unfiltered pulls are massive, especially in emissions domains. - TCL for national trade aggregates, TM only for partner breakdowns. Never sum TM rows to reconstruct national totals.
- China composite default (Apr 2026 user preference). Default: composite
China(area 351).China, mainland(41) is an opt-in; full disaggregation (41 + 96 + 128 + 214) is also opt-in. Record the choice in the README sheet with the FAOSTAT-default-41 caveat. faostat_get_rankingsHTTP-500 fallback. On failure, reconstruct by pullingfaostat_get_dataacross all reporting countries and sorting client-side. Note the fallback in Methodology.
- Element and item code resolution. Never use a hardcoded numeric element or item code as the primary value in a
faostat_get_datacall. Always resolve at runtime:faostat_search_codes(domain_code='', dimension_id='element', query='')for elements;faostat_search_codes(domain_code='', dimension_id='item', query='')for items. Numeric codes shown in reference tables and code examples are verified hints — use them to validate the search result, not as the authoritative source. Domain letter-codes (QCL, TCL, GT, EM, FBS, FS…) are stable and may be used directly.
Export-specific invariants:
- Every value traces to an API call. The Methodology sheet logs one row per
faostat_get_datacall with domain / area / element / item / year list / timestamp / rows-returned. No value appears in the export that did not come from a documented call. - FAO-native units kept as-is. No auto-conversion. Values stay in FAOSTAT's native units (kt CO₂eq, tonnes, USD 1000, etc.). Unit is a column in tidy-long and a header row in wide. If the user explicitly asks for normalised units, add normalised columns alongside the native ones — never in place of.
- No FAO branding. No FAO logo, "Food and Agriculture Organization of the United Nations" masthead, ISSN, "FAO Statistics Division" stamp, or "Required citation: FAO. …" line. CC-BY-4.0 attribution to FAOSTAT (source, licence, access date) IS kept — that's a property of the source data.
- Both shapes in the xlsx.
Data_tidy(long) andData_wide(years-as-columns pivot) are both always present. The CSV mirror is tidy-long only. A wide CSV is produced only if the user asks.
Workflow
Step 1 — Gather parameters
Required from the user (prompt via AskUserQuestion in Cowork, inline otherwise):
- Domain — e.g., GT, QCL, TCL, ET, PP, FBS, FS.
- Element(s) — FILTER code(s). If the user supplies a name rather than a code, resolve via
faostat_search_codes(invariant 7) before use. - Year range — list of years (will be passed comma-separated).
- Area scope — World, specific regions, specific country list, or "all reporting countries". Default if unspecified: all reporting countries plus regional aggregates (5000/5100/5200/5300/5400/5500).
Optional:
- Item(s) — FILTER code(s). If omitted, all items in domain for the chosen element.
- Flag filter — default keep all; optional strip to official-value-only.
- China handling — default
composite_351. Options:mainland_41ordisaggregated(41,96,128,214). - Topic title — propose one from domain + element + item + year range if the user does not supply.
Step 2 — Resolve codes
Always resolve element and item codes at runtime before the data pull (invariant 7). Call faostat_search_codes(domain_code=…, dimension_id='element'|'item'|'area', query=…) for every numeric code needed — even when the user supplies a code directly, verify it matches. Print the resolved codes back in a short confirmation block before the heavy pull so mismatches surface early.
Step 3 — Pull data
Call faostat_get_data with:
domain_codearea= comma-separated list (applying the China rule:351composite /41mainland /41,96,128,214disaggregated)element= comma-separated FILTER codesitem= comma-separated FILTER codes (or omit for "all items in domain")year= comma-separated year list (invariant 2)
Log one Methodology row per API call, as the call is made — do not retrofit. If multiple element codes need different item sets, issue separate calls and concatenate. Never conflate element-item pairings across calls.
Step 4 — Clean the dataframe
In order:
- Coerce
Valueto numeric. Drop rows whereValueis null. - Rename columns to the canonical schema:
area_code, area, item_code, item, element_code, element, year, unit, value, flag, note(omititem_code/itemif the domain has no items, e.g. ET temperature anomalies). - Keep both code and label columns — downstream analysts need them.
- Sort by
area, item, element, year.
Step 5 — Build the tidy-long CSV
Schema: area_code, area, item_code, item, element_code, element, year, unit, value, flag, note.
Header comment lines at the top of the CSV (prefixed with #):
# Source: FAOSTAT (https://www.fao.org/faostat/), accessed YYYY-MM-DD. Licence: CC-BY-4.0.
# Domain: (). Elements: . Items: . Years: .
# China handling: .
# Rows: . Generated by faostat-export-dataset skill.
Save as _-_tidy.csv.
Step 6 — Build the wide pivot
Rows: (area_code, area, item_code, item, element_code, element, unit). Columns: years. Values: value.
Keep area_code and item_code — do not drop identifiers. If the pivot contains multiple elements with different units, keep one row per element; unit shown in its own column.
Step 7 — Assemble the xlsx
Sheets in this order:
- README — plain-prose block:
- Title (topic + year range)
- Source line (FAOSTAT, licence, access date)
- Column dictionary (one line per column — mirrors the
.mdfile) - China-handling choice with the FAOSTAT-default-41 caveat
- Flag codes key (from
faostat_get_metadata) - File manifest (tidy.csv / xlsx / data-dictionary.md)
- Data_tidy — identical schema to the tidy CSV (no
#comment header inside xlsx). - Data_wide — pivoted with years as columns.
- Methodology — one row per API call:
call_id, timestamp_utc, domain, area_param, element_param, item_param, year_param, rows_returned, notes. Year param stored as the literal comma-separated string that was passed. - Sources — one row per domain used:
domain_code, domain_label, citation, url, licence, access_date. Pulled fromfaostat_get_metadata.
Step 8 — Build data-dictionary.md
Plain markdown file:
- Dataset description — topic, year range, scope, row count.
- Column schema table — column name | type | description | example | nullable.
- Unit reference table — unit string | full name | note (no conversion applied; purely descriptive).
- Flag codes — flag | meaning.
- Known caveats — China handling, any FAOSTAT revisions relevant to the pulled years, any items that changed codes over the series.
- Citation block — FAOSTAT + licence + access date + full URL of each domain used.
Step 9 — Save and present
Save all three files to the outputs folder with a shared slug:
.xlsx_tidy.csv_data-dictionary.md
Confirm to the user with links to all three files and a one-line summary: "topic, year range, N rows, K sheets in xlsx, China handling = choice." Nothing more — this is a data-delivery skill, not a narrative skill.
Slug convention
{domain_lower}_{primary_element_label}_{year_start}-{year_end}
Examples:
gt_emissions-total_2001-2023qcl_production_cattle-poultry-pig_2010-2024tcl_export-value_cereals_2015-2024pp_producer-price_coffee-cocoa_2020-2024
Lowercase, hyphen-separated labels, underscore between segments.
Error handling
- Empty
faostat_get_dataresult. Re-check comma-separated year syntax (invariant 2) and the element/item resolution. If the problem persists, widen the item filter to "all items in domain" to confirm the domain + area + year combo returns anything at all. Log the failure in Methodology withrows_returned = 0, notes = "…". - Rankings HTTP 500. Use the
get_datafallback (invariant 6). Record in Methodology. - Mixed units in one element. Shouldn't happen for a single element code; if it does, split into separate
Data_wideblocks per unit. - User asks for a narrative or a chart. Decline politely and route to
faostat-analytical-brief/faostat-infographic/faostat-story/faostat-scientific-paper/faostat-viz. This skill is data-only. - User asks to normalise units. Explain the invariant (keep FAO-native, auditable). If they insist, add normalised columns alongside — never replace the native ones.
Defaults summary
| knob | default | |---|---| | bundle | xlsx + tidy csv + data-dictionary md | | shapes | tidy-long + wide pivot (both) | | China | composite 351 | | units | FAO-native (no conversion) | | flag filter | keep all flags | | year range | user must supply — no default | | item filter | if omitted, all items in domain | | area scope | if omitted, all reporting countries + regional aggregates |
All defaults can be overridden by the user; every override is documented in the README sheet and the data-dictionary.md.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: berba-q
- Source: berba-q/faostat-skills
- License: MIT
- Homepage: https://github.com/berba-q/faostat-skills
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.