faostat-mcp-server について
faostat-mcp-serverは、ローカルのSQLiteミラーから国連FAOSTATの食料・農業統計を提供します。世界の観測データの検索、コード解決、大規模な結果のSQL分析に使えます。
主な機能
- 01統計ドメインとローカル索引状態の閲覧
- 02地域、品目、要素コードの解決
- 03地域、品目、年を指定した観測データの検索
- 04生産と貿易を含む品目プロファイルの作成
- 05ステージング結果の読み取り専用SQL分析
活用シーン
- 01各国の農業生産量の比較
- 02年間生産量と品目貿易の追跡
- 03大量の観測データに対するSQL分析
MCP 対応
FAOSTATのドメイン探索、コード解決、観測データ検索、品目プロファイル、DataCanvas SQL用ツールをMCPクライアントに公開します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://faostat.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-faostat https://faostat.caseyjhand.com/mcp{"mcpServers":{"cyanheads-faostat":{"type":"http","url":"https://faostat.caseyjhand.com/mcp"}}}Cursor で開く{"servers":{"cyanheads-faostat":{"type":"http","url":"https://faostat.caseyjhand.com/mcp"}}}VS Code で開く{"mcpServers":{"cyanheads-faostat":{"type":"http","url":"https://faostat.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-faostat":{"serverUrl":"https://faostat.caseyjhand.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
6| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| code | string | いいえ | ドメインコードで正確に検索します(例:"RL")。大文字と小文字は区別しません。そのドメインの完全なレコードを1ページで返します。指定した場合、`topic` / `indexed_only` より優先されます。 |
| limit | integer | いいえ | このページで返すドメインの最大数(最大 200。カタログの件数を上回るため、値を大きくすれば一度にすべて取得できます)。ドメインの説明は長いため、デフォルト値では一覧取得の応答を小さく保てます。 |
| topic | string | いいえ | ドメインコード、名前、トピックを対象に、大文字と小文字を区別せず部分一致で絞り込みます(例:"trade"、"emissions"、"QCL")。省略するとカタログ全体を一覧表示します。 |
| offset | integer | いいえ | 一致したドメインに対する、0始まりのページネーションオフセットです(コード順)。応答で truncated が報告された場合、次のページを取得するには、返された nextOffset をここに指定します。コードの完全一致検索では無視されます(常に1ページ)。 |
| indexed_only | boolean | いいえ | true の場合、ローカルミラーでインデックス済みのドメイン(現在クエリ可能)のみを返します。 |
詳細
@cyanheads/faostat-mcp-server
MCP 経由で提供される、国連 FAOSTAT の一括ダウンロードデータを収録した、ローカルの SQLite ミラーと DataCanvas の SQL インターフェイスによる世界の食料・農業統計です。STDIO または Streamable HTTP に対応しています。
公開ホストサーバー: https://faostat.caseyjhand.com/mcp
概要
国連 FAOSTAT の世界の食料・農業統計です。生産、貿易、食料需給表、食料安全保障、土地利用、肥料、排出量を、1961 年以降の 245 か国・地域以上について提供します。商品コードと国コードを解決してデータを照会し、大規模な結果に対して SQL を実行できます。
ツール
| ツール | 説明 |
|---|---|
faostat_list_domains | FAOSTAT の統計ドメインを、コード、説明、最終更新日、上流の行数、ローカルのインデックス状態とともに確認します。すべてのクエリはドメインコードをキーにするため、最初に使用するツールです。 |
faostat_resolve_codes | 人間が読める用語を、クエリに必要な不透明な整数コード(地域、品目、要素)に解決し、各地域が国か集計地域かを示します。 |
faostat_query_observations | 地域、品目、要素、年の範囲でドメインのキューブを照会します。結果が少ない場合はインラインでプレビューし、大規模な結果は DataCanvas テーブルに格納します。 |
faostat_commodity_profile | ワークフロー:生産ドメインと貿易ドメインから、ある商品についての上位生産者、生産トレンド、貿易フローを 1 回の呼び出しでまとめます。 |
faostat_dataframe_query | 分析ツールによってステージングされたキャンバステーブルに対し、読み取り専用の SQL SELECT を実行します。 |
faostat_dataframe_describe | このセッションでステージングされたキャンバステーブルを、由来、行数、列スキーマとともに一覧表示します。 |
faostat_dataframe_drop | 2 時間の TTL が切れる前に、ステージングされたキャンバステーブルを 1 つ削除します。オプトイン方式です。FAOSTAT_DATAFRAME_DROP_ENABLED=true の場合のみ呼び出せます。 |
機能リファレンス
faostat_list_domains ツール
- バルクマニフェストからライブで読み込んだFAOSTATカタログ全体(約69ドメイン)。ローカルミラーの状態が注記されています
codeでドメインを完全一致検索、topicでコード/名前/トピックの部分一致フィルターを指定できます。indexed_onlyを指定すると、ローカルミラーからクエリ可能なドメインのみを一覧表示しますoffsetとlimit(最大200、デフォルト20)でカタログをページ分割します。レスポンスにはtotalMatches、truncated、nextOffsetが含まれます- 各エントリには
indexed/index_readyフラグ、ローカルの行数、最後に完了した同期が示されます
faostat_resolve_codes ツール
dimension(area、item、element)内で、FTS5全文検索のquery、名前の部分一致検索name_contains、またはコードの完全一致検索codeを指定します- item/element の一致結果は、指定した
domainのキューブ内に存在するコードに限定されます。area コードは全ドメインで共通です - area の一致結果にはすべて
countryまたはaggregateのフラグが付きます(コードが5000以上のもの、および中国=351など、厳選されたしきい値未満の集計コード) limit(最大200、デフォルト50)とoffsetで一致結果をページ分割します- 型付きエラー:
unknown_domain、index_not_ready、query_timeout
faostat_query_observations ツール
area_codes/item_codes/element_codesと、開始年・終了年を含むyear_start/year_endの範囲でフィルターします- デフォルトでは集計地域は除外されます(
include_aggregates: false)。area_codesを明示すると、この除外は適用されません limitはインラインページの上限です(デフォルト200、最大1000)。一致件数が上限を超えると、全件がDataCanvasテーブルにステージングされます(ステージング上限50,000行)。列を確認するにはfaostat_dataframe_describeを実行し、その後faostat_dataframe_queryでSQLを実行します- 各行にはデータ品質を示す
flag(A/E/I/B/M/T/X。そのほかの値はドメインによって異なります)が含まれ、削除されることはありません - 型付きエラー:
domain_not_indexed、index_not_ready、canvas_disabled、canvas_not_found、invalid_year_range、query_timeout
faostat_commodity_profile ツール
item_codeまたはitem_queryでQCLの項目を1つ選択し(item_codeが優先されます)、主要な生産国/輸出国/輸入国を順位付けし、年間生産量の推移を返します- クエリによる選択では、前後の空白の削除、連続する空白の圧縮、大文字と小文字の区別を無視した後に、一意の完全一致ラベルを優先します。それ以外の場合は、一意の関連度一致が必要です。
maizeやmilkなど、あいまいな用語の場合は、domain: "QCL"、dimension: "item"、およびクエリを指定してfaostat_resolve_codesを呼び出し、選択したitem_code(たとえば、とうもろこしの穀粒なら56)を渡してください - 順位は単位ごとに国別の合計値で、各国で最新の報告年を使用します。国のみが対象で、集計値は除外されます
- 貿易ドメイン(TCL)がインデックス化されていない、または同期中の場合は、失敗ではなく、通知とともに生産のみの部分的なプロファイルを返します
top_nは各順位リストの上限です(最大50)。結合された観測値が多すぎてインラインで返せない場合は、DataCanvasテーブルにステージングされます。列を確認するにはfaostat_dataframe_describeを実行し、その後、追加のSQLにはfaostat_dataframe_queryを使用します- すべてのステージング結果は通知に記載されます。ステージングされたテーブル、インラインに収まった結果、ステージングの失敗、または無効になっているキャンバスが示されます
- 型付きエラー:
missing_item、ambiguous_item、no_match、domain_not_indexed、index_not_ready、invalid_year_range、canvas_not_found、query_timeout
faostat_dataframe_query ツール
- ステージングされた
faostat_xxxxxxxxテーブルに対する、単一ステートメントの読み取り専用SELECT。結合、集計、ウィンドウ関数、CTEをすべて使用できます - 書き込み、DDL、
DROP、COPY、PRAGMA、ATTACH、外部ファイル関数、システムカタログ(information_schema、sqlite_master、duckdb_*)は拒否されます - エンジン設定のイントロスペクション、
query_table、動的なquery()SQL、ファイルテーブルへの参照は拒否されます。単一のリテラルな読み取り専用SELECTを使うquery()は引き続きサポートされます row_limitはレスポンスの上限です(デフォルト1000、最大10000)。truncatedは、さらに行が存在することを示します。この経路では正確な総数は計算されません- 型付きエラー:
canvas_disabled、canvas_not_found、missing_table、system_catalog_access、invalid_sql
faostat_dataframe_describe ツール
- ステージング済みテーブルを、ソースツール、クエリパラメーター、行数、列スキーマ、作成日時/有効期限(2時間のスライディング TTL)とともに一覧表示します
nameを指定すると、そのテーブルの詳細を表示します。指定しない場合は、offsetとlimit(最大100、デフォルト20)で新しい順に一覧をページ分割します- 型付きエラー:
canvas_disabled、canvas_not_found、missing_table
faostat_dataframe_drop ツール
- オプトイン方式です。
FAOSTAT_DATAFRAME_DROP_ENABLED=trueを設定しない限り、登録済みですが無効です。ランディングページには有効化のヒントとともに表示されますが、tools/listには表示されません - ステージング済みの
faostat_xxxxxxxxテーブル1つとその出所情報を、セッションのキャンバス、またはcanvas_idで指定したキャンバスから削除します - 冪等です。指定したキャンバスにステージングされていない名前の場合は、通知とともに
dropped: falseを返し、何も変更しません - 型付きエラー:
canvas_disabled、canvas_not_found
機能
@cyanheads/mcp-ts-core 上に構築されており、stdio および Streamable HTTP トランスポート、プラグイン式認証(none/jwt/oauth)、交換可能なストレージ(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1)、オプションの OpenTelemetry トレースを備えた構造化ログに対応しています。
FAOSTAT 固有の機能:
- フレームワークの
MirrorServiceを介した、FAOSTAT 一括データコーパスのローカル SQLite ミラー。コード解決には、ディメンションラベルを対象とする FTS5 を使用します - ストリーミング方式の一括 ZIP 取り込み処理。上流の更新日が進んでいないドメインはスキップし、正規化済み CSV をストリーム解析して SQLite に取り込みます。ファイル全体をメモリ上に展開することはありません
- 設定駆動のドメイン選択(
FAOSTAT_DOMAINS)。コードを変更せずにインデックス対象を拡張でき、全カタログも引き続き閲覧できます - DataCanvas の SQL インターフェース(DuckDB)により、スピルされた結果セットを対象とする
GROUP BY、ランキング、時系列分析が可能です
エージェントに適した出力:
- すべての地域に国/集計区分を付与し、デフォルトでは集計値を合計から除外します。これにより、世界や大陸の行とその構成国を二重計上するのを防ぎます
- データ品質の出所情報。すべての観測値に FAOSTAT フラグ(
A/E/I/B/M/T/X、およびドメインごとのその他のフラグ)が含まれ、出力から削除されることはありません - 部分的な結果を適切に返します。たとえば、trade ドメインがインデックスされていない場合、
faostat_commodity_profileは失敗するのではなく、通知とともに生産のみのプロファイルを返します - 型付きエラー契約。
index_not_ready、domain_not_indexed、canvas_disabledなど、それぞれに具体的な復旧方法のヒントが含まれます
はじめに
公開ホストインスタンス
公開インスタンスは https://faostat.caseyjhand.com/mcp で利用できます。インストールは不要です。Streamable HTTP を提供しており、クライアントごとに設定形式が異なります。
Claude Code の場合:
claude mcp add --transport http faostat-mcp-server https://faostat.caseyjhand.com/mcp
Cline の場合(cline_mcp_settings.json):
{
"mcpServers": {
"faostat-mcp-server": {
"type": "streamableHttp",
"url": "https://faostat.caseyjhand.com/mcp"
}
}
}
Cursor の場合(mcp.json):
{
"mcpServers": {
"faostat-mcp-server": {
"url": "https://faostat.caseyjhand.com/mcp"
}
}
}
Claude Desktop では、Settings → Connectors からリモートサーバーを追加できます。
セルフホスト/ローカル
以下を MCP クライアントの設定ファイルに追加してください。サーバーはローカルミラーのみで動作するため、クエリを実行する前に一度ミラーを構築してください。
{
"mcpServers": {
"faostat-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/faostat-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
または、npx を使用する場合(Bun は不要です):
{
"mcpServers": {
"faostat-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/faostat-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
または、Docker を使用する場合:
{
"mcpServers": {
"faostat-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"-v", "faostat-mirror:/usr/src/app/.faostat-mirror",
"ghcr.io/cyanheads/faostat-mcp-server:latest"
]
}
}
}
Streamable HTTP を使用する場合は、トランスポートを設定してサーバーを起動してください:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
API キーは不要です。FAOSTAT の一括ダウンロードサービスは公開されており、キーなしで利用できます。
前提条件
- Bun v1.4.0 以降(または Node.js v24 以降)。
- ローカルミラー用のディスク容量。デフォルトのドメインセット(
QCL,TCL,FBS,FS,RL,GLE,RFN,QV、約3,700万行)には数 GB が必要です。TCL(約1,700万行)が大半を占めるため、容量に制約のあるホストではFAOSTAT_DOMAINSから除外できます。
インストール
- リポジトリをクローンします:
git clone https://github.com/cyanheads/faostat-mcp-server.git
- ディレクトリに移動します:
cd faostat-mcp-server
- 依存関係をインストールします:
bun install
- 環境を設定します:
cp .env.example .env
# edit .env to override the default domain set, mirror path, or refresh cron
ミラーの構築
コーパスはバンドルされていません。データツールがクエリに応答する前に、選択したドメインをローカルミラーに同期してください。
bun run mirror:init # one-time bootstrap — downloads and indexes the FAOSTAT_DOMAINS set
bun run mirror:refresh # re-sync domains whose upstream update date has advanced; build missing planner statistics
bun run mirror:verify # report sync status, local row counts, and sample reads
mirror:init は冪等で、ドメインごとに再開できます。中断後に再実行すると、未完了のドメイン ZIP のみが再ストリーミングされます。FAOSTAT_DOMAINS でインデックス対象のドメインを選択します。カタログ内のその他のドメインは、追加して再同期するまで faostat_list_domains に indexed: false と表示されます。HTTP トランスポートでは、FAOSTAT_REFRESH_CRON を設定すると、プロセス内で定期的に更新されます。stdio では、プロセス外で mirror:refresh を実行してください。最初の同期が完了するまで、読み取りツールは index_not_ready を返します。
mirror:refresh は、選択したドメインのデータに上流で変更がない場合でも、クエリプランナー用の統計情報(ANALYZE)がまだないドメインについて、その情報も構築します。これは、以前のリリースで同期したミラーや、直近の構築に失敗したミラーにも適用されます。それ以外の場合は、データ読み取りがそのドメインに初めてアクセスしたときに、サーバーがワーカースレッド上でバックグラウンドに構築し、その間も応答を続けます。
設定
| 変数 | 説明 | デフォルト |
|---|---|---|
FAOSTAT_DOMAINS | ローカルミラーにインデックスする FAOSTAT ドメインコード。指定したセット外のドメインは faostat_list_domains に表示されますが、追加して再同期するまでクエリできません。 | QCL,TCL,FBS,FS,RL,GLE,RFN,QV |
FAOSTAT_MIRROR_PATH | ドメインごとの SQLite ストアと共有ディメンションデータベースを格納するディレクトリ。存在しない場合は作成されます。 | ./.faostat-mirror |
FAOSTAT_BULK_BASE_URL | FAOSTAT 一括ダウンロードサービスのベース URL(マニフェストとドメインごとの ZIP)。 | https://bulks-faostat.fao.org/production |
FAOSTAT_REFRESH_CRON | プロセス内の増分更新用 cron(HTTP トランスポートのみ)。無効にする場合は省略し、プロセス外で mirror:refresh を実行してください。 | — |
CANVAS_PROVIDER_TYPE | DataCanvas エンジン。duckdb を指定すると SQL サーフェスが有効になります。分析用ステージングを無効にするには none を設定してください(その場合、dataframe_* ツールは canvas_disabled を返し、大規模なクエリはスピルを拒否します)。 | duckdb |
FAOSTAT_DATAFRAME_DROP_ENABLED | true を設定すると、faostat_dataframe_drop を呼び出せるようになります。無効の場合、ツールは無効状態で登録され、tools/list には表示されず、ランディングページにはこのヒントとともに表示されます。 | false |
MCP_TRANSPORT_TYPE | トランスポート:stdio または http。 | stdio |
MCP_SESSION_MODE | HTTP セッションモード:stateless、stateful、または auto(stateful に解決されます)。サーバーは src/index.ts で stateless を宣言しています。ハンドラーの途中で呼び出し元に入力を求めるツールはありません。この設定を指定すると、その宣言は上書きされます。 | stateless |
MCP_HTTP_PORT | HTTP サーバーのポート。 | 3010 |
MCP_AUTH_MODE | 認証モード:none、jwt、または oauth。 | none |
MCP_LOG_LEVEL | ログレベル(RFC 5424)。 | info |
LOGS_DIR | ログファイル用ディレクトリ(Node.js のみ)。 | <project-root>/logs |
オプションで上書きできる設定の一覧は、.env.example を参照してください。
サーバーの実行
ローカル開発
-
ビルドと実行:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:http -
チェックとテストの実行:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest suite under Bun, then under Node bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t faostat-mcp-server .
docker run --rm -p 3010:3010 -v faostat-mirror:/usr/src/app/.faostat-mirror faostat-mcp-server
Dockerfile は、HTTP トランスポート、ステートレスセッションモード、/var/log/faostat-mcp-server へのログ出力をデフォルトで設定します。専用の依存関係ステージで、対象プラットフォーム向けの本番用ツリーをインストールします(DuckDB のビルド済みネイティブバインディングを含みます)。そのため、スリムなランタイムイメージにはビルドツールチェーンが含まれず、マルチアーキテクチャビルドでもエミュレーション下で Bun を実行しません。OpenTelemetry のピア依存関係はデフォルトでインストールされます。省略するには、--build-arg OTEL_ENABLED=false を指定してビルドしてください。コンテナーの再作成後もコーパスを保持するには、ミラーパスにボリュームをマウントし、コンテナー内で初期化してください。
docker exec <container> bun run mirror:init # one-time bootstrap
docker exec <container> bun run mirror:verify # sync status + sample reads
docker exec <container> bun run mirror:refresh # re-sync updated domains; build missing planner statistics
プロジェクト構成
| ディレクトリ | 目的 |
|---|---|
src/index.ts | createApp() のエントリーポイントです。7 つのツールを登録し(オプトインフラグが有効な場合のみ faostat_dataframe_drop を登録します)、setup() でミラーとキャンバスを接続し、HTTP 更新をスケジュールします。 |
src/config | サーバー固有の環境変数の解析と、Zod による検証を行います。 |
src/mcp-server/tools/definitions | ツール定義(*.tool.ts)です。 |
src/services/faostat-mirror | 一括ダウンロードミラーサービスです。マニフェストの検出、ストリーミング ZIP インジェスター、CSV 解析、ディメンションストア、SQLite ベースの MirrorService の接続、およびメインスレッド外でキューブ読み取りと統計情報の構築を実行する 2 ワーカー読み取りプール(read-pool.ts、read-worker.ts)を含みます。 |
src/services/canvas-accessor.ts、canvas-staging.ts | DataCanvas アクセサーと、スピル/クエリ/説明/削除のステージングレイヤーです。 |
scripts/faostat-mirror-*.ts | mirror:init/mirror:refresh/mirror:verify CLI です。 |
tests/ | src/ に対応するユニットテストと統合テストです。 |
開発ガイド
開発ガイドラインとアーキテクチャ上のルールについては、CLAUDE.md/AGENTS.md を参照してください。要点は次のとおりです。
- ハンドラーは例外をスローし、フレームワークが捕捉します。ツールのロジック内で
try/catchを使用しないでください。 - リクエスト単位のログには
ctx.logを、テナント単位のストレージにはctx.stateを使用します。 - 新しいツールは、
src/index.tsのcreateApp()配列に登録します。 - 外部データは、未加工の値を検証し、ドメイン型に正規化してから、出力スキーマに沿って返します。不足しているフィールドを捏造せず、データ品質フラグを引き継いでください。
データの帰属表示
データの出典は、国際連合食糧農業機関(FAO)の統計部門である FAOSTAT です。FAOSTAT のデータは CC BY-4.0 の下で公開されています。二次利用では、出典として FAO を明記してください。このプロジェクトは FAO と提携しておらず、FAO の推薦を受けているものでもありません。
コントリビューション
Issue を歓迎します。提出前にチェックとテストを実行してください。
bun run devcheck
bun run test
ライセンス
Apache-2.0 — 詳細は LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。