mcpField
O
openaq-mcp-server

openaq-mcp-server

远程服务
github.com/cyanheads科研与教育25 周前更新
代码仓库

关于 openaq-mcp-server

openaq-mcp-server 通过 OpenAQ v3 提供全球监测站的实测空气质量数据,面向环境研究和空气质量分析。它可查找站点、读取最新传感器值并获取污染物历史序列,同时保留单位和观测时间信息。

主要功能

  1. 01按坐标、区域或国家查找监测站
  2. 02读取站点传感器的最新数值
  3. 03获取污染物历史序列及小时或日汇总
  4. 04查询污染物目录和国家覆盖范围
  5. 05将大型序列暂存并用只读 SQL 查询

适用场景

  1. 01查找某地附近测量特定污染物的站点
  2. 02查看站点最新读数及其单位和时间
  3. 03分析一段时期的污染物历史变化

MCP 相关

该 MCP 服务向客户端提供站点搜索、读数和历史测量等工具,以及站点和污染物目录资源。支持 STDIO 与 Streamable HTTP;调用 OpenAQ v3 需要 API 密钥。

配置

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

服务地址https://openaq.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/openaq-mcp-server0.4.1

工具

详细介绍

@cyanheads/openaq-mcp-server

通过 MCP 查找空气质量监测站、读取最新传感器数值,并获取污染物历史序列。支持 STDIO 或 Streamable HTTP。

8 个工具(默认启用 7 个) • 2 个资源

npm License Docker MCP SDK TypeScript Bun

Install in Claude Desktop Install in Cursor Install in VS Code

Framework

公开托管服务: https://openaq.caseyjhand.com/mcp


概述

通过 OpenAQ v3 API 获取实测空气质量数据:来自全球政府参考监测仪和研究级传感器的物理传感器观测数据。查找监测站、读取当前数值,并通过任意 MCP 客户端获取污染物历史序列。可作为 stdio 进程、本地 Streamable HTTP 服务或上述公开托管端点运行。

工具
工具描述
openaq_find_locations按地点附近、边界框或国家查找监测站;返回其他工具所需的地点 ID
openaq_get_readings获取监测站每个传感器的最新数值,并标注污染物和单位
openaq_get_measurements获取监测站某种污染物的历史序列,支持原始数据或按小时/天汇总
openaq_list_parameters污染物目录及其标准单位;将污染物和单位映射到其参数 ID
openaq_list_countries国家覆盖情况:数据时间跨度及各国测量的参数
openaq_dataframe_describe列出已暂存到 DataCanvas 的表和列
openaq_dataframe_query对已暂存的测量序列运行只读 SQL SELECT
openaq_dataframe_drop删除完整的暂存画布;需通过 OPENAQ_ENABLE_CANVAS_DROP=true 选择启用
资源
资源描述
openaq://location/{locationId}单个监测站的元数据:坐标、提供方、带单位的传感器、数据时间跨度
openaq://parameters完整的污染物和单位目录

两个资源均与工具输出一致,因此仅支持工具的客户端也不会缺少任何内容。

能力参考

openaq_find_locations 工具
  • 使用 coordinates 和 radius(单位为米,1–25000,默认值为 12000)、bbox 和/或 iso(来自 openaq_list_countries 的代码)限定范围;至少需要其中一项,且 coordinates 与 bbox 不能同时使用。还可用 parametersId、monitor、mobile 和 providersId 进一步筛选;每页最多 100 个站点(limit,默认值为 20),page 从 1 开始
  • 每个站点包含 id、distanceMeters(仅适用于坐标搜索)、provider/providerId、isMonitor/isMobile、包含单位信息的 parameters,以及 datetimeFirst/datetimeLast 时间范围;OpenAQ 未提供时,coordinates、country 和 provider 为 null
  • totalCount 统计截至当前页的站点数;设置 totalCountIsLowerBound 时,该值为下限。未找到匹配项时返回 no_locations_found,页码超出末页时返回 page_exhausted

