mcpField
F
fema-mcp-server

fema-mcp-server

远程服务
github.com/cyanheads法律与政务11 周前更新
代码仓库

关于 fema-mcp-server

fema-mcp-server 面向灾害研究者和公共部门分析人员,提供 FEMA 灾害声明、公共援助、住房援助和 NFIP 理赔数据查询。它还支持 OpenFEMA 数据集查询,并可对暂存的理赔结果运行 SQL。

主要功能

  1. 01按州、类型和日期搜索灾害声明
  2. 02查看灾害指定区域与项目标记
  3. 03查询公共援助项目及拨款
  4. 04查询住房援助与 NFIP 理赔
  5. 05对暂存理赔数据运行只读 SQL

适用场景

  1. 01查找某州或某类灾害声明
  2. 02梳理灾害的公共援助资金去向
  3. 03查看县或邮编层级的住房援助
  4. 04分析指定地区的洪水保险理赔

MCP 相关

作为 MCP 服务,它通过 STDIO 或 Streamable HTTP 提供灾害、援助和理赔查询工具,以及灾害摘要资源;大型 NFIP 结果可暂存并用 SQL 查询。OpenFEMA API 无需密钥。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://fema.caseyjhand.com/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

安装包
npm@cyanheads/fema-mcp-server0.4.1

工具

8
参数类型必填说明
limitinteger否要返回的唯一灾害声明的最大数量(1–1000,默认值为 50)。每页还受 100,000 个声明字符的限制(约 290 条声明;包含县时约 190 条);任一上限导致仍有匹配声明未返回时,next_offset 会提供继续查询的偏移量。
statestring否美国州/领地的两字母代码(例如 TX、CA、FL、PR)。按州筛选。
countystring否按指定区域/县名称筛选(例如 Harris、Los Angeles、dekalb)。不区分大小写的子字符串匹配:harris 也会匹配 Harrison。选择指定区域匹配的声明;designated_area_count 和程序标志仍描述整个声明,matched_areas 列出匹配的区域。
offsetinteger否声明中的分页偏移量(默认值为 0)。传入上一页的 next_offset 以继续。
date_toany否声明日期范围的结束日期,格式为 YYYY-MM-DD 的日历日期(例如 2024-12-31)。包含该日期;查询单日时,将其设为与 date_from 相同。
date_fromany否声明日期范围的开始日期,格式为 YYYY-MM-DD 的日历日期(例如 2024-01-01)。包含该日期;不得晚于 date_to。
incident_typestring否事件类型筛选条件(例如 Flood、Hurricane、Tornado、Fire、Earthquake、Severe Storm)。不区分大小写的子字符串匹配:storm 也会匹配 Snowstorm 和 Winter Storm。
declaration_typeenum否声明类型:DR(重大灾害声明)、EM(紧急情况声明)、FM(火灾管理援助声明)。DR | EM | FM

详细介绍

@cyanheads/fema-mcp-server

通过 MCP 查询 FEMA 灾害声明、公共援助拨款、住房援助和 NFIP 洪水保险理赔。支持 STDIO 或 Streamable HTTP。

8 个工具 • 1 个选择启用的工具 • 1 个资源

版本 许可证 Docker MCP SDK npm TypeScript Bun

在 Claude Desktop 中安装 在 Cursor 中安装 在 VS Code 中安装

框架

公共托管服务: 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 洪水保险理赔数据,可选启用 DataCanvas 溢出,以进行 SQL 分析
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 中。其他八种工具始终会列出。

资源
资源描述
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、计划标记和声明总额。指定 county 时,total_area_rows 和 matched_areas(FIPS 代码及各区域标记)会显示匹配的区域。错误:invalid_state、invalid_range(date_from 晚于 date_to)、request_too_long。
  • 搜索最近的 10,000 条指定区域记录。达到上限时,结果会标记为 truncated,总数为下限,notice 会指出下一个 date_to。

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 数组,其中包含按县/邮政编码统计的登记数、批准金额和检查次数,以及 owners_count/renters_count。业主数据还包含以美元计的已检查损失;租户数据仅包含损失程度计数。错误:invalid_state、not_found、request_too_long。

