Metadata-Version: 2.4
Name: oecd-stats-mcp
Version: 0.1.0
Summary: OECD 공식 통계(SDMX) 조회·분석 MCP 서버 — 고용·노동 지표를 한국어로 질의
Project-URL: Homepage, https://github.com/seongapark/oecd_mcp
Project-URL: Repository, https://github.com/seongapark/oecd_mcp
Project-URL: Issues, https://github.com/seongapark/oecd_mcp/issues
Author-email: seongapark <seongapark92@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: employment,labour,mcp,oecd,sdmx,statistics,통계
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Natural Language :: Korean
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Information Analysis
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.2.0
Description-Content-Type: text/markdown

# OECD Stats MCP

OECD SDMX API 기반 MCP 서버. Claude에게 한국어로 물으면 OECD 공식 수치를 출처와 함께 반환.
`korean-stats-mcp`(KOSIS)의 구조를 Python으로 옮긴 것.

```
나: OECD 회원국 중 우리나라 청년실업률 몇 위야?
Claude: 2024년 기준 38개국 중 ○위 (○.○%), OECD 평균 대비 -○.○%p
        출처: OECD SDMX OECD.SDD.TPS,DSD_LFS@DF_IALFS_UNE_M,1.0
```

---

## 설치 — 설정 파일 한 곳만 고치면 끝

Claude Desktop 설정 → 개발자 → 설정 편집 으로
`%APPDATA%\Claude\claude_desktop_config.json`(macOS는
`~/Library/Application Support/Claude/claude_desktop_config.json`)을 열고
`mcpServers`에 아래를 추가한다.

```json
{
  "mcpServers": {
    "oecd-stats": {
      "command": "uvx",
      "args": ["oecd-stats-mcp"]
    }
  }
}
```

저장하고 Claude Desktop을 **완전 종료 후 재시작**한다(창만 닫으면 백그라운드에 남으니
트레이 아이콘에서 종료). `uvx`가 격리된 환경에 알아서 받아서 실행하므로
clone도 pip install도 필요 없다. API 키도 필요 없다(OECD 공개 엔드포인트).