openaq_get_readings 工具
  • 提供 locationId,或提供 coordinates 和 parametersId,以解析出 25 km 内测量该参数的最近站点(最多比较 1,000 个匹配站点;达到 1,000 个时会附加 notice);提供 locationId 时,可选用 parametersId 筛选单个参数
  • 每个传感器返回一条读数,包含 value、unit、sensorId 和 datetimeUtc/datetimeLocal;另返回站点的 provider、providerId、timezone 和 datetimeLast
  • 未找到时会返回对应错误类型:location_not_found、parameter_not_at_location(附带站点的 available id)和 no_station_near_coordinates、no_recent_values

openaq_get_measurements 工具
  • 必须提供 locationId 和 parametersId;datetimeFrom/datetimeTo 接受 UTC 时间戳或站点当地时间的 YYYY-MM-DD 日期(站点没有时区时使用 UTC 日期)。aggregation 可设为 raw(默认值)、hourly 或 daily;每次调用最多返回 5,000 行
  • 返回 series、sensorId、pulledCount、pullComplete、effectiveRange,以及站点的 provider、providerId 和 timezone。设置 totalCountIsLowerBound 时,totalCount 为下限;汇总结果还会包含统计摘要、gapCount、前 20 个缺失时间间隔(作为 gaps),以及边界时间桶被截断时的提示
  • 超过 100 行时,series 会以预览形式返回(truncated),且拉取的行会暂存到 DataCanvas,表名为 measurements_<sensorId>(canvasId、tableName),条件是 CANVAS_PROVIDER_TYPE=duckdb;提供 canvas_id 时,无论数据量大小,都会暂存到该画布。每个传感器对应一张表:第二个传感器会新增一张可供联接的表;对同一传感器再次暂存时,会覆盖之前的序列

openaq_list_parameters 工具
  • 可选使用 query(不区分大小写)搜索代码、显示名称和描述;pollutantsOnly 会排除气象和粒子计数通道
  • 每行包含 id、name、displayName、unit 和 description;一种污染物可能因单位不同而对应多个 id(CO 在 µg/m³ 中为 4,在 ppm 中为 8,在 ppb 中为 102)

openaq_list_countries 工具
  • 可选使用 query(两字母值会优先匹配 ISO 3166-1 alpha-2 代码;否则匹配代码或名称中包含的子串)和 parametersId;每页最多 100 个(limit,默认值为 20),page 从 1 开始
  • 每行包含 code(openaq_find_locations 的 iso 值)、name、datetimeFirst/datetimeLast 时间范围,以及该国任何地点测量的 parameters;totalCount 为筛选后的完整计数

openaq_dataframe_describe 工具
  • 接受来自 openaq_get_measurements 的 canvas_id,并返回每个暂存表的 name、rowCount 和 columns。调用 openaq_dataframe_query 前请先调用此工具:暂存表为扁平结构(min、sd),而内联的 series 会将这些字段嵌套在 summary 下
  • 除非设置了 CANVAS_PROVIDER_TYPE=duckdb,否则会返回 canvas_unavailable;id 未知或已过期时会返回 canvas_not_found

openaq_dataframe_query 工具
  • 接受 canvas_id 和一条只读 SELECT 语句;写入、DDL 以及文件/网络表函数都会被拒绝
  • 每次响应最多返回 200 行;如果结果因达到上限而被截断,则会将 truncated 设为 true;可通过 ORDER BY 加 LIMIT/OFFSET 翻页
  • 失败时会返回 canvas_unavailable、canvas_not_found 或 missing_table

openaq_dataframe_drop 工具
  • 仅当设置了 OPENAQ_ENABLE_CANVAS_DROP=true 时才会注册;除非 CANVAS_PROVIDER_TYPE=duckdb,否则调用会以 canvas_unavailable 失败。禁用时,HTTP 首页会显示启用提示,且 tools/list 中不会包含该工具
  • 接受 canvas_id 并删除整个 canvas,包括所有暂存表。共享该 ID 的其他 Agent 将失去访问权限;OpenAQ 的源数据不受影响
  • 返回请求中的 canvasId 和 dropped:删除成功时为 true,不存在可访问的 canvas 时为 false。关闭身份验证时,调用方共用一个租户:启用该功能后,任何持有 ID 的人都可以删除对应的 canvas

openaq://location/{locationId} 资源
  • application/json:名称、地区、时区、国家、提供方、isMonitor/isMobile、坐标、sensors(每项都包含 parameterId 和 unit),以及 datetimeFirst/datetimeLast 时间范围
  • locationId 来自 openaq_find_locations;缓存 5 分钟