fema_search_nfip 工具
  • 必需参数:state;可选参数:county_code(5 位 FIPS 代码,如 48201;或会自动添加州前缀的 3 位代码,如 201)、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)。
  • 按县搜索时,会在同一州和年份范围内检查没有县代码的理赔数据,使用一次仅计数的请求,不重试,截止时间为两秒。只有当主页面的数据已就绪时,响应才会使用该计数;否则会说明未检查覆盖情况。这些理赔数据无法分配到所选县或邮政编码。移除 county_code 并视情况搜索已知邮政编码可能会有所帮助;邮政编码搜索结果不保证完整,也不一定等同于县级结果。
  • 当 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。
  • 列出表/视图名称、列类型、是否可为空以及暂存行数。类型化错误:canvas_not_found、canvas_unavailable。

fema_dataframe_query 工具
  • 需要 canvas_id 和单条 SQL query;仅允许 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。
  • 移除一个暂存表或视图;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 层)。
  • 对于值列表,使用 field in ('a','b'),而不是链式 or 比较(约允许 90 个值)。对于 NfipPolicies,使用 propertyState 和 reportedZipCode,并始终包含邮政编码筛选条件,以避免超时。

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 顺序读取声明,并在不排序的情况下读取非空 PA 县数据,同时进行有界的瞬时错误重试。每次导出都必须与其报告的数量一致;刷新失败或不完整时,快照保持不变。
  • DisasterDeclarationsSummaries 行会合并为每项声明一条摘要,并包含 designated_area_count
  • fema_search_nfip 要求提供 state,以避免获取无界的 270 万行数据
  • 大型 NFIP 结果集会溢出到 DuckDB 表中,你可以通过 DataCanvas 使用 SQL 查询这些表
  • 无需 API 密钥 — OpenFEMA 是免费的公共 API

便于 Agent 使用的输出:

  • 灾害编号是各工具之间的关联键,因此调用可以串联进行,无需重复搜索
  • 空搜索会在两个响应界面中返回空数组、零总数和包含筛选条件提示的 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 分析。
安装
  1. 克隆仓库:
git clone https://github.com/cyanheads/fema-mcp-server.git
  1. 进入目录:
cd fema-mcp-server
  1. 安装依赖项:
bun install
  1. 配置环境:
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_URLOpenFEMA API 根地址。https://www.fema.gov/api/open
FEMA_REQUEST_TIMEOUT_MS单次上游请求(包括重试)的总时间预算,单位为毫秒。30000
CANVAS_PROVIDER_TYPE设置为 duckdb 以启用针对 NFIP 理赔的 DataCanvas SQL 分析。—
FEMA_ENABLE_CANVAS_DROP启用 fema_dataframe_drop 工具。false
MCP_TRANSPORT_TYPE传输方式:stdio 或 http。stdio
MCP_SESSION_MODE会话模式:auto、stateful 或 stateless。stateless
MCP_HTTP_PORTHTTP 服务端口。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 检测。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.tscreateApp() 入口点——注册工具和资源,并初始化服务。
src/config解析并验证服务专用环境变量,使用 Zod 进行验证。
src/mcp-server/tools工具定义(*.tool.ts)——每个工具对应一个文件。
src/mcp-server/resources资源定义(*.resource.ts)。
src/services/openfemaOpenFEMA REST API 客户端,以及不区分大小写的名称匹配器及其内置名称词汇表。
src/services/canvasDataCanvas 集成——使用 DuckDB 处理较大的 NFIP 结果集。
tests/与 src/ 结构对应的单元测试和集成测试。

开发指南

开发指南和架构规则请参见 CLAUDE.md。简要说明:

  • 处理器抛出异常,框架负责捕获——工具逻辑中不要使用 try/catch
  • 使用 ctx.log 记录请求级日志,使用 ctx.state 存储租户级数据
  • 在 src/index.ts 中注册新工具和资源
  • 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出模式;绝不伪造缺失字段

贡献

欢迎提交问题。提交前请运行检查和测试:

bun run devcheck
bun run test

数据源

数据由 OpenFEMA API 提供。这是由联邦紧急事务管理局维护的免费公共 API。使用须遵守 OpenFEMA 条款和条件。

本产品使用联邦紧急事务管理局的 OpenFEMA API,但并未获得 FEMA 背书。数据从该机构的网站检索后,联邦政府或 FEMA 无法保证这些数据或基于这些数据得出的分析的可靠性。

在研究或出版物中引用 OpenFEMA 数据集时,请使用 FEMA 指定的格式:

Federal Emergency Management Agency (FEMA), OpenFEMA Dataset: <name>. Retrieved from <URL> on <date>.

许可证

Apache-2.0 — 详情请参阅 LICENSE。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。