关于 usgs-water-mcp-server
usgs-water-mcp-server 为水文研究者和资源管理人员提供美国及属地 USGS 监测站的实时与历史水数据。它可按地理范围查找站点、检索读数与时间序列,并将较大结果暂存以供 SQL 查询。
主要功能
- 01按地理范围查找监测站
- 02获取站点最新水文读数
- 03查询每日或瞬时历史序列
- 04查看水文条件的历史百分位
- 05暂存数据并执行只读 SQL
适用场景
- 01查找指定州、县或流域的监测站
- 02查看河流流量或地下水位变化
- 03将当前读数与历史记录百分位比较
MCP 相关
作为 MCP 服务,它通过工具和资源向客户端提供 USGS 站点、参数及水文数据查询。支持 STDIO 和 Streamable HTTP;大型结果可暂存于 DuckDB 数据画布并通过只读 SQL 查询。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://usgs-water.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-usgs-water https://usgs-water.caseyjhand.com/mcp{"mcpServers":{"cyanheads-usgs-water":{"type":"http","url":"https://usgs-water.caseyjhand.com/mcp"}}}在 Cursor 中打开{"servers":{"cyanheads-usgs-water":{"type":"http","url":"https://usgs-water.caseyjhand.com/mcp"}}}在 VS Code 中打开{"mcpServers":{"cyanheads-usgs-water":{"type":"http","url":"https://usgs-water.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-usgs-water":{"serverUrl":"https://usgs-water.caseyjhand.com/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
7| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| group | enum | 否 | 按主题领域筛选精选列表:"streamflow"、"groundwater"、"temperature"、"meteorological"、"water-quality" 或 "all"(默认值)。仅适用于精选列表——传入 query 时请保留为 "all"。streamflow | groundwater | temperature | meteorological | water-quality | all |
| query | string | 否 | 搜索完整的 USGS 参数代码目录。不区分大小写;每个词都必须是参数名称或描述中某个词的开头(例如 "turbidity"、"nitrate filtered"、"dissolved oxygen")。仅输入 5 位代码(例如 "63680")时,返回该代码。省略则列出精选代码。 |
详细介绍
@cyanheads/usgs-water-mcp-server
通过 MCP 查询美国约 8,000 个河流水文站和地下水井的实时及历史水数据。支持 STDIO 或 Streamable HTTP。
概览
提供美国及其属地约 8,000 个活跃的 USGS 河流水文站和地下水井的实时及历史水数据。查找监测站点,获取最新读数或历史数据序列,并了解今天的流量与数十年的记录相比如何。
工具
| 工具 | 描述 |
|---|---|
water_list_parameters | 列出常见的 USGS 参数代码及其名称、单位和领域(不发起网络请求),或按名称或描述搜索完整的约 19,600 个代码的 USGS 目录。 |
water_find_sites | 按边界框、州、县或 HUC 流域查找 USGS 监测站点。可按站点类型和参数可用性筛选。匹配结果集较大时会写入 DataCanvas。 |
water_get_readings | 获取最多 100 个 USGS 站点的最新瞬时值(约每 15 分钟更新一次)。 |
water_get_series | 获取站点在指定日期范围内的每日值或瞬时值时间序列。较大的结果范围会写入 DataCanvas。 |
water_get_site_data_catalog | 发现站点的参数、传感器、统计数据和完整 UTC 记录范围,并支持游标分页。 |
water_get_conditions | 获取当前水文状况,并根据完整记录期间的百分位统计进行排序。 |
water_dataframe_describe | 列出由 water_get_series 或 water_find_sites 暂存到 DataCanvas 的表和列。 |
water_dataframe_query | 对由 water_get_series 和 water_find_sites 暂存的时间序列表和站点表运行只读 SQL SELECT 查询。 |
water_dataframe_drop | 从 DataCanvas 中删除一个暂存表,同时保留画布及其其他表。需通过 WATER_DATAFRAME_DROP_ENABLED 启用。 |
资源
| 资源 | 描述 |
|---|---|
usgs-water://site/{siteId} | 站点元数据:名称、坐标、类型、HUC、州、县、集水面积和海拔 |
usgs-water://parameters | 精选的常见参数代码(water_list_parameters 无需查询即可返回的列表) |
所有资源数据也可通过工具访问。使用 water_find_sites 查找地理区域内的站点。
功能参考
water_list_parameters 工具
- 不带
query:返回精选的内置代码列表(不发起网络请求),例如00060(流量,ft³/s)、00065(水位,ft)和72019(地下水位埋深,ft);可按group筛选(streamflow、groundwater、temperature、meteorological、water-quality或默认值all) - 带
query:按名称或描述搜索完整的约 19,600 个代码的 USGS 目录(仅输入 5 位代码也会返回对应代码),最多返回 25 条结果;每条结果都会注明其source(curated或usgs-catalog),并通过total和truncated描述完整匹配集。query不能与值不是all的group组合使用 - 首次查询时会获取目录,并缓存 24 小时;如果获取失败,会返回可重试的
upstream_error
water_find_sites 工具
- 每次调用只能指定一个地理范围——
bbox("west,south,east,north")、2 个字母的stateCd、最多 20 个以逗号分隔的 5 位 FIPScountyCd代码,或 2 位或 8 位的huc——并可按siteType(ST、GW、LK、SP、……)、parameterCd和hasDataTypeCd(iv/dv/gw)进一步缩小范围。缺少范围或指定多个范围时,会在调用 NWIS 前分别以missing_major_filter/conflicting_major_filters报错 limit(1–500,默认值为 500)和offset用于翻阅匹配结果;truncated和upstreamTotal描述窗口之外的结果;siteOutput: expanded会添加集水面积和贡献面积- 当
CANVAS_PROVIDER_TYPE=duckdb时,超过 500 个站点的匹配结果集也会完整暂存到画布(canvas_id/table_name),供water_dataframe_query使用
water_get_readings 工具
- 每次调用最多支持 100 个
sites,可选parameterCd筛选条件,以及回溯时长period(ISO 8601,默认PT2H);每个站点、参数和传感器方法(methodId/methodDescription)返回一个序列,每次调用最多返回 100 个序列(在各站点间轮流保留),每个序列最多返回最近的 10 条记录;totalSeries、totalValues和truncated会报告因上限而未返回的内容 - 每个值都包含其限定码(
P表示暂定,A表示已批准);对于 NWIS 未返回任何数据的站点,missingSites会列出其名称
water_get_series 工具
- 每次调用指定一个
site和一个parameterCd,并指定startDate–endDate日期范围;seriesType可设为daily(每天一个值,默认值)或instantaneous(约每 15 分钟一个值)。最近的 500 条记录会直接返回;totalRecords和truncated会报告其余记录 - 返回一个命名序列——默认是日均值,以及记录数最多的传感器方法;
statCd(00003表示平均值,00001表示最大值,00002表示最小值;仅适用于每日数据)和methodId可用于选择其他序列,otherSeries会列出所有备选序列及其记录数 - 设置
CANVAS_PROVIDER_TYPE=duckdb时,超过 500 条记录的日期范围会将完整序列存入画布(canvas_id/table_name);传入先前的canvas_id可将表添加到已有画布
water_get_site_data_catalog 工具
- 指定一个
site,以及可选的parameterCd和seriesType,并设置limit(1–1000;默认值为 100)。使用相同的筛选条件和 limit,并传入nextCursor继续获取,直到其值为 null。未知站点会返回not_found错误;已知站点没有匹配的元数据时会返回series: [] - 每行都会保留其 OGC
timeSeriesId、参数名称/单位、可为空的统计值、传感器描述、原始计算字段,以及完整的 UTCbeginDate/endDate。Daily映射为daily;Instantaneous类型的Points映射为instantaneous;其他计算类型的seriesType为 null - 对于
water_get_series,从边界日期中提取 YYYY-MM-DD;仅对每日数据行传入statCd,并从序列响应中选择methodId,切勿使用 OGC ID。边界可能存在间隔,也可能滞后于观测时间;未知边界仍为未知 - 站点身份信息和元数据共用 45 秒的截止时间(包括重试)。格式错误或被拒绝的续传游标会返回
invalid_cursor错误;不带游标重新开始
water_get_conditions 工具
- 指定一个
site和一个parameterCd;将当前瞬时读数与该站点记录期内对应日历日的日均百分位数进行比较,并将结果划分为percentileClass:record-high(≥p95)、above-normal、normal、below-normal、low、record-low(<p05);若读数无数据,则为unknown。percentileLabel会用通俗语言说明阈值,comparisonBasis会注明该排名为近似值,并非洪水等级或干旱判定 - 无法应用百分位数时,仍会返回读数,并将
historicalContext设为 null;historicalContextStatus的值为no_record、no_matching_day、no_matching_method或unavailable(统计服务暂时性故障)。对于多传感器站点,methodId和methodMatched会标明读取所用的传感器,以及百分位数是否来自该传感器自身的序列
water_dataframe_describe 工具
- 列出由
water_get_series或water_find_sites暂存于画布上的表格,并显示每列的名称、DuckDB 类型及是否可为空——在调用water_dataframe_query或water_dataframe_drop前使用此工具,确认准确名称 row_count是 DuckDB 的估算值,可能与精确计数不同
water_dataframe_query 工具
- 对暂存表执行单条只读
SELECT;其他语句、系统目录访问(information_schema、pg_catalog、duckdb_*)、引擎设置函数、动态 SQL 和文件引用都会被拒绝。query()接受单个 SQL 字符串字面量,并按相同限制进行检查 - 每次查询最多返回 10,000 行;
truncated: true表示还有更多匹配结果 — 可使用WHERE/LIMIT缩小范围,或运行SELECT COUNT(*)获取准确总数
water_dataframe_drop 工具
- 根据
table_name(不区分大小写匹配)从canvas_id指定的画布中移除一个暂存表;画布及其其他表会保留,响应会报告被删除表的row_count和remaining_tables - 如果画布上没有暂存该名称,则会报错
table_not_found,且不会进行任何更改,因此重复删除是安全的 - 需主动启用:仅当
WATER_DATAFRAME_DROP_ENABLED=true时才可调用;否则,它会作为禁用工具显示在落地页上,并且不会出现在tools/list中。与其他 dataframe 工具一样,它需要CANVAS_PROVIDER_TYPE=duckdb
usgs-water://site/{siteId} 资源
- 返回
application/json格式的站点元数据:名称、坐标、类型、HUC 流域代码、州、县、排水面积和海拔 siteId是 8–15 位数字的 USGS 站点编号 — 可通过water_find_sites查找
usgs-water://parameters 资源
- 以
application/json格式提供精选的常用参数代码表 — 即water_list_parameters无需查询即可返回的列表 - 不接受参数;这是 USGS 目录中的精选子集 — 使用
water_list_parameters的query搜索其他代码
功能
基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔认证(none / jwt / oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志记录。
USGS Water 专属功能:
- 封装 NWIS IV(瞬时)、DV(每日)、站点和统计端点,以及 USGS Water Data 参数代码、监测位置和时间序列元数据——无需 API 密钥,完全公开
- 在入口处检查输入格式,确保符合 NWIS 实际接受的格式——站点编号、参数代码、ISO 8601 时段、HUC、FIPS 县、州和 bbox 均采用经过验证的模式,并在工具的 JSON Schema 中声明
- HTML 错误检测:对于错误输入,NWIS 会返回带有 HTML 正文的 400 响应;服务层会提取 NWIS 自身的错误消息,并将其映射为类型化故障
- DataCanvas 溢出处理:
water_get_series(较长日期范围)和water_find_sites(超过 500 个站点上限的匹配集)会将完整结果暂存为由 DuckDB 支持的表,可通过water_dataframe_query查询;溢出处理和 dataframe 工具需要CANVAS_PROVIDER_TYPE=duckdb,而water_dataframe_drop还需要WATER_DATAFRAME_DROP_ENABLED=true - 无数据读数仍保持无数据:对于 NWIS 报告为
-999999的值(季节性、已停用、干涸或故障的测量站),会返回空的value,并通过限定符说明原因(Ssn、Dis、Dry、Eqp)——绝不会将其作为数值返回;暂存到画布时会记为NULL - 地下水深度通过标准 IV 服务和参数
72019读取——旧版gwlevels端点已于 2025 年 11 月停用
便于 Agent 使用的输出:
- 百分位分类:
water_get_conditions会返回调用方可直接使用的percentileClass,并附带用通俗语言说明阈值的percentileLabel - 部分成功优于彻底失败:
water_get_readings会返回已获取的序列,并在missingSites中列出其余站点;water_get_conditions会区分空统计表(no_record/no_matching_day)和失败的统计调用(暂时不可用,unavailable),而不会将两者合并为一个错误 - 截断信号:每个受上限限制的响应(
water_get_series、water_find_sites、water_get_readings)都会报告自身的计数和truncated标志;如果其余数据可通过 SQL 获取,还会提供canvas_id/table_name - 结构化内容与渲染文本保持一致——工具应用的每个上限和计数都会以相同方式出现在
structuredContent和 Markdown 中
开始使用
公共托管实例
公共实例可通过 https://usgs-water.caseyjhand.com/mcp 使用——无需安装。通过 Streamable HTTP 将任意 MCP 客户端指向该实例:
{
"mcpServers": {
"usgs-water-mcp-server": {
"type": "streamable-http",
"url": "https://usgs-water.caseyjhand.com/mcp"
}
}
}
自行托管 / 本地运行
将以下内容添加到 MCP 客户端配置文件中。
{
"mcpServers": {
"usgs-water-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/usgs-water-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
也可以使用 npx(无需 Bun):
{
"mcpServers": {
"usgs-water-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/usgs-water-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}
也可以使用 Docker:
{
"mcpServers": {
"usgs-water-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/usgs-water-mcp-server:latest"
]
}
}
}
DataCanvas 默认启用,可针对大型结果集执行 SQL 分析。设置 CANVAS_PROVIDER_TYPE=none 即可仅返回内联预览。便携式 Claude Desktop 捆绑包未包含平台专属的 DuckDB 二进制文件,因此会禁用 DataCanvas。
使用 Streamable HTTP 时,设置传输方式并启动服务:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcp
前置条件
- Bun v1.4.0 或更高版本(或 Node.js v24+)。
- 无需 API 密钥——USGS NWIS 是免费公共 API。
安装
- 克隆仓库:
git clone https://github.com/cyanheads/usgs-water-mcp-server.git
- 进入目录:
cd usgs-water-mcp-server
- 安装依赖:
bun install
- 配置环境:
cp .env.example .env
# Edit .env to set any optional overrides
配置
| 变量 | 描述 | 默认值 |
|---|---|---|
CANVAS_PROVIDER_TYPE | 用于存放 water_get_series 和 water_find_sites 大型结果的 DataCanvas 溢出存储;设为 none 可禁用。便携式桌面套件会设为 none。 | duckdb |
USGS_USER_AGENT | 发送至 USGS NWIS 和 OGC 发现端点的自定义 User-Agent 字符串。根据 USGS 的条款,请求应使用描述性 User-Agent。 | usgs-water-mcp-server/0.4.0 (contact: https://github.com/cyanheads/usgs-water-mcp-server) |
USGS_REQUEST_TIMEOUT_MS | USGS NWIS 和 OGC 调用的 HTTP 请求超时时间(毫秒)。站点序列发现还有一个共享的 45 秒截止时间。 | 30000 |
WATER_DATAFRAME_DROP_ENABLED | 设为 true 后可调用 water_dataframe_drop。关闭时,该工具会列为已禁用。需要将 CANVAS_PROVIDER_TYPE=duckdb,才能删除内容。 | false |
MCP_TRANSPORT_TYPE | 传输方式:stdio 或 http。 | stdio |
MCP_HTTP_PORT | HTTP 服务的端口。 | 3010 |
MCP_SESSION_MODE | HTTP 会话模式。代码中将服务声明为 stateless,与 .env.example 和 Docker 运行时设置一致;设置此变量会覆盖该值,auto 会解析为 stateful。 | stateless |
MCP_AUTH_MODE | 身份验证模式:none、jwt 或 oauth。 | none |
MCP_LOG_LEVEL | 日志级别(RFC 5424)。 | info |
LOGS_DIR | 日志文件目录(仅 Node.js)。 | <project-root>/logs |
LOG_TOOL_FAILURE_PAYLOADS | 记录每次失败工具调用的参数和结果,按键名进行脱敏,并限制为 LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES(默认 16384)字节。自由格式值中的密钥不会被脱敏。 | false |
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 usgs-water-mcp-server .
docker run --rm -p 3010:3010 usgs-water-mcp-server
Dockerfile 默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/usgs-water-mcp-server。默认会安装 OpenTelemetry 对等依赖项;构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖项。
项目结构
| 目录 | 用途 |
|---|---|
src/index.ts | createApp() 入口点 — 注册工具/资源并初始化服务。 |
src/config | 使用 Zod 解析和验证服务专属环境变量。 |
src/mcp-server/tools | 工具定义(*.tool.ts)。 |
src/mcp-server/resources | 资源定义(*.resource.ts)。 |
src/services/nwis | NWIS HTTP 客户端 — 包含 IV、DV、site 和 stat 端点,并检测 HTML 错误。 |
src/services/waterdata | USGS Water Data 站点序列发现、参数代码目录读取器(24 小时缓存)和精选参数表。 |
src/services/canvas | DataCanvas 访问器、调用方提供的 canvas_id 解析,以及由 DuckDB 支持的溢出存储所用的确定性表名。 |
tests/ | 与 src/ 结构对应的单元测试和集成测试。 |
开发指南
开发指南和架构规则请参阅 CLAUDE.md。简要来说:
- 处理程序抛出异常,框架负责捕获 — 工具逻辑中不要使用
try/catch - 使用
ctx.log记录请求范围内的日志,使用ctx.state进行租户范围内的存储 - 通过
src/mcp-server/*/definitions/index.ts中的聚合导出文件注册新工具和资源 - 封装外部 API 调用:验证原始数据 → 规范化为领域类型 → 返回输出架构;绝不伪造缺失字段
贡献
欢迎提交问题。提交前请运行检查和测试:
bun run devcheck
bun run test
许可证
Apache-2.0 — 详情请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。