openaq://parameters 资源
  • application/json 目录,行内容与未筛选的 openaq_list_parameters 相同
  • 缓存 1 小时

功能

基于 @cyanheads/mcp-ts-core 构建:支持 stdio 和 Streamable HTTP 传输、可插拔身份验证(none/jwt/oauth)、可切换存储(in-memory、filesystem、Supabase、Cloudflare KV/R2/D1),以及支持可选 OpenTelemetry 跟踪的结构化日志。

OpenAQ 专属功能:

  • 基于 OpenAQ v3 REST API 的类型化客户端:使用 X-API-Key 身份验证、带退避的重试,并为每次 OpenAQ 调用提供类型化上游错误(invalid_api_key、rate_limited、upstream_timeout、upstream_error)
  • 隐藏 v3 的站点 → 传感器 → 测量值层级结构:读数会与最新数据流及站点的传感器映射关联;测量值则通过站点和参数解析到对应传感器
  • 在请求发送到 OpenAQ 之前,对坐标和边界框角点进行范围检查,并拒绝相互矛盾的搜索范围
  • 较大的测量序列会暂存到 DataCanvas 中,以便使用 DuckDB SQL 进行只读查询;每个传感器对应一张表,因此可以联接同一 canvas_id 上的两个序列

便于 Agent 使用的输出:

  • 数据来自实际测量,而非模型估算:搜索不到站点时会返回 no_locations_found 或 no_station_near_coordinates,并说明这是无覆盖数据,而非空气质量良好
  • 每个数值都会附带单位,且绝不进行单位换算;parametersId 会同时选择污染物和单位
  • 明确标示数据新鲜度和截断情况:提供每个数值的时间戳和 datetimeLast,以及达到结果上限时的 totalCount/truncated/notice

开始使用

公共托管实例

公共实例位于 https://openaq.caseyjhand.com/mcp,无需安装。通过 Streamable HTTP 将任意 MCP 客户端连接到该实例:

{
  "mcpServers": {
    "openaq-mcp-server": {
      "type": "streamable-http",
      "url": "https://openaq.caseyjhand.com/mcp"
    }
  }
}
自托管/本地部署

将以下内容添加到 MCP 客户端配置文件中。

{
  "mcpServers": {
    "openaq-mcp-server": {
      "type": "stdio",
      "command": "bunx",
      "args": ["@cyanheads/openaq-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "OPENAQ_API_KEY": "your-api-key"
      }
    }
  }
}

或者使用 npx(无需 Bun):

{
  "mcpServers": {
    "openaq-mcp-server": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@cyanheads/openaq-mcp-server@latest"],
      "env": {
        "MCP_TRANSPORT_TYPE": "stdio",
        "OPENAQ_API_KEY": "your-api-key"
      }
    }
  }
}

或者使用 Docker:

{
  "mcpServers": {
    "openaq-mcp-server": {
      "type": "stdio",
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "MCP_TRANSPORT_TYPE=stdio",
        "-e", "OPENAQ_API_KEY=your-api-key",
        "ghcr.io/cyanheads/openaq-mcp-server:latest"
      ]
    }
  }
}

将 "CANVAS_PROVIDER_TYPE": "duckdb" 添加到 env,即可为大型测量序列启用 DataCanvas SQL。

使用 Streamable HTTP 时,设置传输方式并启动服务:

MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 OPENAQ_API_KEY=your-api-key bun run start:http
# Server listens at http://localhost:3010/mcp
先决条件
安装
  1. 克隆代码仓库:
git clone https://github.com/cyanheads/openaq-mcp-server.git
  1. 进入目录:
cd openaq-mcp-server
  1. 安装依赖:
bun install
  1. 配置环境:
cp .env.example .env
# edit .env and set OPENAQ_API_KEY

配置

