Skip to main content
Glama
Nanparam

IQAir MCP Server

by Nanparam

IQAir MCP 서버

IQAir의 실시간 대기질 데이터를 제공하는 MCP 서버입니다. IQAir 웹사이트를 리버스 엔지니어링하여 제작되었습니다(공식 API 키 불필요).

자카르타 대기질 페이지(https://www.iqair.com/id/air-quality/indonesia/jakarta/jakarta)를 위해 만들어졌지만 모든 IQAir 위치에서 작동합니다.

반환 내용

위치에 대해 다음을 얻을 수 있습니다:

  • US AQI 및 주요 오염물질

  • 오염물질별 수치: PM2.5, PM10, O₃, SO₂ (AQI + 농도)

  • 날씨: 기온, 습도, 기압, 바람

  • 측정소 수

  • 7일 및 72시간 예보

  • 좌표 / 시간대

Related MCP server: WeatherAPI MCP Server

도구

도구

설명

get_jakarta_air_quality(locale="id")

전체 자카르타 보고서(현재 + 예보).

get_jakarta_current(locale="id")

자카르타 현재 상태만(가벼움).

get_jakarta_forecast(locale="id", kind="daily")

자카르타 예보(daily 또는 hourly).

get_air_quality_by_path(path, locale="en")

모든 위치, 예: path="indonesia/west-java/bandung".

path는 IQAir URL에서 /<locale>/air-quality/ 뒤에 오는 세그먼트입니다 — country/state/city.

작동 방식 (리버스 엔지니어링)

IQAir는 Vercel에서 실행되는 React Router v7 (Remix) 앱입니다. 모든 대기질 페이지는 동일한 URL에 .data 접미사를 붙여 로더 페이로드를 노출합니다:

GET /id/air-quality/indonesia/jakarta/jakarta.data?_routes=routes%2F%24(locale).air-quality.%24

응답은 turbo-stream으로 인코딩됩니다(인덱스 참조 풀과 지연된 promise 청크 포함). turbo_stream.py로 디코딩됩니다.

안티봇: Vercel 보안 체크포인트

사이트는 Vercel의 체크포인트로 보호됩니다. 리버스 엔지니어링 중 다음을 발견했습니다:

  • 일반 requests / httpx → HTTP 429 (챌린지 페이지).

  • Chrome TLS 위장을 사용한 curl_cffi → 여전히 429 (JS/WASM 챌린지가 필요하며, 단순히 일치하는 TLS 지문만으로는 부족).

  • 비브라우저 클라이언트에서 재생된 유효한 _vcrcs 쿠키조차 → 429 (TLS/JA3 지문이 검증됨).

  • 헤드리스 Chromium → 체크포인트가 절대 해제되지 않음(헤드리스가 감지됨).

  • 헤드풀 Chromium → 약 3초 내에 해제됨.

따라서 클라이언트(iqair_client.py)는 영구 프로필을 가진 헤드풀 Chromium을 구동합니다: 체크포인트를 한 번 해결하고, _vcrcs 쿠키를 프로필에 캐시하며, .data fetch를 페이지 컨텍스트 내부에서 실행하여 브라우저의 실제 TLS 스택 + 해결된 쿠키를 사용합니다. 창은 화면 밖에 배치되어 사용자를 방해하지 않습니다.

설정

cd iqair-mcp
pip install -r requirements.txt
python -m playwright install chromium

데스크톱 세션/디스플레이가 필요합니다(브라우저는 헤드풀로 실행되어야 함).

실행

python server.py                    # stdio (for MCP clients)
python server.py --transport sse    # SSE on http://localhost:8000

MCP 클라이언트에 등록

{
  "mcpServers": {
    "iqair": {
      "command": "python",
      "args": ["C:\\path-to-mcp\\iqair-mcp\\server.py"]
    }
  }
}

파일

  • server.py — 도구를 노출하는 FastMCP 서버.

  • iqair_client.py — 브라우저 기반 클라이언트(챌린지 해결 + fetch + 정규화).

  • turbo_stream.py — React Router의 turbo-stream .data 형식 디코더.

  • requirements.txt — 의존성.

RDP 연결 끊김에도 살아남기

체크포인트는 헤드풀 브라우저를 강제하며, 화면 밖 헤드풀 Chromium은 RDP 세션이 연결 해제되거나 잠기면 렌더링 표면을 잃고(죽을 수 있음) 실패할 수 있습니다. 서버는 두 가지 수준에서 이를 견뎌냅니다:

  1. 자동 복구 — 호출 중 "target/browser closed" 오류가 발생하면 클라이언트가 죽은 브라우저를 정리하고 한 번 투명하게 재실행합니다.

  2. 워치독 하트비트 — 백그라운드 스레드가 keepalive_seconds(기본 60초)마다 브라우저를 핑합니다. 죽었거나 응답하지 않으면 사전에 재구축하고 챌린지를 다시 해결하므로, 연결 끊김으로 인해 죽은 브라우저가 다음 도구 호출을 기다리는 일이 없습니다. 복구 후 웜 호출은 재해결 없이 약 1~2초 내에 반환됩니다.

또한 현재 사용자에 대해 화면 보호기/자동 잠금이 비활성화되었습니다(HKCU\Control Panel\Desktop → ScreenSaveActive=0, ScreenSaveTimeOut=0). 이는 연결된 세션이 브라우저 아래에서 스스로 잠기지 않도록 하기 위함입니다. 사용자별 설정이며 되돌릴 수 있습니다.

완전히 콘솔이 없는 헤드리스 설정(연결된 사용자 없이 라이브 데스크톱 유지)은 관리자 권한이 필요합니다 — HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services 아래의 머신 정책 MaxDisconnectionTime=0 또는 tscon-to-console 예약 작업이 필요합니다. 여기서는 적용되지 않습니다(이 도메인 계정에는 승격 권한이 없음). 워치독 + 자동 복구가 이러한 설정 없이 연결 끊김 상황을 처리합니다.

참고 사항 및 제한 사항

  • 세션당 첫 호출은 일회성 약 3초의 브라우저 시작 + 챌린지 해결 시간이 소요됩니다. 이후 호출은 웜 세션을 재사용합니다.

  • 연결된 데스크톱 세션을 여전히 권장합니다. 워치독이 짧은 연결 끊김/잠금을 재구축으로 처리하지만, 헤드풀 브라우저를 렌더링하려면 머신에 세션이 있어야 합니다.

  • 데이터는 IQAir가 현재 게시하는 내용입니다(값은 실시간으로 업데이트됨).

  • 이는 IQAir의 내부(문서화되지 않은) 데이터 엔드포인트에 의존합니다. 사이트 변경 시 경로 ID 또는 디코더를 업데이트해야 할 수 있습니다.

  • 개인/교육용으로 사용하십시오 — IQAir의 서비스 약관을 존중하십시오.

Related MCP Connectors

Related MCP Servers