Metadata-Version: 2.5
Name: kre-mcp
Version: 0.1.1
Summary: Korean apartment transaction and presale right trade MCP server
Project-URL: Repository, https://github.com/jaypakdevkr/KRE-MCP
Project-URL: Issues, https://github.com/jaypakdevkr/KRE-MCP/issues
Author: jaypakdevkr
License-Expression: MIT
License-File: LICENSE
Keywords: apartment,korea,mcp,real-estate
Requires-Python: >=3.10
Requires-Dist: defusedxml<1,>=0.7.1
Requires-Dist: httpx<1,>=0.27
Requires-Dist: mcp<2,>=1.26
Description-Content-Type: text/markdown

# KRE-MCP · 한국 아파트 실거래가를 AI와 함께 조회하기

**KRE-MCP는 AI가 국토교통부의 아파트 매매·분양권 전매 실거래가를 조회할 수 있도록 연결하는 Python MCP 서버입니다.**

Claude Desktop이나 MCP를 지원하는 개발 도구에서 질문하면, AI가 필요한 조회 도구를 호출하고 결과를 설명합니다. Python 개발자는 LangChain 에이전트에 연결해 공공데이터를 사용하는 AI 실습을 만들 수 있습니다.

[PyPI 패키지](https://pypi.org/project/kre-mcp/) · [소스 저장소](https://github.com/jaypakdevkr/KRE-MCP) · [공공데이터포털](https://www.data.go.kr/)

| 한눈에 보기 | 내용 |
| --- | --- |
| 패키지 / 실행 명령 | `kre-mcp` / `uvx kre-mcp` |
| 현재 안내 버전 | `0.1.1` |
| 제공 도구 | 아파트 매매 조회, 아파트 분양권·입주권 전매 조회 |
| 조회 기준 | 지역코드 + 계약년월 + 페이지 |
| 데이터 출처 | 국토교통부 공공데이터포털 API |
| 실행 환경 | Python 3.10 이상, 로컬 stdio MCP 클라이언트 |
| 필요한 인증 | 각 API의 활용승인 및 공공데이터포털 인증키 |
| 개발·배포 | jaypakdevkr / MIT 라이선스 |

> 이 프로젝트는 국토교통부 공개 API를 연결하는 독립 프로젝트입니다. 한국부동산원 R-ONE 통계 서비스나 정부기관의 공식 MCP 제품이 아닙니다. `korea-realestate-mcp`와도 별개의 패키지입니다.

## 목차

1. [이 패키지로 할 수 있는 일](#이-패키지로-할-수-있는-일)
2. [어떻게 동작하나요?](#어떻게-동작하나요)
3. [시작 전 준비](#시작-전-준비)
4. [설치와 실행 확인](#설치와-실행-확인)
5. [AI 클라이언트에 연결](#ai-클라이언트에-연결)
6. [첫 조회와 단계별 실습](#첫-조회와-단계별-실습)
7. [도구 입력 명세](#도구-입력-명세)
8. [조회 결과 읽는 법](#조회-결과-읽는-법)
9. [Python과 LangChain에서 사용](#python과-langchain에서-사용)
10. [문제 해결](#문제-해결)
11. [자주 묻는 질문](#자주-묻는-질문)
12. [개발·검증·배포](#개발검증배포)

## 이 패키지로 할 수 있는 일

### 1. 아파트 매매 실거래가 조회

`realestate_search_apt_trade`는 지정한 지역과 계약월의 아파트 매매 신고 내역을 가져옵니다. 아파트 이름, 계약일, 거래금액, 전용면적, 층 등 API가 제공하는 필드를 확인할 수 있습니다.

**질문 예시**

> 지역코드 11680의 2026년 1월 아파트 매매 거래를 10건 조회하고, 단지명·계약일·금액·전용면적·층을 표로 보여줘.

### 2. 아파트 분양권·입주권 전매 실거래가 조회

`realestate_search_presale_trade`는 같은 방식으로 분양권·입주권 전매 신고 내역을 가져옵니다. 거래금액·면적과 함께 권리 구분(`ownershipGbn`), 취소 관련 필드를 확인할 수 있습니다.

**질문 예시**

> 같은 지역과 월의 분양권 전매도 10건 조회해줘. 매매 결과와 구분해서 보여주고, 권리 구분 필드가 있으면 함께 설명해줘.

### 3. 페이지를 이어서 조회하고 원본 필드 확인

한 번에 최대 100건을 조회하며, 전체 건수와 다음 페이지 여부를 반환합니다. AI 클라이언트나 Python 코드에서 `page`를 늘려 다음 데이터를 가져올 수 있습니다. 서버가 단지명이나 숫자를 임의로 바꾸지 않으므로 원본 필드를 기준으로 데이터 처리 수업을 진행하기에도 적합합니다.

### 지원 범위

| 작업 | 현재 지원 방식 |
| --- | --- |
| 지역·월별 매매 및 분양권 전매 조회 | 전용 MCP 도구 2개 제공 |
| 전체 건수, 페이지별 거래 확인 | `total_count`, `returned_count`, `has_next` 제공 |
| 거래 취소 여부 확인 | 원본 `cdealType`, `cdealDay` 반환; 자동 제외하지 않음 |
| 단지명으로 필터링 | 전용 입력 없음; 조회한 데이터에서 클라이언트가 후처리 |
| 여러 달 비교·평균·중앙값 계산 | 서버 내장 분석 없음; 각 월·페이지 조회 후 별도 계산 필요 |
| 지역명 → 법정동 코드 검색 | 내장 검색 없음; 공식 코드표에서 확인 |
| 전월세·전세가율·호가·시세 예측 | 제공하지 않음 |
| 웹 대시보드·원격 HTTP 서버 | 제공하지 않음; 로컬 stdio 연결 사용 |

AI에게 표 작성이나 데이터 비교를 요청할 수 있지만, 이것은 조회된 결과를 활용하는 클라이언트의 작업입니다. 패키지 자체에 해당 분석 도구가 추가되는 것은 아닙니다.

## 어떻게 동작하나요?

MCP(Model Context Protocol)는 AI 애플리케이션이 외부 도구를 호출할 때 사용하는 통신 규약입니다. KRE-MCP는 이 규약에 맞춰 두 개의 조회 기능을 제공합니다.

```text
사용자의 질문
    ↓
AI 클라이언트 / LangChain 에이전트
    ↓ 도구 이름과 조회 조건 전달
KRE-MCP 서버 (내 컴퓨터에서 실행)
    ↓ 인증키로 HTTPS 요청
국토교통부 공공데이터 API
    ↓ 실제 거래 데이터
KRE-MCP → AI 클라이언트 → 표·설명으로 답변
```

- **서버**는 데이터를 조회합니다. 자체 LLM이나 대화 화면은 포함하지 않습니다.
- **클라이언트**가 서버 프로세스를 실행하고 표준입출력(stdio)으로 통신합니다. 별도의 포트 설정은 필요하지 않습니다.
- **인증키**는 서버의 `PUBLIC_DATA_API_KEY` 환경변수에 넣습니다. 질문이나 도구 입력에는 넣지 않습니다.
- 서버는 거래 데이터를 별도 데이터베이스에 저장하거나 캐시하지 않습니다. 반복 조회도 API 호출량을 사용합니다.

## 시작 전 준비

### 준비물

- 인터넷 연결이 가능한 macOS·Windows·Linux 환경
- `uv` 또는 Python 3.10 이상
- 로컬 stdio MCP 서버를 지원하는 클라이언트, 또는 Python 실행 환경
- 공공데이터포털 계정과 아래 두 API의 활용승인

### 공공데이터포털 API 신청

1. [공공데이터포털](https://www.data.go.kr/)에 로그인합니다.
2. 다음 API 각각에서 **활용신청**을 진행합니다.
3. 마이페이지의 활용신청 내역에서 승인 상태를 확인합니다.
4. **일반 인증키(Decoding)**를 준비합니다.

| API | 용도 | 상세 안내 |
| --- | --- | --- |
| 국토교통부_아파트 매매 실거래가 자료 | 아파트 매매 도구 | [활용신청 페이지](https://www.data.go.kr/data/15126469/openapi.do) |
| 국토교통부_아파트 분양권전매 실거래가 자료 | 분양권·입주권 전매 도구 | [활용신청 페이지](https://www.data.go.kr/data/15126471/openapi.do) |

한 API의 승인만으로 다른 API까지 사용할 수 있다고 가정하지 마세요. 동일한 인증키를 쓰더라도 서비스별 활용승인은 확인해야 합니다. 호출 한도와 승인 상태는 포털의 본인 계정에서 확인할 수 있습니다.

일반 인증키(Encoding)도 서버에서 한 번 디코딩하여 처리하지만, 처음 설정할 때는 Decoding 키를 권장합니다. 수강생마다 본인의 키를 사용하세요.

## 설치와 실행 확인

### 방법 A. uvx로 실행 — 교육 실습 권장

`uvx`는 패키지와 의존성을 격리된 환경에 준비해 실행하는 명령입니다. 저장소를 내려받거나 먼저 `pip install kre-mcp`를 실행할 필요가 없습니다.

**uv가 없다면 설치**

macOS / Linux:

```sh
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Windows PowerShell:

```powershell
winget install --id=astral-sh.uv -e
```

설치 후 터미널을 다시 열고 확인합니다. 다른 설치 방법은 [uv 공식 설치 안내](https://docs.astral.sh/uv/getting-started/installation/)를 참고하세요.

```sh
uv --version
uvx --from kre-mcp==0.1.1 kre-mcp --version
```

두 번째 명령에서 `0.1.1`이 출력되면 패키지 설치와 실행 진입점이 정상입니다. **이 명령만으로 인증키나 API 활용승인까지 검증되지는 않습니다.**

### 방법 B. pip로 가상환경에 설치

macOS / Linux:

```sh
python3 -m venv .venv
source .venv/bin/activate
python -m pip install kre-mcp==0.1.1
kre-mcp --version
```

Windows PowerShell에서는 가상환경을 활성화하지 않고 실행할 수도 있습니다.

```powershell
py -m venv .venv
.\.venv\Scripts\python.exe -m pip install kre-mcp==0.1.1
.\.venv\Scripts\kre-mcp.exe --version
```

MCP 클라이언트가 이 가상환경을 자동으로 사용하지는 않습니다. pip 방식으로 설치했다면 서버 설정의 `command`에 해당 환경의 `kre-mcp` 실행 파일 **절대 경로**를 지정하고 `args`는 빈 배열로 설정하세요.

### 인증키를 셸에 설정할 때

Python 실습이나 직접 실행할 때 사용합니다. 아래 문자열을 본인 키로 교체하세요.

macOS / Linux:

```sh
export PUBLIC_DATA_API_KEY='본인의 공공데이터포털 인증키'
```

Windows PowerShell:

```powershell
$env:PUBLIC_DATA_API_KEY = '본인의 공공데이터포털 인증키'
```

이 설정은 해당 터미널과 그 터미널에서 시작한 프로세스에 적용됩니다. 바탕화면에서 실행한 GUI 앱에는 전달되지 않을 수 있으므로, 다음 클라이언트 설정의 `env`를 사용하는 편이 명확합니다.

**`.env` 파일은 자동으로 읽지 않습니다.** 파일에 키를 적는 것만으로 서버에 설정되지 않습니다.

## AI 클라이언트에 연결

### Claude Desktop

1. Claude Desktop의 **Settings → Developer → Edit Config**에서 설정 파일을 엽니다.
2. 아래 `kre-mcp` 항목을 `mcpServers` 안에 추가합니다. 기존 서버 설정이 있다면 유지하세요.
3. 인증키 문자열을 교체하고 저장합니다.
4. 앱을 완전히 종료한 뒤 다시 실행합니다.
5. 사용 가능한 도구 목록에 두 조회 도구가 나타나는지 확인합니다.

```json
{
  "mcpServers": {
    "kre-mcp": {
      "command": "uvx",
      "args": ["--from", "kre-mcp==0.1.1", "kre-mcp"],
      "env": {
        "PUBLIC_DATA_API_KEY": "본인의 공공데이터포털 인증키"
      }
    }
  }
}
```

JSON에는 주석이나 마지막 항목 뒤 쉼표를 넣지 마세요. Windows 경로를 직접 입력할 때는 `C:\\Users\\이름\\...\\uvx.exe`처럼 역슬래시를 두 번 적습니다.

설정 파일 위치와 연결 과정은 [MCP 공식 로컬 서버 연결 안내](https://modelcontextprotocol.io/docs/2026-07-28/develop/connect-local-servers)를 참고하세요. 클라이언트 버전에 따라 메뉴 위치는 달라질 수 있습니다.

### VS Code

작업 폴더의 `.vscode/mcp.json`에는 아래 형식을 사용합니다. Claude Desktop의 `mcpServers`와 달리 최상위 키가 `servers`입니다. 암호 입력 항목으로 키를 받아 설정 파일에 직접 적지 않는 예제입니다.

```json
{
  "inputs": [
    {
      "type": "promptString",
      "id": "public-data-api-key",
      "description": "공공데이터포털 일반 인증키",
      "password": true
    }
  ],
  "servers": {
    "kre-mcp": {
      "type": "stdio",
      "command": "uvx",
      "args": ["--from", "kre-mcp==0.1.1", "kre-mcp"],
      "env": {
        "PUBLIC_DATA_API_KEY": "${input:public-data-api-key}"
      }
    }
  }
}
```

서버 시작·도구 활성화는 [VS Code MCP 안내](https://code.visualstudio.com/docs/agent-customization/mcp-servers)를 따르세요. 그 밖의 클라이언트도 `command`, `args`, `env`를 이용한 **로컬 stdio** 연결이 가능하면 같은 서버를 사용할 수 있습니다. 설정 파일 형식은 각 클라이언트에 맞춰야 합니다.

### 연결 성공 확인

다음 두 도구가 보이면 도구 탐색 단계가 성공한 것입니다.

- `realestate_search_apt_trade`
- `realestate_search_presale_trade`

이어서 실제 조회를 한 번 실행해야 키·API 승인·네트워크까지 확인할 수 있습니다. `uvx kre-mcp`를 터미널에서 직접 실행했을 때 화면이 조용한 것은 정상입니다. 서버는 MCP 클라이언트의 요청을 기다립니다. 직접 실행한 프로세스를 끝내려면 `Ctrl+C`를 누르세요.

## 첫 조회와 단계별 실습

### 실습 1. 조건이 분명한 첫 질문

> 지역코드 11680, 계약년월 202601로 아파트 매매 실거래가 첫 페이지를 5건 조회해줘. 전체 건수와 이번에 받은 건수를 따로 알려줘.

**확인할 점:** 도구 호출의 입력이 `region_code="11680"`, `deal_ym="202601"`, `page=1`, `page_size=5`인지, 응답에 `total_count`와 `returned_count`가 있는지 확인합니다.

### 실습 2. 결과를 읽기 쉬운 표로 정리

> 방금 받은 거래에서 단지명, 계약일, 전용면적, 층, 거래금액을 표로 만들어줘. 금액 단위는 만원으로 표시하고, 빈 필드는 정보 없음으로 적어줘.

**확인할 점:** `dealAmount`를 원으로 오해하지 않았는지, 빈 값을 임의로 채우지 않았는지 확인합니다. 예를 들어 `120,000`만원은 12억원입니다.

### 실습 3. 분양권 전매와 구분

> 같은 지역과 월의 분양권 전매를 첫 페이지 5건 조회해줘. 앞서 본 아파트 매매와 별개의 목록으로 보여줘.

**확인할 점:** `realestate_search_presale_trade`가 호출되는지, `trade_type`이 `presale`인지 확인합니다. 일반 매매와 분양권 전매를 같은 거래 목록으로 합치지 않습니다.

### 실습 4. 페이지네이션

> 매매 결과의 has_next가 true라면 같은 page_size로 2페이지를 조회해줘. 지금까지 전체 중 몇 건을 받았는지 구분해서 설명해줘.

**확인할 점:** `page`는 1부터 시작합니다. 이어서 조회할 때 `page_size`를 유지해야 겹치거나 건너뛰는 구간을 피할 수 있습니다. 여러 페이지를 읽었다고 해서 전체를 읽은 것은 아닙니다.

### 실습 5. 데이터 해석 연습

> 지금 조회한 거래에서 취소 관련 필드를 확인해줘. 이 표만으로 해당 지역 전체의 평균 시세를 말할 수 있는지도 설명해줘.

**확인할 점:** 취소 거래를 서버가 자동 제외하지 않는다는 점, 월·지역·면적·단지별 거래 구성이 다르다는 점, 현재 결과가 전체 데이터인지 확인합니다.

### 강사용 진행 예시 (약 30분)

| 순서 | 실습 내용 | 완료 기준 |
| --- | --- | --- |
| 1 · 준비 | uv 설치, API 승인·키 확인 | 버전 출력 확인 |
| 2 · 연결 | 클라이언트 설정, 앱 재시작 | 도구 2개 표시 |
| 3 · 조회 | 지역코드·계약월을 명시해 질문 | 실제 API 응답 수신 |
| 4 · 해석 | 금액 단위·취소 필드·페이지 확인 | 표와 원본 필드 대조 |
| 5 · 확장 | Python 또는 LangChain으로 같은 도구 호출 | 도구 반환값 확인 |

API 활용신청은 수업 전에 끝내는 것을 권장합니다. 실습에서는 버전을 고정하고 5~10건부터 조회하면 결과를 비교하기 쉽습니다.

## 도구 입력 명세

두 도구는 같은 입력 구조를 사용합니다.

| 매개변수 | 자료형 | 필수 | 기본값 | 의미와 허용 범위 |
| --- | --- | --- | --- | --- |
| `region_code` | 문자열 | 예 | 없음 | 법정동 코드 앞 5자리. 예: `"11680"` |
| `deal_ym` | 문자열 | 예 | 없음 | 유효한 계약년월 `YYYYMM`. 예: `"202601"` |
| `page` | 정수 | 아니요 | `1` | 1 이상 |
| `page_size` | 정수 | 아니요 | `100` | 1~100 |

**도구 호출 입력 예제**

```json
{
  "region_code": "11680",
  "deal_ym": "202601",
  "page": 1,
  "page_size": 5
}
```

- 서울 종로구 예시는 `11110`, 서울 강남구 예시는 `11680`입니다. 다른 지역은 [행정표준코드관리시스템](https://www.code.go.kr/)에서 법정동 코드를 확인하고 앞 5자리를 사용하세요.
- `"강남구"`, `"1168010100"`, `"2026-01"`은 이 도구가 받는 입력 형식이 아닙니다.
- 계약년월은 조회하는 날짜가 아니라 **계약이 이루어진 월**입니다.
- 지역코드는 5자리 형식을 검사하지만 실제 존재 여부를 별도 코드표로 검증하지 않습니다.
- 현재 월·신고 지연·거래가 없는 조건에서는 결과가 적거나 없을 수 있습니다. 특정 건수를 보장하지 않습니다.

## 조회 결과 읽는 법

다음은 **형식 설명을 위한 가상 응답**입니다. 실제 단지나 실제 거래 사례를 나타내지 않습니다. `items`의 필드는 일부만 표시했습니다.

```json
{
  "source": "국토교통부 실거래가 공개자료 (공공데이터포털)",
  "trade_type": "apartment",
  "region_code": "11680",
  "deal_ym": "202601",
  "page": 1,
  "page_size": 1,
  "total_count": 12,
  "items": [
    {
      "aptNm": "교육용 예시 아파트",
      "dealYear": "2026",
      "dealMonth": "1",
      "dealDay": "15",
      "dealAmount": "120,000",
      "excluUseAr": "84.95",
      "floor": "10",
      "cdealType": "",
      "cdealDay": ""
    }
  ],
  "returned_count": 1,
  "has_next": true,
  "units": {"dealAmount": "만원", "excluUseAr": "㎡"},
  "note": "한 페이지의 원본 거래입니다. 취소 거래(cdealType, cdealDay)를 확인하세요. 신고 지연·정정으로 결과가 바뀔 수 있습니다."
}
```

### 응답 메타데이터

| 필드 | 의미 |
| --- | --- |
| `trade_type` | `apartment`: 매매, `presale`: 분양권·입주권 전매 |
| `total_count` | 해당 조회 조건에 대해 API가 알려준 전체 건수 |
| `returned_count` | 이번 페이지의 `items` 길이 |
| `has_next` | 다음 페이지가 있는지 여부 |
| `items` | 현재 페이지의 원본 거래 목록 |
| `units` | 금액·면적 단위 안내 |

`has_next=true`이면 같은 지역·월·페이지 크기로 `page`를 1 늘려 조회합니다. 조회 중 원천 데이터가 정정되면 페이지별 결과나 건수도 달라질 수 있습니다. 결과가 없다면 `items=[]`, `returned_count=0`으로 반환될 수 있습니다.

### 자주 사용하는 거래 필드

| 필드 | 의미 | 읽을 때 주의할 점 |
| --- | --- | --- |
| `aptNm` | 아파트 이름 | 이름이 비슷한 단지를 같은 단지로 단정하지 않기 |
| `dealYear`, `dealMonth`, `dealDay` | 계약 연·월·일 | 각 값이 문자열로 반환됨 |
| `dealAmount` | 거래금액 | 만원 단위, 쉼표가 포함될 수 있음 |
| `excluUseAr` | 전용면적 | 제곱미터(㎡), 공급면적이 아님 |
| `floor` | 층 | 숫자로 계산할 때 별도 변환 필요 |
| `umdNm`, `jibun` | 법정동 이름·지번 | API가 제공하는 주소 관련 필드 |
| `cdealType`, `cdealDay` | 거래 취소 관련 정보 | 원천 API 의미에 따라 판별; 서버는 원본을 유지 |
| `ownershipGbn` | 분양권·입주권 관련 구분 | 분양권 전매 응답에서 확인 |

원본 XML 필드의 앞뒤 공백만 제거합니다. 숫자형 변환, 금액 환산, 누락값 보정, 취소 거래 제거, 정렬은 자동 수행하지 않습니다. API나 거래에 따라 필드가 없거나 빈 문자열일 수 있습니다.

## Python과 LangChain에서 사용

아래 예제는 **GitHub 저장소 접근 없이**, PyPI 패키지만으로 실행할 수 있습니다. 저장소는 현재 비공개이므로 소스 링크는 접근 권한이 있는 사용자만 열 수 있습니다.

### 1. LLM 없이 MCP 도구 직접 호출

`mcp_demo.py`라는 파일에 저장합니다. 앞서 설명한 방식으로 `PUBLIC_DATA_API_KEY`를 터미널에 설정하세요.

```python
import asyncio
import json
import os

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client


async def main():
    params = StdioServerParameters(
        command="uvx",
        args=["--from", "kre-mcp==0.1.1", "kre-mcp"],
        env={"PUBLIC_DATA_API_KEY": os.environ["PUBLIC_DATA_API_KEY"]},
    )
    async with stdio_client(params) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            tools = await session.list_tools()
            print("도구:", [tool.name for tool in tools.tools])
            result = await session.call_tool(
                "realestate_search_apt_trade",
                {"region_code": "11680", "deal_ym": "202601", "page_size": 5},
            )
            if result.isError:
                raise RuntimeError(result.content)
            data = json.loads(result.content[0].text)
            print(json.dumps(data, ensure_ascii=False, indent=2))


asyncio.run(main())
```

```sh
uv run --no-project --with "mcp>=1.26,<2" python mcp_demo.py
```

이 실습에는 LLM API 키가 필요하지 않습니다. 서버 도구가 실제로 동작하는지 먼저 확인하기 좋은 단계입니다.

### 2. LangChain MCP 어댑터로 에이전트 만들기

MCP 어댑터는 서버의 도구를 LangChain이 호출할 수 있는 도구로 변환합니다. 다음 예제는 기존 `langchain-mcp-adapters`의 `MultiServerMCPClient`를 사용하는 교육용 코드입니다.

> 이 어댑터 저장소는 유지보수가 종료됐으며 공식 후속 API는 [`langchain.mcp.MCPAdapter`](https://docs.langchain.com/oss/python/langchain/mcp)입니다. 기존 교육 자료와의 연결을 위해 아래 예제는 검증한 기존 어댑터 버전을 고정합니다.

`agent_demo.py`로 저장하세요. 공공데이터 키 외에 선택한 LLM 제공자의 키도 필요합니다. 아래 코드는 Anthropic 연동 예시이며, `MODEL_ID`에는 본인 계정에서 사용할 수 있는 실제 모델 ID를 설정합니다.

```python
import asyncio
import os

from langchain.agents import create_agent
from langchain_mcp_adapters.client import MultiServerMCPClient


async def main():
    client = MultiServerMCPClient({
        "kre": {
            "transport": "stdio",
            "command": "uvx",
            "args": ["--from", "kre-mcp==0.1.1", "kre-mcp"],
            "env": {"PUBLIC_DATA_API_KEY": os.environ["PUBLIC_DATA_API_KEY"]},
        }
    })
    tools = await client.get_tools()
    agent = create_agent(
        model="anthropic:" + os.environ["MODEL_ID"],
        tools=tools,
        system_prompt=(
            "실거래가 조회 도우미입니다. 도구로 조회하고 한국어로 답하세요. "
            "금액은 만원, 면적은 ㎡입니다. 전체 건수와 현재 페이지 건수를 구분하세요."
        ),
    )
    result = await agent.ainvoke(
        {"messages": [{
            "role": "user",
            "content": "지역코드 11680의 2026년 1월 매매와 분양권 전매를 각각 1건 조회해줘.",
        }]},
        config={"recursion_limit": 12},
    )
    print(result["messages"][-1].content)


asyncio.run(main())
```

macOS / Linux 환경변수 예시:

```sh
export ANTHROPIC_API_KEY='본인의 LLM API 키'
export MODEL_ID='계정에서 사용 가능한 모델 ID'
```

Windows PowerShell 환경변수 예시:

```powershell
$env:ANTHROPIC_API_KEY = '본인의 LLM API 키'
$env:MODEL_ID = '계정에서 사용 가능한 모델 ID'
```

실행 명령은 한 줄입니다.

```sh
uv run --no-project --with langchain==1.4.3 --with langchain-mcp-adapters==0.3.2 --with langchain-anthropic python agent_demo.py
```

LLM API 이용 요금은 모델 제공자의 정책을 따릅니다. 질문과 조회 결과는 선택한 모델 제공자에게 전달됩니다. 공공데이터 키는 서버 환경변수로 전달하고 프롬프트에는 넣지 않습니다.

**검증 범위:** 기존 어댑터와 테스트용 모델을 이용해 `create_agent → MCP 서버 → 실제 국토교통부 API → 도구 결과 → 에이전트 종료` 흐름을 검증했습니다. 실제 유료 LLM의 도구 선택·답변 품질까지 검증한 것은 아닙니다.

저장소 접근 권한이 있다면 [실행 가능한 에이전트·연결 테스트 예제](https://github.com/jaypakdevkr/KRE-MCP/tree/main/examples/langchain)도 이용할 수 있습니다.

## 문제 해결

| 증상 | 확인 및 해결 |
| --- | --- |
| `uvx`를 찾지 못함 / 서버 시작 실패 | 터미널에서 `uvx --version` 실행. GUI 앱만 실패하면 `command`에 uvx 절대 경로 지정 |
| 터미널에서 서버가 멈춘 것처럼 보임 | stdio 요청 대기 상태일 수 있음. 설치 확인은 `--version`, 실제 사용은 MCP 클라이언트로 연결 |
| `PUBLIC_DATA_API_KEY` 환경변수 오류 | 클라이언트의 `env` 또는 Python을 실행한 터미널에 키 설정. `.env`는 자동 로드하지 않음 |
| 도구 목록은 보이지만 조회 실패 | 키·서비스별 활용승인·네트워크를 확인. 도구 탐색 성공과 API 인증 성공은 별개 |
| 인증키 확인 / 활용신청 승인 안내 | Decoding 키의 복사 상태와 해당 API 승인 내역 확인 |
| 일일 호출 한도 초과 | 본인 계정의 호출량을 확인하고 포털 정책에 따라 이후 재시도 |
| HTTP 오류 / 연결 실패 / 시간 초과 | API 서비스 상태와 네트워크 확인 후 재시도. 서버 요청 제한 시간은 30초 |
| 지역코드·계약년월 형식 오류 | 지역코드 5자리 문자열, 월은 `YYYYMM` 문자열로 전달 |
| 결과가 0건 | 지역·월·페이지 확인. 해당 조건에 신고된 거래가 없을 수 있음 |
| 거래가 일부만 보임 | `total_count`와 `has_next` 확인 후 같은 크기로 다음 페이지 조회 |
| 수정한 키나 버전이 적용되지 않음 | 클라이언트 설정 저장 후 서버 또는 앱 재시작 |
| LangChain 예제에서 모델 인증 실패 | 공공데이터 키와 LLM 키는 서로 다름. 모델 제공자 패키지·키·접근 가능한 모델 ID 확인 |

uvx 실행 파일 위치 확인:

```sh
# macOS / Linux
command -v uvx
```

```powershell
# Windows PowerShell
(Get-Command uvx).Source
```

문제를 공유할 때는 패키지 버전, 운영체제, 클라이언트, 도구 이름, 키를 제외한 입력값, 오류 메시지를 함께 남겨 주세요. 인증키가 들어 있는 설정 파일 전체를 공유하지 마세요.

## 자주 묻는 질문

**설치만 하면 AI와 대화할 수 있나요?**  
아니요. 이 패키지는 데이터 조회 서버입니다. 대화하려면 MCP 클라이언트나 LLM 에이전트가 필요합니다. Python에서 직접 호출하면 LLM 없이도 조회할 수 있습니다.

**패키지에 API 키가 들어 있나요?**  
없습니다. 각 사용자가 공공데이터포털에서 키를 발급받아 환경변수로 설정합니다.

**무료인가요?**  
패키지는 MIT 라이선스로 배포됩니다. 공공데이터 API의 이용 조건·호출 한도는 포털을 따르며, AI 클라이언트나 LLM API 비용은 별도입니다.

**실거래가가 지금 매물의 가격인가요?**  
신고된 계약 자료입니다. 현재 호가나 매물 목록을 제공하지 않습니다. 신고 지연·정정·취소로 결과가 바뀔 수 있습니다.

**지역 이름만 입력해도 되나요?**  
서버는 5자리 코드를 받습니다. 교육 초기에는 코드와 계약월을 명시하면 AI의 추측을 줄이고 결과를 재현하기 쉽습니다.

**전월세나 한국부동산원 통계도 조회할 수 있나요?**  
현재 버전에는 포함하지 않습니다. 제공 도구 표에 있는 두 종류의 거래 조회만 지원합니다.

**업데이트는 어떻게 하나요?**  
버전을 고정한 클라이언트는 설정의 버전 문자열을 새 릴리스로 바꾸고 재시작하세요. 최신 버전 확인은 `uvx --refresh kre-mcp --version`, pip 설치 업데이트는 가상환경에서 `python -m pip install --upgrade kre-mcp`를 사용합니다.

## 개발·검증·배포

소스 저장소 접근 권한이 있는 개발자는 저장소 루트에서 실행합니다.

```sh
uv sync --locked
uv run pytest -q
uv run ruff check .
uv build
uv run twine check dist/*
```

자동 테스트는 입력 검증, XML 응답 파싱, 빈 결과, 오류·인증키 노출 방지, HTTP 요청과 페이지 처리, 실제 stdio MCP 연결을 확인합니다. 일반 테스트에는 API 키가 필요하지 않습니다. 실제 공공데이터 조회는 별도 연결 검증으로 수행합니다.

PyPI 배포는 GitHub Actions의 `Publish to PyPI` 워크플로에서 진행합니다. `main`의 버전을 갱신하고 잠금 파일을 반영한 뒤 실행하면 테스트·빌드를 거쳐 `pypi` 환경의 Trusted Publishing으로 게시합니다. 이미 게시한 버전은 덮어쓰지 않습니다.

### 변경 이력

- **0.1.1** — 사용자·교육생 안내서 확장: 설치, 클라이언트 설정, 단계별 실습, 입력·응답 명세, Python·LangChain 예제, 문제 해결. 서버 도구의 동작은 0.1.0과 동일합니다.
- **0.1.0** — 아파트 매매·분양권 전매 MCP 도구, 페이지 정보, 환경변수 인증, 초기 PyPI 배포.

### 데이터 출처와 라이선스

- [국토교통부 아파트 매매 실거래가 API](https://www.data.go.kr/data/15126469/openapi.do)
- [국토교통부 아파트 분양권전매 실거래가 API](https://www.data.go.kr/data/15126471/openapi.do)
- 코드: MIT License, Copyright (c) 2026 jaypakdevkr.
- 데이터의 제공 범위·이용 조건은 각 원천 API의 안내를 따릅니다.
