IQAir MCP Server
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@IQAir MCP ServerWhat's the air quality in Bandung, Indonesia?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
IQAir MCP Server
An MCP server that exposes real-time air-quality data from IQAir — built by reverse-engineering the IQAir website (no official API key required).
It was created for the Jakarta air-quality page
(https://www.iqair.com/id/air-quality/indonesia/jakarta/jakarta) but works
for any IQAir location.
What it returns
For a location you get:
US AQI and the main pollutant
Per-pollutant readings: PM2.5, PM10, O₃, SO₂ (AQI + concentration)
Weather: temperature, humidity, pressure, wind
Reporting station count
7-day and 72-hour forecasts
Coordinates / timezone
Tools
Tool | Description |
| Full Jakarta report (current + forecasts). |
| Jakarta current conditions only (lighter). |
| Jakarta forecast ( |
| Any location, e.g. |
path is the segment after /<locale>/air-quality/ in an IQAir URL —
country/state/city.
How it works (reverse engineering)
IQAir is a React Router v7 (Remix) app on Vercel. Every air-quality
page exposes its loader payload at the same URL with a .data suffix:
GET /id/air-quality/indonesia/jakarta/jakarta.data?_routes=routes%2F%24(locale).air-quality.%24The response is turbo-stream encoded (an index-referenced pool with
deferred promise chunks), decoded by turbo_stream.py.
Anti-bot: the Vercel Security Checkpoint
The site is guarded by Vercel's checkpoint. During reverse engineering we found:
Plain
requests/httpx→ HTTP 429 (challenge page).curl_cffiwith Chrome TLS impersonation → still 429 (JS/WASM challenge is required, not just a matching TLS fingerprint).Even a valid
_vcrcscookie replayed from a non-browser client → 429 (TLS/JA3 fingerprint is validated).Headless Chromium → checkpoint never clears (headless is detected).
Headful Chromium → clears in ~3 s.
So the client (iqair_client.py) drives a headful Chromium with a persistent
profile: it solves the checkpoint once, caches the _vcrcs cookie in the
profile, and issues the .data fetch from inside the page context so the
browser's real TLS stack + solved cookie are used. The window is parked
off-screen so it doesn't disturb you.
Setup
cd iqair-mcp
pip install -r requirements.txt
python -m playwright install chromiumA desktop session / display is required (the browser must run headful).
Run
python server.py # stdio (for MCP clients)
python server.py --transport sse # SSE on http://localhost:8000Register with an MCP client
{
"mcpServers": {
"iqair": {
"command": "python",
"args": ["C:\\path-to-mcp\\iqair-mcp\\server.py"]
}
}
}Files
server.py— FastMCP server exposing the tools.iqair_client.py— browser-backed client (challenge solving + fetch + normalize).turbo_stream.py— decoder for React Router's turbo-stream.dataformat.requirements.txt— dependencies.
Staying alive across RDP disconnects
The checkpoint forces a headful browser, and an off-screen headful Chromium can lose its rendering surface (and die) when an RDP session disconnects or locks. The server survives this on two levels:
Auto-recovery — if a call hits a "target/browser closed" error, the client tears down the dead browser and relaunches once, transparently.
Watchdog heartbeat — a background thread pings the browser every
keepalive_seconds(default 60 s); if it's dead/unresponsive it rebuilds and re-solves the challenge proactively, so a disconnect never leaves a dead browser waiting for the next tool call. Warm calls after a revive return in ~1–2 s with no re-solve.
Additionally, the screensaver/auto-lock was disabled for the current user
(HKCU\Control Panel\Desktop → ScreenSaveActive=0, ScreenSaveTimeOut=0) so
a connected session doesn't lock itself out from under the browser. This is
per-user and reversible.
Fully headless-of-console setups (keeping a live desktop with nobody connected) require admin rights — either a machine policy
MaxDisconnectionTime=0underHKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services, or atscon-to-console scheduled task. Those aren't applied here (no elevation on this domain account); the watchdog + auto-recovery cover the disconnect case without them.
Notes & limitations
First call per session pays a one-time ~3 s browser launch + challenge solve; subsequent calls reuse the warm session.
A connected desktop session is still recommended; the watchdog handles brief disconnects/locks by rebuilding, but the machine must have a session to render a headful browser at all.
Data is whatever IQAir currently publishes (values update in real time).
This relies on IQAir's internal (undocumented) data endpoint; site changes may require updating the route id or decoder.
For personal/educational use — respect IQAir's terms of service.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Air Quality MCP — wraps air-quality-api.open-meteo.com (free, no auth)
EPA AirNow MCP — official US real-time AQI + forecast (free key)
WAQI MCP — World Air Quality Index (free key)
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Nanparam/iqair-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server