airkorea-forecast-alert-mcp
by hlucent
README.md
> ⚠️ **서비스 종료 안내**
> 본 MCP 서버는 2026-08-23부로 fly.io 배포를 종료했습니다.
> 코드는 개발 참고용으로 저장소에 남겨둡니다.
# airkorea-forecast-alert-mcp
한국환경공단 에어코리아 OpenAPI의 **대기질 예보 · 미세먼지 경보 · 오존/황사 주의보** 계열을
조회하는 MCP 서버입니다.
## 제공 도구
| 도구 | 설명 |
|---|---|
| `get_air_quality_forecast` | 대기질(미세먼지/오존) 예보통보 조회 — 오늘/내일/모레 예보, 예보개황, 발생원인, 행동요령 |
| `get_pm25_weekly_forecast` | 초미세먼지 주간예보 조회 — 3일 후부터 4일간의 낮음/높음 예보 |
| `get_high_pm25_forecast` | 고농도 초미세먼지(50초과) 예보 정보 조회 — 19개 권역의 PM2.5 50㎍/㎥ 초과 여부 |
| `get_pm_alarm_status` | 미세먼지 경보 현황 조회 — 지역별 주의보·경보 발령/해제 이력 |
| `get_ozone_advisory` | 오존주의보 발생정보 조회 |
| `get_yellowdust_advisory` | 황사주의보 발생정보 조회 |
> **설계 노트**: DEVPLAN.md 3절에서는 오존주의보·황사주의보를 하나의 툴(`advisory_type`
> 파라미터로 분기)로 묶는 방안을 우선 검토하도록 했으나, 실측 결과 두 오퍼레이션의 응답
> 필드가 크게 달라(오존은 농도·발령단계 등 8개 필드, 황사는 회차·지역 텍스트 2개 필드)
> 하나로 묶으면 사용성이 떨어진다고 판단해 **2개 툴로 분리**했습니다(총 6개 툴).
## 데이터 출처
- **제공기관**: 한국환경공단 기후대기본부 대기환경처 대기정책지원부
- **플랫폼**: [공공데이터포털](https://www.data.go.kr) (data.go.kr)
- **서비스 그룹**: 한국환경공단_에어코리아_대기오염정보(일부), 한국환경공단_에어코리아_
고농도 초미세먼지(50초과) 예보 정보, 한국환경공단_에어코리아_미세먼지 경보 발령 현황,
한국환경공단_에어코리아_오존황사 발생정보 (서비스 그룹 코드 `B552584`)
- **이용허락범위**: 저작자표시-변경금지 (자료의 출처(환경부/한국환경공단) 표기 의무 준수)
## 발표 주기 (중요)
| 항목 | 발표 주기 |
|---|---|
| 미세먼지 예보(오늘/내일/모레) | 매일 4회 (05시/11시/17시/23시), 19개 권역 |
| 오존 예보 | **매년 4월 1일 ~ 10월 31일**에만 발표. 오늘예보는 05/11시(특이사항 시 17시 추가) |
| 초미세먼지 주간예보 | 매일 1회 17시 30분, 19개 권역, 3일 후부터 4일간 |
| 고농도 초미세먼지(50초과) 예보 | 매일 4회 (05/11/17/23시), 각 시별 10분 내외 |
## 알려진 제약사항 (실측으로 확인된 사항, 오퍼레이션별 — 2026-08-22/23 실측)
### `get_air_quality_forecast` (getMinuDustFrcstDspth)
- `informData` 필드 **실제 존재 확인**. items 배열의 각 항목이 오늘/내일/모레 예보를
구분하며, `informData` 값(YYYY-MM-DD)이 해당 예보의 대상 날짜를 나타냅니다.
(예: `dataTime`이 "2026-08-22 23시 발표"일 때 items가 `informData`
"2026-08-22"/"2026-08-23"/"2026-08-24" 순으로 옴)
- 오존(O3) 비시즌(11~3월) 조회 시 **에러 없이 정상적으로 빈 목록**(`resultCode: "00"`,
`totalCount: 0`)이 옵니다(2026-01-15 실측 확인).
- `ver=1.1` 파라미터는 이번 실측에서 사용하지 않았습니다(기본/구버전 방식으로 충분히
동작 확인). 이미지 URL(`imageUrl1`~`imageUrl9`)은 참고용 링크로 그대로 반환합니다.
### `get_high_pm25_forecast` (getMinuDustFrcstDspth50Over)
- 명세서에 스펙 표가 없어(SWAGGER 문서 참고로만 기재) 전량 실측으로 확정했습니다.
- `searchDate`, `informCode`(PM10/PM25/O3) 파라미터 **정상 동작 확인**.
- 19개 권역 `{지역}50Over` 필드명 전체(실측 확인, 알파벳순):
`busan50Over`, `chungbuk50Over`, `chungnam50Over`, `daegu50Over`, `daejeon50Over`,
`gwangju50Over`, `gyeongbuk50Over`, `gyeonggibuk50Over`, `gyeongginam50Over`,
`gyeongnam50Over`, `incheon50Over`, `jeju50Over`, `jeonbuk50Over`, `jeonnam50Over`,
`sejong50Over`, `seoul50Over`, `ulsan50Over`, `youngdong50Over`, `youngseo50Over`
(같은 이름 패턴의 `{지역}Grade` 필드도 함께 제공되며 좋음/보통/나쁨/매우나쁨 텍스트).
- **⚠️ 확인 필요(미해결)**: 미초과 시 값이 `"X"`임은 실측 확인했으나, 초과 시 값(명세서
본문 추정값 `"O"`)은 2026년 8월 한 달(계절적으로 PM2.5가 낮은 시기) 동안 재현되지
않아 미확인 상태입니다. 코드에서는 명세서 추정값(`"O"`)을 기본값으로 두고 있으며,
실제 고농도 발생 시 재검증이 필요합니다.
- **조회 가능 기간이 최근 약 1개월로 제한**되는 것으로 실측 확인(그 이전 날짜의
`searchDate`로 조회하면 `totalCount: 0`인 빈 목록).
### `get_pm_alarm_status` (getUlfptcaAlarmInfo)
- 아직 해제되지 않은 경보는 명세서상 `clearDate`가 `"--"`, `clearTime`이 `":00"`,
`clearVal`이 `"공람"`(숫자 아님)으로 온다고 되어 있습니다. 이 도구는 이 경우 해당
필드를 안전 변환 시 `null`로 처리하고, 별도로 `cleared`(bool)/`status`(문자열) 필드로
"미해제(진행 중)" 상태를 명시합니다.
- **⚠️ 확인 필요(미해결)**: 2025~2026년 실제 데이터(총 448건)를 전량 조회했으나 전부
이미 해제 완료 상태였고, 미해제 패턴(`"--"`/`"공람"`)이 실제로 재현되는 사례를 찾지
못했습니다. 향후 미해제 경보 발생 시 재검증이 필요합니다.
### `get_ozone_advisory` / `get_yellowdust_advisory`
- 오존주의보는 매년 **4월~10월에만 발표**되는 계절성이 있습니다(비시즌 데이터는 단순히
없을 뿐이며, 위 `get_air_quality_forecast`의 O3 비시즌 실측에서 API 자체는 정상
동작함을 별도로 확인했습니다).
- `get_ozone_advisory`, `get_yellowdust_advisory` 모두 `year` 파라미터로 실측 정상
호출 확인(2026년/2025년).
### 공통: 공공데이터포털 API 자체의 간헐적 불안정성
- 실측 중 `getMinuDustFrcstDspth`, `getMinuDustWeekFrcstDspth`,
`getMinuDustFrcstDspth50Over` 호출에서 **간헐적으로 `SERVICETIMEOUT_ERROR`(코드 05)
또는 순수 네트워크 타임아웃**이 발생했습니다. 동일 요청을 재시도하면 대부분 정상
응답을 받았습니다 — 코드 결함이 아니라 공공데이터포털 서버 자체의 부하성 이슈로
판단됩니다. 클라이언트는 `httpx` 30초 타임아웃을 사용하며, 필요 시 호출자가 재시도할
것을 권장합니다.
## 환경변수
| 변수명 | 설명 |
|---|---|
| `AIRKOREA_SERVICE_KEY` | 공공데이터포털에서 발급받은 에어코리아 서비스키 (Decoding 키) |
## 설치 및 실행 (로컬)
```bash
pip install -r requirements.txt --break-system-packages
cp .env.example .env # AIRKOREA_SERVICE_KEY 값 입력
python server.py
```
## 배포 (fly.io)
```powershell
fly launch --no-deploy
# fly.toml이 [http_service] 방식인지 확인 후
fly secrets set AIRKOREA_SERVICE_KEY=발급받은키
flyctl deploy
```
## Claude.ai 커넥터 연결
```
https://airkorea-forecast-alert-mcp.fly.dev/mcp
```
## Rate Limit 정책
- 분당 3회 초과 시 429 (멀티 머신 배포 시 머신 수에 비례해 실질 완화될 수 있음)
- 1시간 내 429를 5회 이상 받으면 24시간 차단
- 일일(rolling 24시간) 총 30회 초과 시 429
## 에러 코드
공공데이터포털 표준 에러코드 체계를 사용합니다 (1단계 `airkorea-realtime-mcp`와 동일).
| 코드 | 의미 |
|---|---|
| 00 | 정상 |
| 03 | No Data |
| 10 | 잘못된 요청 파라미터 |
| 11 | 필수 파라미터 누락 |
| 20 | 서비스 접근 거부 |
| 22 | 일일 트래픽 제한 초과 |
| 30 | 등록하지 않은 서비스키 |
| 31 | 서비스키 사용 기간 만료 |
## 관련 프로젝트
에어코리아 OpenAPI는 규모가 커서 3개의 독립 MCP로 분리 개발됩니다:
| 단계 | 저장소 | 포함 범위 |
|---|---|---|
| 1단계 | `airkorea-realtime-mcp` | 실시간 측정정보, CAI, 측정소정보 |
| 2단계 (이 프로젝트) | `airkorea-forecast-alert-mcp` | 대기질 예보, 초미세먼지 주간예보, 고농도 예보, 미세먼지 경보, 오존주의보, 황사주의보 |
| 3단계 | `airkorea-statistics-mcp` | 시도·측정소 통계(일/월평균), CAI 나쁨이상 측정소 |
## 라이선스
MIT (코드) / 공공누리 제1유형(저작자표시) 준수 — 데이터 출처(환경부/한국환경공단) 표기
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues