Skip to main content
Glama
hlucent

seoul-air-quality-mcp

by hlucent
README.md
# 서울시 대기환경 정보 MCP (seoul-air-quality-mcp)

서울특별시 기후환경본부 대기정책과에서 관리하는 대기환경 공공데이터를
AI(Claude 등)가 직접 조회할 수 있도록 만든 MCP(Model Context Protocol) 서버입니다.

담당: 대기정책과 차량공해저감팀 청정 (사무관)
목적: 시민이 "오늘 우리 동네 미세먼지 어때?" 같은 질문을 AI에게 바로 물어보고,
정확한 서울시 공식 데이터로 답을 받을 수 있게 하는 것.

---

## 왜 만들었나

광진구청 류승인 주무관님이 `korean-law-mcp`, `kordoc` 등을 만들면서
개발 과정을 GitHub에 상세히 기록해두신 것을 보고,
"나도 우리 부서 데이터로 이런 걸 만들 수 있지 않을까" 하는 생각에서 시작했습니다.

같은 이유로, 이 저장소도 완성된 코드만 올리는 게 아니라
**왜 이렇게 만들었는지, 어떤 시행착오가 있었는지**를 함께 남깁니다.
다른 직원분이 비슷한 걸 만들고 싶을 때 이 저장소를 그대로 참고하실 수 있도록 하는 게 목표입니다.

---

## 사용한 원본 데이터 (서울 열린데이터광장)

| 데이터셋 | ID | 설명 |
|---|---|---|
| 서울시 시간 평균 대기오염도 정보 | OA-2275 | 자치구별 시간별 대기환경지수/미세먼지/오존 등 (최근 7일) |
| 서울시 실시간 자치구별 대기환경 현황 | OA-1200 | 25개 자치구 실시간 측정값 |
| 서울시 실시간 대기환경 평균 현황 | OA-1201 | 서울시 전체 평균값 |
| 서울시 기간별 시간평균 대기환경 정보 | OA-2221 | 최근 2개월 시간평균 (기간 조회 가능) |
| 서울시 연도별 미세먼지/오존 경보발령 현황 | OA-2228 / OA-2229 | 경보 이력 |

원본시스템: [기후대기환경정보서비스](http://cleanair.seoul.go.kr)
제공부서: 기후환경본부 대기정책과 (☎ 02-2133-3665)
라이선스: 공공누리 1유형 (출처표시 시 상업적 이용·변경 가능)

---

## 개발 일지

### 1단계 — 데이터 파악 (2026-08-01)
서울 열린데이터광장에서 대기정책과 소관 데이터셋을 확인.
`OA-2275`(시간평균 대기오염도)를 1차 대상으로 선정.
연관데이터 탭에서 같은 계열 데이터셋 8~9개를 추가로 확인 → 추후 확장 대상으로 기록.

### 2단계 — API 인증키 발급
`data.seoul.go.kr` 회원가입 → 마이페이지에서 인증키 발급 (무료, 일일 호출 제한 있음).
**주의: 인증키는 절대 코드에 하드코딩하지 않고 환경변수(`SEOUL_API_KEY`)로만 사용.**

### 3단계 — API URL 패턴 확인
서울시 열린데이터광장 공통 패턴:
```
http://openapi.seoul.go.kr:8088/{인증키}/{요청타입}/{서비스명}/{시작인덱스}/{종료인덱스}/
```
- 확인된 서비스명: `RealtimeCityAir` (OA-1200, 실시간 자치구별 대기환경)
- **TODO: OA-2275(시간평균)의 정확한 서비스명은 로그인 후 Open API 탭에서 확인 필요.**
  확인되는 대로 `main.py`의 `TODO_SERVICE_NAME` 부분을 실제 값으로 교체할 것.

### 4단계 — MCP 서버 설계
기존에 만들어둔 `부동산원+빈집` MCP(FastMCP + Fly.io)와 동일한 구조 채택:
- `main.py`: FastMCP 서버, SSE transport
- 도구 1개당 API 엔드포인트 1개 매핑이 기본 원칙 (한 도구가 너무 많은 일을 하지 않게)

### 5단계 — 확장 전략 확정 (2026-08-01)
13개 데이터셋을 한 번에 개발하지 않기로 결정. 이유:
1) 갱신이 오래전에 멈춘 데이터까지 전수 조사 없이 다 넣으면 신뢰도가 오히려 떨어짐.
2) 한 번에 여러 개를 만들면 중간에 지칠 위험이 큼 — 도구 1개씩 완성하고 실제 동작을 확인한 뒤 다음으로 넘어가는 방식 채택.
아래 "MCP 도구 목록 및 확장 로드맵" 표를 기준으로 순서대로 진행.