`uvx`가 없다면 한 번만 설치한다 — [uv](https://docs.astral.sh/uv/) 설치 시 같이 딸려온다.

```powershell
irm https://astral.sh/uv/install.ps1 | iex     # Windows
```
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh  # macOS / Linux
```

이미 다른 MCP 서버가 등록돼 있으면 `mcpServers` 중괄호 **안쪽에** `"oecd-stats": {...}`만
추가하고 앞 항목 끝에 쉼표를 찍는다. 경로 역슬래시는 두 개(`\\`), 마지막 항목 뒤 쉼표는 금지 —
JSON이 깨지면 MCP가 통째로 안 뜬다.

### 잘 되는지 확인

Claude에게 이렇게 물어본다.

```
OECD 회원국 중 우리나라 청년실업률 몇 위야?
```

안 뜨면 로그를 본다.

```powershell
Get-Content $env:APPDATA\Claude\logs\mcp-server-oecd-stats.log -Tail 30
```

---

## 개발자용 — 소스에서 실행

지표를 추가하거나 코드를 고칠 사람만 해당된다.

```powershell
git clone https://github.com/seongapark/oecd_mcp.git
cd oecd_mcp
python -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txt
```

`activate`가 `PSSecurityException`으로 막히면 activate 없이 `.venv\Scripts\python.exe`를
직접 쓰면 된다. 굳이 쓰려면 그 세션에서만 `Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass`.
macOS/Linux는 `source .venv/bin/activate` 후 `pip install -r requirements.txt`.
`mcp` 1.x / 2.x 양쪽에서 동작한다.

설정에는 `uvx` 대신 해당 python을 직접 지정한다.

```json
{
  "mcpServers": {
    "oecd-stats": {
      "command": "C:\\경로\\oecd_mcp\\.venv\\Scripts\\python.exe",
      "args": ["-m", "oecd_mcp.server"],
      "cwd": "C:\\경로\\oecd_mcp"
    }
  }
}
```

### 지표 검증

```powershell
python verify.py            # 9개 지표가 실제로 값을 받아오는지
python verify.py --meta     # note 문구의 근거를 OECD 메타데이터에서 확인
python verify.py --describe 고용률   # 해당 dataflow의 차원·코드 전체
```

`[OK] 실업률 2025 = 2.79` 처럼 찍히면 정상. `[EMPTY]`/`[FAIL]`이면 그 지표의 필터가
틀린 것이므로 `--describe`로 실제 코드를 확인해 `oecd_mcp/indicators.py`의 `filters`를 고친다.
계열이 2건 이상이면 어느 차원이 안 잡혔는지 `[!]`로 짚어준다.

> Windows 콘솔은 cp949라 한글 출력이 깨질 수 있다. 파일로 받을 때는
> `python verify.py --meta 2>&1 | Out-File -Encoding UTF8 meta.txt` 후
> `Get-Content meta.txt -Encoding UTF8`.

---

## 도구 8개

| 도구 | 하는 일 |
|------|---------|
| `oecd_list_indicators` | 등록 지표 목록 — 뭘 물어볼 수 있는지 확인 |
| `oecd_stats` | 단일 수치 (한 국가 × 한 지표 최신값) |
| `oecd_trend` | 시계열 추세 — 변화율·CAGR·최고/최저·추세방향 |
| `oecd_compare` | N개국 비교표 + 시점 불일치 경고 |
| `oecd_rank` | OECD 회원국 중 순위·백분위·평균 격차 (동일 시점만 비교) |
| `oecd_search_dataflow` | 미등록 통계 검색 (영문 키워드) |
| `oecd_describe_flow` | dataflow의 차원·코드 + OECD 공식 정의문 |
| `oecd_raw_query` | 임의 dataflow 직접 조회 (탈출구) |

등록 지표 9종 — 실업률 / 청년실업률 / 실업률_월별 / 고용률 / 경제활동참가율 /
취업자수 / 실업자수 / 평균임금 / 평균임금_원화

`집값`처럼 정식 용어가 아니어도 별칭으로 인식한다(`연봉`→평균임금, `고용율`→고용률 등).
목록에 없는 통계는 `oecd_search_dataflow` → `oecd_describe_flow` → `oecd_raw_query` 3단으로 조회한다.

---

## 잘못 인용되는 걸 막는 장치

통계는 틀린 값보다 **맞는 값을 잘못 갖다 쓰는 것**이 사고가 된다. 그래서 응답마다 다음이 붙는다.

**해석주의** — 지표마다 정의·단위·비교 가능성을 응답에 항상 실어 보낸다.

| 지표 | 붙는 경고 |
|------|-----------|
| 고용률 | 분모가 15~64세. KOSIS 고용률(15세 이상)과 값이 달라 같은 표에 넣으면 안 됨 |
| 청년실업률 | OECD 청년은 15~24세, 한국 고용통계는 15~29세 |
| 취업자수·실업자수 | `UNIT_MULT=Thousands` — 천 명 단위. 명으로 쓰면 1000배 오류 |
| 평균임금 | 국민계정 기반 FTE 환산치. 사업체 임금조사(「고용형태별 근로실태조사」)와 성격이 다름 |

OECD 원문에서 확인된 사실과 국내 통계 대조(작성자 판단)는 `[참고]`로 구분 표기한다.
근거는 `python verify.py --meta`로 언제든 재확인할 수 있다.

**비교 불가 지표 차단** — `평균임금_원화`는 원화가 한국에만 제공되므로
`oecd_compare`·`oecd_rank` 호출 자체를 거부하고 대안을 안내한다.
"38개국 중 1위" 같은 무의미한 결과가 나올 여지를 없앤다.

**관측치 상태 표시** — `OBS_STATUS`가 `Normal value`가 아니면 잠정·추정치임을 응답에 명시한다.

**출처 표기** — 모든 응답에 dataflow ID가 붙어 그대로 인용·검증할 수 있다.

---

## 구조

```
oecd_mcp/
  client.py      SDMX REST 호출 + SDMX-JSON 파싱 + 6시간 캐시
  indicators.py  지표 카탈로그 (dataflow + 필터 + 한국어 별칭)
  countries.py   ISO3 ↔ 한국어 국가명
  analysis.py    추세·비교·순위 계산 (표준 라이브러리만)
  server.py      MCP 도구 정의
verify.py        지표 카탈로그 실동작 검증
```

### 설계 포인트 — 차원 위치를 하드코딩하지 않음

SDMX 조회 키는 `KOR..._T.Y_GE15..A` 처럼 **점 위치**로 차원을 지정한다.
위치를 코드에 박으면 OECD가 차원을 추가·재배열하는 순간 조용히 엉뚱한 값이 나온다.

이 서버는 조회 전에 DSD를 먼저 읽어 차원 순서를 얻고,
`{"REF_AREA":"KOR","SEX":"_T"}` 같은 **이름 기반 dict**로 키를 조립한다
(`client.build_key`). 지정 안 한 차원은 자동으로 공백(=전체).

부작용: 필터가 덜 걸리면 여러 계열이 섞여 돌아온다.
→ `server._series_note`가 감지해 응답에 "주의"를 붙인다.

### 429 대응

OECD는 짧은 시간에 요청이 몰리면 `429 Too Many Requests`를 준다.
`client._get`이 `Retry-After`를 읽어 지수백오프로 최대 4회 재시도하고,
연속 요청 사이에 최소 간격을 둔다. 404 같은 영구 오류는 재시도하지 않는다.
동일 질의는 6시간 캐싱된다.

### 지표 추가하는 법

1. `oecd_search_dataflow("NEET")` → dataflow ID 확보
2. `oecd_describe_flow(agency, flow)` → 차원 ID와 코드 확인
3. `indicators.py`의 `INDICATORS`에 한 줄 추가, `ALIASES`에 한국어 별칭 추가
4. `python verify.py`로 확인

---

## 업무망(폐쇄망) 관련

OECD API는 외부 인터넷 호출이므로 **폐쇄망에서는 동작하지 않음.**
업무망에서 쓰려면 개인 노트북에서 데이터를 뽑아 xlsx/csv로 반출한 뒤
로컬 파일을 읽는 별도 도구를 쓰는 구조로 가야 함.

---

## 출처

- [OECD SDMX-JSON API 문서](https://data.oecd.org/api/sdmx-json-documentation/)
- [OECD Data Explorer](https://data-explorer.oecd.org/) — 화면에서 데이터 고른 뒤 `Developer API` 버튼으로 쿼리 복사 가능
- 원본 참고: [chrisryugj/korean-stats-mcp](https://github.com/chrisryugj/korean-stats-mcp)