变量说明默认值
OPENAQ_API_KEY必填。 OpenAQ v3 API 密钥,通过 X-API-Key 标头发送。—
OPENAQ_API_BASE_URLOpenAQ v3 API 基础 URL,可用于代理或测试镜像。https://api.openaq.org/v3
CANVAS_PROVIDER_TYPEduckdb 会将大型测量序列暂存,以便通过 dataframe 工具执行 SQL;未设置时,大型序列会返回预览和提示。.mcpb 捆绑包不包含 DuckDB,因此进行 canvas 操作时请使用 npm、npx 或 Docker。none
OPENAQ_ENABLE_CANVAS_DROP启用 openaq_dataframe_drop,以删除整个画布并释放其资源。需要 DuckDB;如果某个 ID 与同一租户中的其他 Agent 共享,则该 Agent 也有权删除。false
MCP_TRANSPORT_TYPE传输方式:stdio 或 http。stdio
MCP_HTTP_PORTHTTP 服务端口。3010
MCP_SESSION_MODEHTTP 会话模式:stateless、stateful 或 auto。会覆盖服务端明确设置的无状态模式;auto 会解析为有状态模式。stateless
MCP_AUTH_MODE身份验证:none、jwt 或 oauth。none
MCP_LOG_LEVEL日志级别(debug、info、warning、error 等)。info
OTEL_ENABLED启用 OpenTelemetry。false
OTEL_EXPORTER_OTLP_ENDPOINTOTLP 基础 URL;跟踪数据使用 /v1/traces,指标使用 /v1/metrics。信号专用端点会覆盖此项。—
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT设置完整端点 URL,以启用 OTLP 日志导出。基础端点不会启用日志。—
LOG_TOOL_FAILURE_PAYLOADS记录调用失败时的参数和结果。仅按键名脱敏;自由格式值中的机密信息仍会保留。false
LOG_TOOL_FAILURE_PAYLOAD_MAX_BYTES每个失败负载的 UTF-8 字节数上限。16384

完整的可选覆盖项列表请参见 .env.example。

运行服务端

本地开发
  • 构建并运行:

    bun run rebuild
    bun run start:http   # or start:stdio
    
  • 运行检查和测试:

    bun run devcheck   # Lint, format, typecheck, security, changelog sync
    bun run test       # Vitest test suite
    bun run lint:mcp   # Validate MCP definitions against spec
    
Docker
docker build -t openaq-mcp-server .
docker run --rm -e OPENAQ_API_KEY=your-api-key -p 3010:3010 openaq-mcp-server

此镜像默认使用 HTTP 传输、无状态会话模式,并将日志写入 /var/log/openaq-mcp-server。镜像中包含 DuckDB,因此设置 CANVAS_PROVIDER_TYPE=duckdb 后即可使用 DataCanvas。默认会安装 OpenTelemetry 对等依赖;构建时使用 --build-arg OTEL_ENABLED=false 可省略这些依赖。

项目结构

目录用途
src/index.tscreateApp() 入口:注册工具和资源,并连接服务与画布。
src/config使用 Zod 解析并验证服务端专用环境变量。
src/mcp-server/tools工具定义(definitions/*.tool.ts)以及共享的输入、错误和格式辅助工具(shared/)。
src/mcp-server/resources资源定义(definitions/*.resource.ts)。
src/servicesOpenAQ v3 客户端和领域类型(openaq/),以及 DataCanvas 访问器。
tests/与 src/ 结构对应的单元测试和集成测试。

开发指南

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

  • 处理程序抛出异常,框架负责捕获——仅在将失败映射到已声明的错误原因或保留部分结果时捕获异常
  • 使用 ctx.log 记录请求范围内的日志,使用 ctx.state 存储租户范围内的数据
  • 在 createApp() 数组中注册新工具和资源
  • 封装 OpenAQ API:验证原始数据 → 规范化为领域类型 → 返回输出架构;原样呈现单位,绝不编造缺失字段

贡献

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

bun run devcheck
bun run test

许可证

Apache-2.0 — 详情请参阅 LICENSE。

数据来自 OpenAQ 平台,使用此服务的输出时必须注明 OpenAQ (使用条款)。OpenAQ 汇总了政府机构、研究机构和其他网络的测量数据,其中每个来源都可能制定自己的署名或许可条款。openaq_find_locations、openaq_get_readings 和 openaq_get_measurements 结果中的 provider 字段,以及 openaq://location/{locationId} 资源名称,会标明数据的来源网络;使用任何提供方的数据前,请查阅并遵守其条款。

评论

支持 Markdown

第一次接触 MCP?

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

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