Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Openair 3 Oss

БесплатноНе проверен

MCP server wrapping the openair R package for air quality data analysis, enabling time series loading, statistical summaries, and publication-ready plots like p

GitHubEmbed

Описание

MCP server wrapping the openair R package for air quality data analysis, enabling time series loading, statistical summaries, and publication-ready plots like polar and calendar plots.

README

License: MIT

The server — run on any machine with R (your laptop, lab VM, or cloud). MCP clients connect via stdio (local) or HTTP (local 127.0.0.1 or remote host via mcp-remote).

Give your AI agent the ability to analyse air quality — import public networks, load CSV exports, and produce publication-grade openair charts from chat.

Pair with the client plugin for your IDE: openair-3-mcp-client-plugin-oss (Claude, Cursor, Codex, VS Code).

Not affiliated with openair-project maintainers.

  • 45 tools — 37 R-backed plots/imports/stats + 8 Python pipeline tools (CSV, Excel, upload, prepare, health, docs)
  • 2 transportsstdio (IDE and R on the same machine) or HTTP (localhost or remote via mcp-remote)
  • Agent skills — plugin manuals + workflows (skills/)
  • Self-hosted — you choose where R runs; the default path is local on your own machine

Architecture

flowchart LR
  subgraph localSetup ["Local (stdio) — IDE and R on the same machine"]
    IDE_L["IDE + client-plugin"]
    S_L["server-oss + R"]
    IDE_L -- ".mcp.json (stdio)" --> S_L
  end

  subgraph remoteSetup ["Remote (HTTP) — server on another host"]
    IDE_R["IDE + client-plugin"]
    Proxy["mcp-remote"]
    S_R["server-oss + R"]
    IDE_R -- ".mcp.json" --> Proxy -- "HTTPS + token" --> S_R
  end

client-plugin on your MCP client · server-oss + R on the host you choose · use stdio when both are on the same machine, HTTP + mcp-remote when the server is elsewhere (including 127.0.0.1).

Choose your setup

Local Remote
R location Same machine as the IDE Another host (VM, cloud, lab server)
Run server fastmcp run … --transport stdio or --transport http --port 8001 fastmcp run … --transport http --port 8001 on the host (+ reverse proxy optional)
Client MCP stdio (spawn Python) or mcp-remotehttp://127.0.0.1:8001/sse mcp-remotehttps://your-host/…/sse (+ token if enabled)
CSV paths Paths on your disk export_local_series.py on your PC, or paths on the server disk — not IDE workspace paths
Node.js on client Only if using HTTP + mcp-remote Yes (npx mcp-remote)

Remote MCP (VS Code, Cursor, etc.): load_series_from_excel(path="data/felisa.xlsx") only works if that file is on the server host. Example paths in docs are not bundled. For chat smoke use the plugin fixture — vscode-chat-felisa.md.

Server run commands are in Running the server; client .mcp.json wiring lives in the client plugin README.

vs R console / openair GUI

This project R console + openair
Natural-language workflows Yes (via MCP client) Manual scripting
PNG charts in chat Yes (inline MCP image blocks) Save files locally
Public network import import_aurn, import_europe, … Same R functions, manual
CSV / IoT exports load_series_from_csv Read + reshape by hand
Tool discovery for agents MCP tool list + skill Docs + memory
Open source server MIT MIT (openair 3.x)
Self-hosted Yes Yes

Quick start

git clone https://github.com/miguel-escribano/openair-3-mcp-server-oss
cd openair-3-mcp-server-oss
python -m venv .venv
# Windows: .venv\Scripts\activate
# Unix: source .venv/bin/activate
pip install -e .
cp .env.example .env
python check_integrations.py

Install R packages on the same machine:

install.packages(c("openair", "jsonlite"), repos = "https://cloud.r-project.org")
# optional: legendry only adds the cor_plot dendrogram — everything else works without it
install.packages("legendry", repos = "https://cloud.r-project.org")