### 6단계 — OA-2275 서비스명 확인 및 도구 완성 (2026-08-01)
data.seoul.go.kr 로그인 후 OA-2275의 Open API 탭에서 샘플 URL 확인.
- 서비스명: `TimeAverageAirQuality`
- URL 패턴: `.../{인증키}/{타입}/TimeAverageAirQuality/{시작}/{끝}/{YYYYMMDD 또는 YYYYMMDDHH}/{자치구명(선택)}`
- 응답 필드: `MSRMT_DT`(측정일시), `MSRSTN_NM`(자치구명), `NTDX`(NO2), `OZON`(O3), `CBMX`(CO), `SPDX`(SO2), `PM`(PM10), `FPM`(PM2.5)
`get_hourly_air_quality` 도구 완성.

### 7단계 — 배포 (예정)
Fly.io Tokyo 리전으로 배포 예정. 배포 전 Fly.io 지출 한도(월 $5 권장)를 반드시 설정할 것
(이전 작업에서 미설정 상태로 남아있었음 — 이번 프로젝트 배포 전 재확인 필요).

---

## MCP 도구 목록 및 확장 로드맵

**원칙**: FILE 형태로만 제공되거나 2024년 이전에 갱신이 멈춘 데이터는 실시간 조회에 적합하지 않으므로 제외한다.
**대상**: 2025~2026년까지 갱신되고 OpenAPI가 제공되는, 대기정책과 소관 데이터만 선정한다.
**진행 방식**: 도구를 한 번에 다 만들지 않고, 하나씩 추가 → 실제 호출 테스트 → 커밋 → 다음 도구. 매 단계가 하나의 "완주"가 되도록 한다.

| 순서 | 도구명 | 원본 데이터셋 | 최근 갱신 | 상태 |
|---|---|---|---|---|
| 1 | `get_realtime_air_quality` | 서울시 실시간 자치구별 대기환경 현황 (OA-1200) | 상시 | ✅ 구현 완료 |
| 2 | `get_hourly_air_quality` | 서울시 시간 평균 대기오염도 정보 (OA-2275) | 상시 | ✅ 구현 완료 (서비스명: TimeAverageAirQuality) |
| 3 | `get_emission_facility_permits` | 서울시 대기오염물질배출시설설치사업장 인허가 정보 | 2026-08-01 | 📋 다음 순서 후보 |
| 4 | `get_env_construction_permits` | 서울시 환경전문공사업 인허가 정보 | 2026-08-01 | 📋 후보 |
| 5 | `get_env_measurement_agency_permits` | 서울시 환경측정대행업 인허가 정보 | 2026-08-01 | 📋 후보 |
| 6 | `get_yearly_air_quality` | 서울시 년도별 평균 대기오염도 정보 | 2025-11-04 | 📋 후보 |
| 7 | `get_monthly_air_quality` | 서울시 월별 평균 대기오염도 정보 | 2025-11-04 | 📋 후보 |
| 8 | `get_ozone_alert_history` | 서울시 연도별 오존 경보발령 현황 | 2025-11-04 | 📋 후보 |
| 9 | `get_pm25_alert_history` | 서울시 초미세먼지 연도별 발령정보 | 2024-12-04 | 📋 후보 |
| 10 | `get_air_signboard_locations` | 서울시 대기오염전광판 위치정보 | 2024-12-04 | 📋 후보 |

### 이번 단계에서 제외한 데이터
- 서울시 광진구 시간별 대기먼지데이터 (2011~2014, FILE만 제공)
- 서울시 TMS부착사업장 시간단위 대기오염물질 배출농도 (2024-04, FILE만 제공)
- 서울시 대기오염물질 일별 배출량 2019~2021 (FILE만 제공)
- 서울시 대기오염 측정소/측정항목 정보 (보건환경연구원 소관, 대기정책과 아님)
- 서울시 마포구 중앙도서관 공기질(IoT) 측정정보 (정보통신과 소관, 대기정책과 아님)

---

## 실행 방법 (로컬 테스트)

```bash
python -m venv venv
source venv/bin/activate   # Windows는 venv\Scripts\activate
pip install -r requirements.txt

export SEOUL_API_KEY="발급받은_인증키"
python main.py
```

## 배포 (Fly.io)

```bash
fly launch --no-deploy
fly secrets set SEOUL_API_KEY="발급받은_인증키"
fly deploy
```

---

## 라이선스 및 출처

원본 데이터: 서울특별시 (공공누리 1유형, 출처표시)
데이터 제공: 서울 열린데이터광장 (data.seoul.go.kr)

Maintenance

ActivityMaintained
ResponsivenessNo issues