openaq-mcp-server について
openaq-mcp-serverは、OpenAQ v3を通じて世界各地の観測所による実測大気質データを提供し、環境調査や大気質分析に利用できます。観測所の検索、最新センサー値、汚染物質の履歴を取得でき、単位と観測時刻も保持します。
主な機能
- 01座標、地域、国から観測所を検索
- 02観測所センサーの最新値を取得
- 03汚染物質の履歴と時間別・日別集計を取得
- 04汚染物質カタログと国別の対象範囲を確認
- 05大規模な時系列を保存して読み取り専用SQLで検索
活用シーン
- 01特定の汚染物質を測る近隣観測所を探す
- 02観測所の最新値、単位、時刻を確認する
- 03指定期間の汚染物質の推移を分析する
MCP 対応
MCP サーバーは、観測所検索、測定値、履歴データのツールに加え、観測所と汚染物質カタログのリソースを提供します。STDIOとStreamable HTTPに対応し、OpenAQ v3の呼び出しにはAPIキーが必要です。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://openaq.caseyjhand.com/mcpclaude mcp add --transport http cyanheads-openaq https://openaq.caseyjhand.com/mcp{"mcpServers":{"cyanheads-openaq":{"type":"http","url":"https://openaq.caseyjhand.com/mcp"}}}Cursor で開く{"servers":{"cyanheads-openaq":{"type":"http","url":"https://openaq.caseyjhand.com/mcp"}}}VS Code で開く{"mcpServers":{"cyanheads-openaq":{"type":"http","url":"https://openaq.caseyjhand.com/mcp"}}}{"mcpServers":{"cyanheads-openaq":{"serverUrl":"https://openaq.caseyjhand.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
@cyanheads/openaq-mcp-server
MCP 経由で大気質モニタリングステーションを検索し、最新のセンサー値を読み取り、汚染物質の過去の時系列データを取得します。STDIO または Streamable HTTP に対応しています。
公開ホストサーバー: https://openaq.caseyjhand.com/mcp
概要
OpenAQ v3 API の測定大気質データを取得します。世界各地の政府基準モニターや研究グレードのセンサーによる、物理センサーの観測データです。MCP クライアントからモニタリングステーションを検索し、現在値を読み取り、汚染物質の過去の時系列データを取得できます。stdio プロセス、ローカルの Streamable HTTP サーバー、または上記の公開ホストエンドポイントとして実行できます。
ツール
| ツール | 説明 |
|---|---|
openaq_find_locations | 地点、境界ボックス、または国を指定して付近のモニタリングステーションを検索します。他のツールで使用するロケーション ID を取得します |
openaq_get_readings | ステーションの各センサーの最新値を、汚染物質名と単位を付けて取得します |
openaq_get_measurements | 1 つのステーションにおける 1 つの汚染物質の過去の時系列データを取得します。生データ、または時間単位/日単位に集約したデータを選べます |
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} | 1 つのステーションのメタデータ:座標、プロバイダー、単位付きセンサー、データ範囲 |
openaq://parameters | 汚染物質と単位の完全なカタログ |
どちらのリソースもツールの出力と同じ内容を提供するため、ツールのみを利用するクライアントでも情報が失われることはありません。
機能リファレンス
openaq_find_locations ツール
coordinatesとradius(メートル単位、1~25000、デフォルトは12000)、bbox、および/またはiso(openaq_list_countriesのコード)で範囲を指定します。少なくとも1つが必要で、coordinatesとbboxは同時に指定できません。parametersId、monitor、mobile、providersIdでさらに絞り込めます。1ページあたり最大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は任意で、1つのパラメーターに絞り込めます- 各センサーの
value、unit、sensorId、datetimeUtc/datetimeLocalを含む読み取り値を1件ずつ返します。また、測定局のprovider、providerId、timezone、datetimeLastも返します - 該当データがない場合は、理由ごとに
location_not_found、parameter_not_at_location(測定局で利用可能なIDをavailableに含む)、no_station_near_coordinates、no_recent_valuesが返されます
openaq_get_measurements ツール
locationIdとparametersIdが必要です。datetimeFrom/datetimeToにはUTCタイムスタンプ、または測定局の現地時間によるYYYY-MM-DD形式の日付を指定できます(測定局にタイムゾーンがない場合はUTCの日付)。aggregationはraw(デフォルト)、hourly、dailyのいずれかです。1回の呼び出しで最大5,000行を取得できますseries、sensorId、pulledCount、pullComplete、effectiveRange、および測定局のprovider、providerId、timezoneを返します。totalCountIsLowerBoundが設定されている場合、totalCountは下限値です。集計値には要約統計量、gapCount、最初の20件の欠損区間(gaps)、および端のバケットが切り詰められた場合の通知が追加されます- 100行を超えると、
seriesはプレビュー(truncated)になり、取得した行はCANVAS_PROVIDER_TYPE=duckdbの場合、DataCanvas にmeasurements_<sensorId>(canvasId、tableName)として保存されます。canvas_idが指定されている場合は、サイズにかかわらずそのキャンバスに保存されます。センサーごとに1つのテーブルが作成されます。2つ目のセンサーは結合可能なテーブルとして追加され、同じセンサーを再度保存すると、以前の series が上書きされます
openaq_list_parameters ツール
- 任意の大文字・小文字を区別しない
queryで、コード、表示名、説明を検索できます。pollutantsOnlyを指定すると、気象および粒子数のチャンネルを除外します - 各行には
id、name、displayName、unit、descriptionが含まれます。1つの汚染物質が単位ごとに複数のIDで表示されることがあります(COはµg/m³では4、ppmでは8、ppbでは102)
openaq_list_countries ツール
- 任意の
query(2文字の値はまずISO 3166-1 alpha-2コードと照合され、それ以外はコードまたは名前の部分一致で検索されます)とparametersIdを指定できます。1ページあたり最大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、ファイル/ネットワークのテーブル関数は拒否されます- 1 回の応答につき最大 200 行です。上限によって結果が切り捨てられた場合は
truncatedが設定されます。ページングには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を指定すると、そのキャンバス全体と、ステージング済みのすべてのテーブルを削除します。同じ ID を共有するほかのエージェントもアクセスできなくなります。OpenAQ のソースデータには影響しません- 要求された
canvasIdとdroppedを返します。削除された場合は true、アクセス可能なキャンバスが存在しない場合は false です。認証が無効の場合、呼び出し元は同じテナントを共有します。有効化されている場合、ID を持つユーザーは誰でもそのキャンバスを削除できます
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 の地点 → センサー → 測定値という階層を隠蔽します。測定値の取得では最新のフィードをステーションのセンサーマップに結合し、測定値の検索ではステーションとパラメーターからセンサーを特定します
- 座標と bbox の各頂点を範囲チェックし、矛盾する検索範囲は OpenAQ へのリクエスト送信前に拒否します
- 大量の測定値系列は、読み取り専用の DuckDB SQL 用に DataCanvas へステージングされます。センサーごとに 1 つのテーブルが作成されるため、同じ
canvas_id上の 2 つの系列を結合できます
エージェントが利用しやすい出力:
- モデル化された値ではなく、実測値を使用します。該当するステーションが見つからない検索は
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"
]
}
}
}
大規模な測定値系列に対する DataCanvas SQL を有効にするには、env に "CANVAS_PROVIDER_TYPE": "duckdb" を追加してください。
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
前提条件
- Bun v1.4.0 以降(または Node.js v24 以降)。
- OpenAQ Explorer アカウントで取得できる無料の OpenAQ v3 API キー。
インストール
- リポジトリをクローンします:
git clone https://github.com/cyanheads/openaq-mcp-server.git
- ディレクトリに移動します:
cd openaq-mcp-server
- 依存関係をインストールします:
bun install
- 環境を設定します:
cp .env.example .env
# edit .env and set OPENAQ_API_KEY
設定
| 変数 | 説明 | デフォルト |
|---|---|---|
OPENAQ_API_KEY | 必須。 OpenAQ v3 API キー。X-API-Key ヘッダーとして送信されます。 | — |
OPENAQ_API_BASE_URL | プロキシまたはテスト用ミラーの OpenAQ v3 API ベース URL。 | https://api.openaq.org/v3 |
CANVAS_PROVIDER_TYPE | duckdb を指定すると、データフレームツールで SQL を実行できるよう、大容量の測定系列をステージングします。指定しない場合、大容量の系列はプレビューと通知を返します。.mcpb バンドルには DuckDB が含まれていないため、キャンバスを使用するには npm、npx、または Docker を使用してください。 | none |
OPENAQ_ENABLE_CANVAS_DROP | openaq_dataframe_drop を有効にして、キャンバス全体を削除し、そのリソースを解放します。DuckDB が必要です。同じテナント内で別のエージェントと共有している ID には、削除アクセス権が付与されます。 | false |
MCP_TRANSPORT_TYPE | トランスポート:stdio または http。 | stdio |
MCP_HTTP_PORT | HTTP サーバーのポート。 | 3010 |
MCP_SESSION_MODE | HTTP セッションモード: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_ENDPOINT | OTLP ベース 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.ts | createApp() のエントリーポイント:ツールとリソースを登録し、サービスとキャンバスを接続します。 |
src/config | Zod を使用した、サーバー固有の環境変数の解析と検証。 |
src/mcp-server/tools | ツール定義(definitions/*.tool.ts)と、共有の入力、エラー、フォーマット用ヘルパー(shared/)。 |
src/mcp-server/resources | リソース定義(definitions/*.resource.ts)。 |
src/services | OpenAQ 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}リソースには、データの提供元ネットワークが記載されています。利用するプロバイダーの条件を確認し、遵守してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。