Run HTTP MCP (same machine or remote host; IDE connects via mcp-remote):

fastmcp run server.py:mcp --transport http --port 8001

Run stdio (IDE and R on the same machine — no mcp-remote, no separate HTTP process):

fastmcp run server.py:mcp --transport stdio

Then install the client plugin and wire MCP — local stdio, localhost HTTP, or remote URL.

Getting your data in

Your data Where it lives What to use
Excel / CSV Server disk load_series_from_excel / load_series_from_csv
Excel / CSV User PC (remote MCP) export_local_series.py on the client → prepare_series_for_openair(data=…) — or copy to server disk; load_series_from_upload (base64, ≤ 1 MB) last resort
UK / EU public networks Fetched by R import_aurn, import_europe, import_ukaq, …
ADMS / AURN CSV on server Server disk path import_adms, import_aurn_csv
Another MCP (API, database, spreadsheet, …) Upstream MCP prepare_series_for_openair(json_exports=[…]) → plot

Another MCP: fetch/query runs on the upstream MCP (Postgres read MCP, REST API MCP, Airtable MCP, etc.). Pass its export JSON to prepare_series_for_openair. The export must include series_v1 or a compatible parameters[].data bucket layout — see export_bridge.py and schemas/series.v1.json. Do not build series arrays in the client.

Data pipeline

flowchart TB
  agent["Agent / chat — orchestrates the pipeline"]

  subgraph in ["Data in (deterministic tools)"]
    disk["load_series_from_*"]
    export["export_local_series.py"]
    net["import_*"]
    mcp["json_exports"]
  end

  v1["SeriesV1"]
  prep["prepare_series_for_openair"]
  df["R data.frame"]
  plot["openair plot"]
  png["PNG"]

  agent --> disk & export & net & mcp
  disk --> v1
  export --> v1
  net --> v1
  mcp --> prep
  agent --> prep --> df --> plot --> png
  v1 --> prep

The agent orchestrates every step. Calculation (parse, align, plot) stays on the server — no LLM-invented JSON or date parsing in the client.

  1. Ingest — disk load, client export script, public import, or JSON from another MCP → SeriesV1
  2. prepare — align timestamps, granularity, timezone, gaps
  3. R — build data.frame(date, …) then call openair::timePlot (etc.)
  4. Return — PNG (+ short text summary)

Typical flows

CSV (global / sensor export)

Wide table: datetime column + pollutant columns. Skip metadata (battery, lat, …) with optional columns.

  1. load_series_from_csv — path on server disk (ISO or EU day-first dates, e.g. 23/06/2026 00:00h)
  2. prepare_series_for_openair — set series_name when multiple pollutants; timezone / timezone_name for local exports
  3. One plot tool — time_plot, calendar_plot, …

Sample files in fixtures/ are for pytest and check_integrations.py only (ingest/date-format smoke). They are not Copilot chat datasets.

Golden-path acceptance: plugin repo tests/ + felisa_munarriz.json. Walkthrough: csv-calendar-plot.md (server-disk CSV flow).

Excel (regional / government exports)

Same pipeline with load_series_from_excel.xlsx on server disk only. Handles Spanish-style Fecha/hora and duplicate-hour dedupe.

Setup Path
Remote MCP + file on your PC export_local_series.pyprepare(data=…)ingest-local-export skill
VS Code smoke (no Excel) Plugin tests/fixtures/felisa_munarriz.jsonvscode-chat-felisa.md
File on server host load_series_from_excel with an absolute path you confirmed

Walkthrough: local-excel-spain.md. There is no bundled data/felisa.xlsx.

Local file on your PC (remote MCP)

If the MCP server runs elsewhere, paths on your laptop are invisible to load_series_from_*.

Preferred: run scripts/export_local_series.py on your machine (pip install -e . from this repo — no R required). Read the JSON and call prepare_series_for_openair(data=…) on the remote MCP. See the client ingest-local-export skill.

