fema-mcp-server について
fema-mcp-serverは、災害研究者や公共部門の分析担当者向けに、FEMAの災害宣言、公共支援、住宅支援、NFIP保険金請求データを提供します。OpenFEMAのデータセット検索にも対応し、ステージングした請求データをSQLで分析できます。
主な機能
- 01州・種類・日付による災害宣言検索
- 02災害指定地域とプログラム情報の取得
- 03公共支援プロジェクトと支出額の検索
- 04住宅支援とNFIP保険金請求の取得
- 05ステージング済み請求データへの読み取り専用SQL
活用シーン
- 01州や災害の種類を指定して宣言を検索
- 02災害に対する公共支援資金の内訳を確認
- 03郡や郵便番号別に住宅支援を確認
- 04指定地域の洪水保険請求を分析
MCP 対応
MCP サーバーとして、STDIOまたはStreamable HTTP経由で災害・支援・保険金請求の検索ツールと災害概要リソースを提供します。大量のNFIP結果はステージングしてSQLで照会できます。公開OpenFEMA APIにキーは不要です。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://fema.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-fema https://fema.caseyjhand.com/mcp{"mcpServers":{"cyanheads-fema":{"type":"http","url":"https://fema.caseyjhand.com/mcp"}}}Cursor で開く{"servers":{"cyanheads-fema":{"type":"http","url":"https://fema.caseyjhand.com/mcp"}}}VS Code で開く{"mcpServers":{"cyanheads-fema":{"type":"http","url":"https://fema.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-fema":{"serverUrl":"https://fema.caseyjhand.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
8| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| limit | integer | いいえ | 返す重複のない災害宣言の最大数(1~1000、デフォルトは 50)。1 ページあたりの宣言文字数は 100,000 文字までです(約 290 件、郡を含む場合は約 190 件)。いずれかの上限に達して一致する宣言が残る場合、続きの取得に使うオフセットが next_offset に示されます。 |
| state | string | いいえ | 米国の州・準州を表す2文字コード(例:TX、CA、FL、PR)。州で絞り込みます。 |
| county | string | いいえ | 指定地域/郡名で絞り込みます(例:Harris、Los Angeles、dekalb)。大文字と小文字を区別しない部分文字列一致です。harris は Harrison にも一致します。一致する地域が指定された宣言を選択します。designated_area_count とプログラムフラグは引き続き宣言全体を示し、matched_areas には一致した地域が一覧表示されます。 |
| offset | integer | いいえ | 宣言のページネーションオフセット(デフォルトは 0)。続行するには、前のページの next_offset を渡します。 |
| date_to | any | いいえ | 宣言日の範囲の終了日を、YYYY-MM-DD 形式の暦日で指定します(例:2024-12-31)。指定日を含みます。1日だけを指定する場合は date_from と同じ日付にします。 |
| date_from | any | いいえ | 宣言日の範囲の開始日を、YYYY-MM-DD 形式の暦日で指定します(例:2024-01-01)。指定日を含みます。date_to より後の日付は指定できません。 |
| incident_type | string | いいえ | インシデント種別のフィルター(例:Flood、Hurricane、Tornado、Fire、Earthquake、Severe Storm)。大文字と小文字を区別しない部分文字列一致です。storm は Snowstorm と Winter Storm にも一致します。 |
| declaration_type | enum | いいえ | 宣言の種類:DR(大規模災害宣言)、EM(緊急事態宣言)、FM(火災管理支援宣言)。DR | EM | FM |
詳細
@cyanheads/fema-mcp-server
MCP 経由で、FEMA の災害宣言、公共支援助成金、住宅支援、NFIP 洪水保険請求を検索できます。STDIO または Streamable HTTP に対応しています。
公開ホスト型サーバー: https://fema.caseyjhand.com/mcp
概要
FEMA の連邦災害復旧データを利用できます。災害宣言、公共支援助成金、個人向け住宅支援、NFIP 洪水保険請求が対象です。州または災害で宣言を検索し、各災害に関連する公共支援と住宅支援を確認できます。また、大量の洪水保険請求結果に対して SQL を実行できます。
ツール
| ツール | 説明 |
|---|---|
fema_search_disasters | 州、インシデントの種類、宣言の種類、期間、郡で連邦災害宣言を検索します |
fema_get_disaster | 特定の災害について、部分的な対象範囲であることを明示したうえで、最大1,000件の指定地域レコードを取得します |
fema_get_public_assistance | 災害または州の公共支援対象プロジェクトを取得します。連邦復興資金の使途を確認できます |
fema_get_housing_assistance | 災害に関する個人向け住宅支援データを取得します。郡またはZIPで絞り込み可能で、郡/ZIP別の持ち家世帯と賃貸世帯の内訳、および検査件数を確認できます |
fema_search_nfip | 州、郡、またはZIPのNFIP洪水保険請求を検索します。SQL分析向けのDataCanvasへの追加送信は任意です |
fema_dataframe_describe | fema_search_nfipによってDataCanvasにステージングされたテーブルの列と行数を一覧表示します |
fema_dataframe_query | fema_search_nfipによってステージングされたDataCanvasテーブルに対してSELECTクエリを実行します |
fema_dataframe_drop | ステージングされたDataCanvasテーブルまたはビューを削除します。オプトインが必要で、既定ではtools/listに表示されません |
fema_query_dataset | OpenFEMAカタログ内の任意のデータセットに対する汎用ODataクエリです。便利ツールでは対応していないデータセット用の代替手段です |
fema_dataframe_dropはオプトイン方式です。FEMA_ENABLE_CANVAS_DROP=trueの場合にのみtools/listに表示されます。ほかの8つのツールは常に表示されます。
リソース
| リソース | 説明 |
|---|---|
fema://disaster/{disasterNumber} | 特定のFEMA災害宣言の概要。タイトル、州、インシデントの種類、プログラム、インシデント期間を含みます |
すべてのリソースデータはツール経由でも取得できます。指定地域の詳細(最大1,000行)にはfema_get_disasterを使用してください。
機能リファレンス
fema_search_disasters ツール
- フィルター:
state、incident_type、declaration_type(DR/EM/FM)、期間を含むdate_from/date_to(YYYY-MM-DD)、county。incident_typeとcountyは、大文字と小文字を区別しない部分一致で検索されます。limit(1~1000、既定値50)とoffsetでページ分割します。ページの上限は100,000文字で、再開位置はnext_offsetに示されます。 - 災害番号ごとに、
designated_area_count、プログラムのフラグ、宣言の合計を含む概要を1件返します。countyを指定すると、一致する地域をtotal_area_rowsとmatched_areas(FIPSコードと地域ごとのフラグ)で示します。エラー:invalid_state、invalid_range(date_fromがdate_toより後の場合)、request_too_long。 - 最新の指定地域レコード10,000件を検索します。上限に達した場合、結果は
truncatedと表示され、合計は下限値となり、次に指定するdate_toがnoticeに示されます。
fema_get_disaster ツール
fema_search_disastersから取得したdisaster_numberが必要です。- 指定地域レコードを最大1,000件、FIPSコード、インシデント期間、および取得した地域全体のプログラムフラグをまとめて返します。災害が見つからない場合は
not_foundを返します。さらにレコードがある場合は、areas_truncated、total_designated_area_count、noticeで部分的な対象範囲であることを示します。取得されていない行のプログラムが、フラグがfalseであることによって除外されるわけではありません。宣言全体を取得するにはfema_query_datasetを使用してください。
fema_get_public_assistance ツール
disaster_numberまたはstateが必要です。county(大文字と小文字を区別しない部分一致)、limit(1~10000、既定値100)、offsetは任意です。ページの上限は100,000文字で、再開位置はnext_offsetに示されます。- 申請者、被害カテゴリ、プロジェクトの規模/ステータス、連邦および総額の債務負担額を返します。エラー:
invalid_state、missing_filter、not_found、request_too_long。
fema_get_housing_assistance ツール
disaster_numberは必須です。state、county(大文字と小文字を区別しない部分一致)、zip_code(5桁)、type(owners/renters/both、デフォルトはboth)、limit(1~10000、デフォルトは 100)、offsetは任意です。ページは 100,000 文字で終了します。next_offsetを使うと、所有者と賃借人の両方の続きを取得できます。ownersとrentersの個別の配列で、郡/ZIP コードごとの登録件数、承認額、検査件数を返し、owners_count/renters_countも返します。所有者には検査済みの損害額(USD)も含まれます。賃借人には損害度別の件数のみが含まれます。エラー:invalid_state、not_found、request_too_long。
fema_search_nfip ツール
stateは必須です。county_code(48201のような5桁の FIPS コード、または州コードが自動的に付加される201のような3桁のコード)、zip_code、year_from/year_to、limit(1~10000、デフォルトは 1000)、offsetは任意です。結果は損失発生日の新しい順に表示されます。- インラインの請求データは 100,000 文字で終了します。続行方法は
next_offsetとnoticeに記載されます。エラー:invalid_state、invalid_county_code(1~5桁以外の値、または FM、MH、PW に対する短縮コード)、invalid_range(year_fromがyear_toより後の場合)。 - 郡を検索すると、同じ州/年の範囲で郡コードのない請求がないか確認します。この確認では、再試行なし、2秒の期限で、件数のみを取得するリクエストを1回行います。主ページの準備ができている場合に限り、レスポンスには件数が使用されます。それ以外の場合、対象データの確認は行われなかったことが示されます。これらの請求を選択した郡や ZIP コードに割り当てることはできません。
county_codeを削除し、既知の ZIP コードを任意で検索すると役立つ場合があります。ZIP コードの結果は、郡の結果と同等または完全であるとは限りません。 CANVAS_PROVIDER_TYPE=duckdbの場合、最初のページの一致件数がインライン上限を超えると、最大 50,000 行がステージングされます。canvas_id、canvas_table、staged_countでステージを識別し、上限に達したことはtruncated: trueで示されます。total_countは一致した全件数です。fema_dataframe_describeでステージを確認し、fema_dataframe_queryでクエリを実行してください。
fema_dataframe_describe ツール
fema_search_nfipから取得したcanvas_idが必須です。- テーブル/ビュー名、列の型、NULL 許容性、ステージングされた行数を一覧表示します。型付きエラー:
canvas_not_found、canvas_unavailable。
fema_dataframe_query ツール
canvas_idと単一の SQLqueryが必須です。SELECT のみ許可されます。- 行数はキャンバスの行数上限と 100,000 文字に制限されます。結果が途中で切り捨てられた場合は、
truncated/shownと OFFSET の指定方法が表示されます。エラー:canvas_unavailable、canvas_not_found、missing_table、invalid_sql、non_select_statement、multi_statement、denied_function、plan_operator_not_allowed、sql_read_only、sql_execution_error(互換性のない値にはTRY_CASTを使うか、フィルターで除外してください)。
fema_dataframe_drop ツール
canvas_idと、fema_dataframe_describeから取得した正確なtable_nameが必須です。- ステージングされたテーブルまたはビューを1つ削除します。
dropped: falseは、その名前が存在しなかったことを意味します。エラー:canvas_not_found、canvas_unavailable。 FEMA_ENABLE_CANVAS_DROP=trueを設定して有効にします。
fema_query_dataset ツール
- 大文字と小文字を区別する OpenFEMA の
datasetが必須です。OData のfilter/select/orderby、limit(1~10000、デフォルトは 100)、offsetは任意です。ページは 100,000 文字で終了します。再開位置はnext_offsetに示されます。 - レコードと
total_countを返します。エラー:unknown_dataset、dataset_not_served、catalog_unavailable(再試行可能)、invalid_filter、invalid_select、invalid_orderby、invalid_odata_syntax、request_too_long(URL が約 8,900 文字を超過)、filter_too_complex(入れ子が100階層を超過)。 - 値のリストには、連鎖した
or比較の代わりにfield in ('a','b')を使ってください(約90個まで使用できます)。NfipPoliciesではpropertyStateとreportedZipCodeを使い、タイムアウトを避けるため、必ず ZIP フィルターを含めてください。
fema://disaster/{disasterNumber} リソース
disasterNumberには数字の文字列を指定する必要があります。- タイトル、州、インシデントの種類、宣言の種類と日付、インシデント期間、
programs_declared、取得したdesignated_area_count(最大500件)を返します。さらに行がある場合、概要にはareas_truncated、total_designated_area_count、noticeが含まれます。プログラム情報は取得した行のみを対象とし、空のリストが不在を示すとは限りません。すべての行を取得するにはfema_query_datasetを使用してください。not_foundはfema_search_disastersを案内します。
特長
@cyanheads/mcp-ts-core を基盤とし、stdio と Streamable HTTP のトランスポート、切り替え可能な認証(none / jwt / oauth)、切り替え可能なストレージ(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1)、オプションの OpenTelemetry トレース機能を備えた構造化ログに対応しています。
OpenFEMA 固有の機能:
- 郡とインシデントの種類を大文字と小文字を区別せずにフィルタリングします。宣言名の同梱データと、PA の郡名の完全一致表記を使用します。
bun run vocabulary:buildで更新できます。連続して実行する全件エクスポートでは、宣言を ID 順に読み込み、null でない PA の郡をソートせずに読み込みます。一時的なエラーには回数を制限して再試行します。各エクスポートは報告された件数と一致する必要があり、更新に失敗するか不完全な場合、スナップショットは変更されません。 DisasterDeclarationsSummariesの行は、宣言ごとに1つの概要にまとめられ、designated_area_countが含まれます。fema_search_nfipではstateの指定が必須です。これにより、270万件の行を無制限に取得することを防ぎます。- 大規模な NFIP 結果セットは DuckDB テーブルに格納され、DataCanvas を介して SQL でクエリできます。
- API キーは不要です。OpenFEMA は無料の公開 API です。
エージェントに適した出力:
- 災害番号はツール間で結合キーとして使われるため、再検索せずに呼び出しを連鎖できます。
- 検索結果が空の場合、どちらの応答形式でも、空の配列、合計数 0、指定されたフィルターに応じた案内を含む
noticeを返します。支援に関する呼び出しでは、fema_get_disasterを使って宣言済みのプログラムを確認できます。ゼロ以外の合計数を超えてページングする場合は、別途オフセットに関する案内が表示されます。 - すべてのツールで、型付きエラー(
invalid_state、invalid_county_code、invalid_range、not_found、missing_filter、unknown_dataset、dataset_not_served、invalid_filter、invalid_select、invalid_orderby、invalid_odata_syntax、request_too_long、filter_too_complex、canvas_unavailable)と、それぞれの復旧方法のヒントを返します。 - 検索結果の
designated_area_countから、fema_get_disasterでの追加取得が有用かどうかを確認できます。
はじめに
公開ホストインスタンス
公開インスタンス(https://fema.caseyjhand.com/mcp)を利用できます。インストールは不要です。Streamable HTTP を介して、任意の MCP クライアントを接続してください。
{
"mcpServers": {
"fema-mcp-server": {
"type": "streamable-http",
"url": "https://fema.caseyjhand.com/mcp"
}
}
}
セルフホスト/ローカル
MCP クライアントの設定ファイルに次の内容を追加してください。
{
"mcpServers": {
"fema-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/fema-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
または、npx を使用する場合(Bun は不要です):
{
"mcpServers": {
"fema-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/fema-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
または、Docker を使用する場合:
{
"mcpServers": {
"fema-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/fema-mcp-server:latest"
]
}
}
}
Streamable HTTP を使用するには、トランスポートを設定してサーバーを起動してください。
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
NFIP Claims の DuckDB を利用した SQL 分析を有効にするには:
{
"mcpServers": {
"fema-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/fema-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"CANVAS_PROVIDER_TYPE": "duckdb"
}
}
}
}
前提条件
- Bun v1.4.0 以降(または Node.js v24 以降)。
- API キーは不要です。OpenFEMA は無料の公開 API です。
- オプション:
CANVAS_PROVIDER_TYPE=duckdbを設定すると、大規模な NFIP Claims の結果セットに対する SQL 分析が有効になります。
インストール
- リポジトリをクローンします:
git clone https://github.com/cyanheads/fema-mcp-server.git
- ディレクトリに移動します:
cd fema-mcp-server
- 依存関係をインストールします:
bun install
- 環境を設定します:
cp .env.example .env
# edit .env — no required vars, but CANVAS_PROVIDER_TYPE=duckdb enables SQL analytics
設定
すべての設定は、src/config/server-config.ts の Zod スキーマを使って起動時に検証されます。主な環境変数は次のとおりです。
| 変数 | 説明 | デフォルト |
|---|---|---|
FEMA_BASE_URL | OpenFEMA API のルート URL です。 | https://www.fema.gov/api/open |
FEMA_REQUEST_TIMEOUT_MS | リトライを含む、1 回の上流リクエストに割り当てる合計時間(ミリ秒)です。 | 30000 |
CANVAS_PROVIDER_TYPE | NFIP の保険金請求に対する DataCanvas SQL 分析を有効にするには、duckdb を設定します。 | — |
FEMA_ENABLE_CANVAS_DROP | fema_dataframe_drop ツールを有効にします。 | false |
MCP_TRANSPORT_TYPE | トランスポート:stdio または http です。 | stdio |
MCP_SESSION_MODE | セッションモード:auto、stateful、または stateless です。 | stateless |
MCP_HTTP_PORT | HTTP サーバーのポートです。 | 3010 |
MCP_AUTH_MODE | 認証モード:none、jwt、または oauth です。 | none |
MCP_LOG_LEVEL | ログレベル(debug、info、warning、error など)です。 | info |
LOG_TOOL_FAILURE_PAYLOADS | 失敗した呼び出しの引数と結果を、キー名に基づいて機密情報を除去して記録します。自由形式の値に含まれる機密情報は保持されます。 | false |
LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES | 記録するペイロードごとのバイト数上限です。 | 16384 |
OTEL_EXPORTER_OTLP_ENDPOINT | トレースとメトリクスの OTLP ベース URL です。 | — |
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT | トレースのエンドポイントです。そのまま使用されます。 | — |
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT | メトリクスのエンドポイントです。そのまま使用されます。 | — |
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT | ログのエクスポート先です。設定されている場合にのみログがエクスポートされます。 | — |
LOGS_DIR | ログファイルの保存先ディレクトリです(Node.js のみ)。 | <project-root>/logs |
OTEL_ENABLED | OpenTelemetry instrumentation を有効にします。 | false |
任意のオーバーライドの全一覧は、.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 test suite bun run lint:mcp # Validate MCP definitions against spec
Docker
docker build -t fema-mcp-server .
docker run --rm -e MCP_TRANSPORT_TYPE=stdio fema-mcp-server
Dockerfile のデフォルトは、HTTP トランスポート、ステートレスセッションモードで、ログは /var/log/fema-mcp-server に記録されます。OpenTelemetry のピア依存関係はデフォルトでインストールされます。これらを省略するには、--build-arg OTEL_ENABLED=false を指定してビルドします。
プロジェクト構成
| ディレクトリ | 目的 |
|---|---|
src/index.ts | createApp() のエントリーポイントです。ツール/リソースを登録し、サービスを初期化します。 |
src/config | サーバー固有の環境変数を解析し、Zod で検証します。 |
src/mcp-server/tools | ツール定義(*.tool.ts)です。ツールごとに 1 ファイルを使用します。 |
src/mcp-server/resources | リソース定義(*.resource.ts)です。 |
src/services/openfema | OpenFEMA REST API クライアントに加え、大文字と小文字を区別しない名前照合機能と、同梱の名前語彙を含みます。 |
src/services/canvas | DataCanvas との連携機能です。大量の NFIP 検索結果を DuckDB に退避します。 |
tests/ | src/ に対応する単体テストと統合テストです。 |
開発ガイド
開発ガイドラインとアーキテクチャのルールについては、CLAUDE.md を参照してください。概要は次のとおりです。
- ハンドラーは例外をスローし、フレームワークが捕捉します。ツールのロジック内で
try/catchを使わないでください。 - リクエスト単位のログには
ctx.logを、テナント単位のストレージにはctx.stateを使用してください。 - 新しいツールとリソースは
src/index.tsに登録してください。 - 外部 API 呼び出しは、未加工データを検証し、ドメイン型に正規化してから、出力スキーマに沿って返してください。欠落しているフィールドを捏造しないでください。
コントリビューション
課題の報告を歓迎します。提出前にチェックとテストを実行してください。
bun run devcheck
bun run test
データソース
データは、Federal Emergency Management Agency が管理する無料の公開 API、OpenFEMA API から提供されています。利用には OpenFEMA Terms and Conditions が適用されます。
この製品は Federal Emergency Management Agency の OpenFEMA API を使用していますが、FEMA による推奨を受けたものではありません。連邦政府または FEMA は、Agency のウェブサイトからデータを取得した後に、そのデータから導き出されたデータや分析の正確性を保証できません。
研究や出版物で OpenFEMA のデータセットを引用する際は、FEMA が指定する形式を使用してください。
Federal Emergency Management Agency (FEMA), OpenFEMA Dataset: <name>. Retrieved from <URL> on <date>.
ライセンス
Apache-2.0 — 詳細は LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。