Alternatives: copy the file to server disk, use local stdio MCP, or load_series_from_upload (base64, max 1 MB raw). See the client ingest-local skill.

Public network (UK / EU)

  1. import_aurn / import_europe / import_ukaq
  2. prepare_series_for_openair
  3. Plot tool

Walkthrough: aurn-time-plot.md.

Another MCP (API, database, spreadsheet, …)

  1. Configure a second MCP in your client (REST API, Postgres, Airtable, custom sensor API, etc.).
  2. Call the upstream tool that returns hourly/time-series JSON.
  3. prepare_series_for_openair(json_exports=[export]) — optional series_name, parameter, granularity, timezone_name.
  4. Plot tool.

The upstream MCP owns fetch and query; this server owns alignment and openair plots.

Optional live smoke: OPENAIR_SMOKE_NETWORK=1 python check_integrations.py

Available tools

Plot and import tools are auto-discovered from r/scripts/*.R manifest headers at startup.

Pipeline (Python)

Tool Description
load_series_from_csv Parse a wide CSV on server disk into SeriesV1. EU/ES date formats; optional columns, timezone, dedupe_timestamps.
load_series_from_excel Parse .xlsx on server disk — same options as CSV (regional air-quality exports).
load_series_from_upload Parse CSV or xlsx from base64 upload. Default limit 1 MB raw; override with OPENAIR_INGEST_MAX_BYTES on the server. Use export_local_series.py instead for larger files.
prepare_series_for_openair Align timestamps, granularity, timezone; optional json_exports from other MCPs.
ping Server liveness check.
health_r R + openair version and install status.
openair_docs Index of openair functions exposed as MCP tools.
openair_function_help R help text for a named openair function.

Data import (R)

Tool Description
import_aurn UK Automatic Urban and Rural Network (AURN). Requires internet.
import_adms CERC ADMS files on server disk (.bgd, .met, .mop, .pst).
import_aurn_csv UK AURN hourly CSV export on server disk.
import_ukaq UK Air Pollution Networks (AQE, SAQN, WAQN, NI, local).
import_europe European monitoring networks via openair (data until Feb 2024).
import_meta Site metadata — codes, names, coordinates, available pollutants.
import_traj Pre-calculated HYSPLIT 96-hour back trajectories.

Time series plots (R)

Tool Description
time_plot One or more pollutant time series.
summary_plot Multi-panel overview: averaged time series + data completeness.
calendar_plot Calendar view — day-of-week and seasonal patterns.
time_variation Diurnal, weekday, and monthly patterns with uncertainty.
variation_plot Mean and confidence intervals by time dimension.
time_prop Stacked proportional contributions over time (wind-aware input).
trend_level Heat map of concentration by two time dimensions.
smooth_trend GAM smooth trend with confidence intervals.
theil_sen Non-parametric Theil–Sen trend and significance.
scatter_plot Scatter between two pollutants.
cor_plot Correlation matrix (≥2 series).
conditional_quantile Model evaluation — predicted vs observed quantiles.
taylor_diagram Model evaluation — Taylor diagram (obs + models).

Polar / wind (R)

Requires wind speed (ws) and direction (wd) in prepared data.

Tool Description
polar_plot Bivariate polar plot — concentration vs wind (source ID).
polar_annulus Polar annulus with a third variable (season, hour, …).
polar_diff Difference between two time periods on the same pollutant.
polar_freq Wind frequency polar with optional pollutant stats.
polar_cluster K-means clustering of polar plots (intensive).
pollution_rose Pollution rose by direction and speed.
percentile_rose Percentile rose by wind direction.
wind_rose Classic wind rose.

Trajectory (R)

Tool Description
traj_plot Back-trajectory line plot (TrajSeriesV1).
traj_level Gridded concentration heat map from trajectory frequency.
traj_cluster K-means clustering of back trajectories.

Stats & transforms (R)

Tool Description
aq_stats Summary stats — mean, median, percentiles, capture %.
mod_stats Model evaluation — FAC2, MB, RMSE, r (model series first, observed second).
calc_percentile Percentile values as JSON.
time_average Resample to another resolution (returns SeriesV1).
rolling_mean Rolling mean (returns SeriesV1).
rolling_quantile Rolling quantile (returns SeriesV1).

Plot tools return [text, image] MCP blocks so clients can show the chart inline. Stats tools return structured JSON.

Prerequisite: R 4.1+ with openair 3.x (ggplot2 backend) on the server host. Run health_r after install.

Running the server

Pick a transport based on where your IDE runs relative to R:

HTTP (R on your laptop at 127.0.0.1, or a remote host):

fastmcp run server.py:mcp --transport http --port 8001

stdio (IDE and R on the same machine — no HTTP port, no mcp-remote):

fastmcp run server.py:mcp --transport stdio

That is all this repo handles. Connecting an IDE to the running server is the client plugin's job — copy its .mcp.json.example and choose stdio, localhost HTTP, or a remote URL (+ token). See the client plugin → Installation detail and .mcp.json.example. Node.js 18+ is needed on the client only for HTTP + mcp-remote.

Server configuration

Copy .env.example.env:

Variable Purpose
RSCRIPT_PATH Path to Rscript (default Rscript)
RSCRIPT_TIMEOUT_SEC Default R subprocess timeout
OPENAIR_ARTIFACTS_DIR Where PNGs are written (default artifacts/)
OPENAIR_MCP_TRANSPORT http or stdio when using python server.py
OPENAIR_MCP_PORT HTTP port (default 8001)

R only needs to run on the server — not on every IDE client.

Development

git clone https://github.com/miguel-escribano/openair-3-mcp-server-oss
cd openair-3-mcp-server-oss
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env
python check_integrations.py
pytest

Project structure

server.py                 # FastMCP entry — tool registration
openair_mcp/
├── prepare.py            # prepare_series_for_openair
├── export_bridge.py      # json_exports merge / SeriesV1
├── r_bridge.py           # R subprocess + manifest discovery
├── contracts.py          # Pydantic SeriesV1, WindSeriesV1, …
└── utils.py              # CSV → SeriesV1
r/
├── scripts/              # One .R file = one MCP tool (MANIFEST header)
└── common/               # Shared R helpers
schemas/                  # JSON Schema for series contracts
fixtures/                 # Tiny CSV samples for pytest / check_integrations (not chat fixtures)
tests/                    # Python unit tests (pre-deploy — not plot acceptance)
check_integrations.py     # Smoke suite (Python always; R when available)

Add a new tool: drop an R script in r/scripts/ with a # MANIFEST: {...} line — no Python edit required.

Testing

Tier Where Purpose
Acceptance Plugin tests/ 15-plot harness against deployed MCP — legends, encoding, end-to-end
Unit This repo pytest tests/ Ingest, prepare, encoding, DST — fast, no R plots required for most
Host smoke check_integrations.py Tool registration + R subprocess when R is installed

After deploy, run the plugin harness — see tests/README.md. Full checklist: docs/VALIDATION.md.

Tech stack

  • Python 3.11+ — MCP server, CSV pipeline, contracts
  • FastMCP 3.x — MCP protocol
  • Pydantic — SeriesV1 / request validation
  • R + openair 3.x — Plots, imports, statistics (openair MIT on CRAN)
  • jsonlite — R JSON bridge

Use cases

  • Researcher with AURN data — “Import Marylebone Road PM2.5 for 2023 and calendar plot it”
  • IoT / indoor CSV — Load hourly export from disk → time plot or diurnal pattern
  • Source apportionment hint — Polar plot when wind columns exist
  • Trend reporting — Theil–Sen or smooth trend for long series
  • Multi-pollutant screening — Correlation matrix across prepared series
  • Ex-GUI habit — Same openair charts you know, alongside your usual R workflow — from Claude / Cursor / Codex when chat fits

Roadmap

Feature What it unlocks Status
CSV load_series_from_csv Global / sensor exports without custom glue Done (v0.1.0)
Excel load_series_from_excel Regional .xlsx (ES/EU date formats, dedupe) Done (v0.1.0)
Upload load_series_from_upload Remote MCP + file on user PC (base64, ≤ 1 MB) Done (v0.1.0)
export_local_series.py Agent-run local export → prepare(data=…) (no R on client) Done (v0.1.0)
UK/EU import_* Public network path familiar to openair users Done (v0.1.0)
worldmet Meteo when CSV has no wind Planned
openairmaps Leaflet maps in chat Later (if demand)
deweather Met normalisation Advanced (later)

Optional: JSON from other MCPs

prepare_series_for_openair(json_exports=[…]) accepts generic time-series JSON (series_v1 or bucketed parameters). Standalone use needs only CSV or import_*.

Scope

This binomio provides charts and data access through MCP, powered by openair on R. It does not include interpretation, compliance advice, or health guidance — those belong in your own reporting workflow.

For methodology, see the openair book. Teams that pair generative AI with air-quality data often add a controlled knowledge base for narrative beyond plots; that layer is separate from this chart stack.

Release v0.1.0 — initial public release of the binomio. CSV/Excel/upload ingest with optional lat/lon (meta for future worldmet), public-network imports (AURN, EU, …), the full openair plot/stats surface. Golden-path Felisa fixture + harness live in the client plugin (tests/fixtures/felisa_munarriz.json). Pair with the client plugin at the same release. Feedback welcome via issues or the landing repo.

Third-party and attribution

See also NOTICE.md for openair MIT text and deploy-time third-party listing.

This project is not affiliated with openair-project. If you use it — commercial or not — please attribute the parts you rely on.

openair (software)

Charts and statistics are produced by the openair R package (MIT). In papers, reports, or published figures, cite:

Carslaw, D. C. and K. Ropkins (2012). openair — an R package for air quality data analysis. Environmental Modelling & Software, 27–28, 52–61. doi:10.1016/j.envsoft.2011.09.008

BibTeX and updates: openair citation. In R: citation("openair").

Public air-quality data

import_aurn, import_europe, and related tools fetch third-party datasets, not data shipped with this repo. You must follow each provider’s licence when you publish or redistribute results.

Source Typical requirement
UK networks (AURN, etc.) Open Government Licence. Attribute Defra / uk-air.defra.gov.uk.
European networks Respect source terms; openair notes EU import availability (see import_europe docs).
Your CSV Your responsibility only.

Example UK data attribution (OGL):

© Crown copyright Defra via uk-air.defra.gov.uk, licensed under the Open Government Licence.

This MCP wrapper (optional)

openair-3-mcp-server-oss and openair-3-mcp-client-plugin-oss are MIT. You do not need our permission for non-commercial or commercial use. If this MCP binomio was part of your workflow and you publish methods, a brief mention or link to the GitHub repos is appreciated — but the scientific citation above is openair, not this wrapper.

License

MIT — see LICENSE. See Third-party and attribution for openair and data sources.

from github.com/miguel-escribano/openair-3-mcp-server-oss

Установка Openair 3 Oss

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/miguel-escribano/openair-3-mcp-server-oss

FAQ

Openair 3 Oss MCP бесплатный?

Да, Openair 3 Oss MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Openair 3 Oss?

Нет, Openair 3 Oss работает без API-ключей и переменных окружения.

Openair 3 Oss — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Openair 3 Oss в Claude Desktop, Claude Code или Cursor?

Открой Openair 3 Oss на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Openair 3 Oss with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории productivity