ArchHub MCP
by chrisryugj
README.md
# 건축HUB MCP
**국토교통부 건축HUB 3개 API를 12개 도구로.** 건축물대장·건축인허가·주택인허가 + 법정동코드 조회 + **용도지역·정화조 포함 종합카드** + **필지 연혁 타임라인** + **가설건축물 존치 스캔** + **층별 구성** + **동 단위 통계·규모 벤치마크** + **노후건축물 분석** + **내진 취약 추정** + **공시가격 시계열** + **철거멸실(석면)** + **인허가 파이프라인**을 AI 어시스턴트에서 자연어로 바로.
[](CHANGELOG.md)
[](LICENSE)
[](https://www.python.org)
[](https://github.com/jlowin/fastmcp)
> 국가법령정보 MCP가 "법령"을, 통계 MCP가 "통계"를 다루듯, 이건 **건축물 실체 데이터**를 다룬다.
> 건축물대장 · 건축인허가 · 주택인허가 — data.go.kr 공식 API 실측값만, 출처를 명시하고, 없으면 `[NOT_FOUND]`로 환각을 차단.
remote 커넥터가 통합 호스트 `mcp.gomdori.app`에 떠 있어, 사용자는 **URL만 등록하면** 별도 설정 없이 바로 쓴다.
---
## 핵심 기능
주소 한 줄이면 `find_region`으로 코드를 얻고, 그다음은 목적에 맞는 도구 하나로 끝난다.
### 1. `building_profile` — 용도지역 포함 한 필지 종합카드
표제부와 지역지구구역을 호출해 **용도지역(법적 규제) + 주용도·구조·규모·건폐율/용적률·세대/주차·사용승인·내진·에너지효율**을 한 카드로 묶는다. 건축의 출발점인 "이 땅 무슨 지역이고, 지금 뭐가 얼마나 서 있나"를 1콜로. (건축사·시공·중개·감정평가)
```
"자양동 2-2번지 건물 정보 한눈에 보여줘"
→ building_profile(11215, 10500, bun=2, ji=2)
```
```
건축물 1개 동
용도지역·지구: 지구단위계획구역 · 일반상업지역
■ 건대입구역자이엘라
위치: 서울특별시 광진구 능동로 87 (자양동)
용도: 업무시설 (기타: 업무시설(오피스텔),근린생활시설,문화및집회시설,공공업무시설) · 구조: 철골철근콘크리트합성구조
규모: 지상20/지하6층 · 높이 99.6m · 연면적 28,515.35㎡ · 대지 2,288.50㎡
건폐율 59.9781% · 용적률 787.882%
세대: 0세대 0가구 366호
주차: 자주식 115대 · 기계식 120대
사용승인 2022-10-07 · 허가 2018-04-18 · 착공 2019-09-26
내진 1(Ⅶ-0.176g)
출처: 국토교통부 건축HUB (공공데이터포털 data.go.kr)
```
> 건폐율/용적률이 응답에 없으면 면적으로 직접 계산해 `(계산)` 표시 — 추정과 실측을 구분한다.
> 용도지역·정화조(형식·용량 — 용도변경 시 오수발생량 검토의 출발점) 정보가 없는 필지는 해당 줄을 조용히 생략한다.
### 1-1. `parcel_history` — 필지 연혁 타임라인 ★NEW
건축인허가 기본개요 + 철거멸실관리대장 + 가설건축물을 한 번에 받아 **"이 땅에 무슨 일이 있었나"를 오래된 순 타임라인**으로. 허가→착공→사용승인 진행, 철거(석면 ⚠), 가설건축물 존치까지. 민원 대응·이력 확인(공무원), 매입 실사(디벨로퍼·중개·감정평가)의 출발점.
```
"자양동 2-2번지 이 필지에 무슨 일 있었는지 연혁 정리해줘"
→ parcel_history(11215, 10500, bun=2, ji=2)
```
```
[필지 연혁] 2-2 · 인허가 + 철거멸실 + 가설건축물 (오래된 순)
■ 2018-04-18 허가 — 신축 · 업무시설 · 연면적 28,515.35㎡ · 366호 — 건대입구역자이엘라
착공 2019-09-26 → 사용승인 2022-10-07
■ 2019-03-01 철거멸실 — 철거 · 문화및집회시설 · 철골콘크리트구조 · 연면적 4,697.48㎡ (2019-03-01~2019-04-30)
■ 2019-07-10 허가 — 가설건축물 · 컨테이너조 · 연면적 171.00㎡ · 2개 동 · 존치만료 2022-08-20(경과)
■ 2023-11-30 허가 — 대수선 · 업무시설
사용승인 2023-12-01
■ 2024-10-18 허가 — 용도변경 · 업무시설 — 건대입구역자이엘라
...
※ 건축HUB 인허가·철거·가설건축물 대장 기준 — 등재 지연·누락 가능. 공부와 대조해 확정하세요.
```
> 옛 건물(건국웨딩타운) 철거 → 신축(자이엘라) → 대수선 → 용도변경까지 한 필지의 생애가 한 화면에 — 전부 자양동 2-2 실측 데이터다.
### 1-2. `temp_buildings` — 가설건축물 존치 스캔 ★NEW
가설건축물 대장을 받아 `가설건축물존치만료일` 기준 **만료 경과 / 만료임박(180일) / 유효 / 미상**을 집계하고 우선 점검 후보를 만료 경과 오래된 순으로 제시. **존치기간 연장 신고 관리는 건축행정의 반복 업무** — 동 단위 일괄 스캔으로 끝낸다. (건축직 공무원·시공 현장 가설사무소 관리)
```
"자양동 가설건축물 중에 존치기간 만료된 것들 점검 목록 뽑아줘"
→ temp_buildings(11215, 10500)
```
### 2. `building_floors` — 층별 구성 스택
층별개요를 호출해 **옥탑→지상→지하 순으로 각 층의 용도·면적**을 쌓아 보여준다. 한 층에 여러 용도가 있으면 합산해 나열. 리모델링·용도변경·임대구성·피난/소방 검토에. (건축사·시공·중개)
```
"자양동 2-2번지 층별로 뭐가 있는지 보여줘"
→ building_floors(11215, 10500, bun=2, ji=2)
```
```
■ 층별 구성 — 건대입구역자이엘라
총 27개 층 (행 31건)
옥탑 73㎡ 오피스텔 73㎡
20층 732㎡ 오피스텔 732㎡
...
6층 1,242㎡ 예식장 1,242㎡
5층 1,242㎡ 일반음식점 1,242㎡
3층 1,890㎡ 기타공공업무시설 1,799㎡ · 놀이형시설 91㎡
1층 1,229㎡ 일반음식점 1,060㎡ · 오피스텔 169㎡
지하1층 1,481㎡ 일반음식점 1,481㎡
지하6층 1,812㎡ 오피스텔 1,812㎡
출처: 국토교통부 건축HUB (공공데이터포털 data.go.kr)
```
### 3. `district_stats` — 동 단위 건축물 통계
개별 건물이 아니라 **동 전체의 그림**이 필요할 때. 표제부 전체를 받아 총괄·주용도별·연대별·노후도 분포를 한 번에 집계한다. (도시계획·정비사업·지역분석)
```
"자양동 건축물 통계 내줘"
→ district_stats(11215, 10500)
```
```
[법정동 건축물 통계] 표제부 6057건 기준
■ 총괄
총 6,057동 · 총 연면적 5,283,211㎡ · 평균 3.5층 · 평균 경과 32년
■ 주용도별 (상위 10)
단독주택 3,543동 (58.5%) · 연면적 841,139㎡
공동주택 1,346동 (22.2%) · 연면적 2,726,331㎡
제1종근린생활시설 532동 ( 8.8%) · 연면적 280,975㎡
...
■ 사용승인 연대별
1970s 814동 (13.4%)
1980s 1,376동 (22.7%)
1990s 2,094동 (34.6%)
...
■ 노후도 분포 (사용승인 경과연수)
30~40년 2,563동 (42.3%) ⚠
40년 이상 1,551동 (25.6%) ⚠
→ 경과 30년↑ 합계 4,114동 (67.9%)
출처: 국토교통부 건축HUB (공공데이터포털 data.go.kr)
```
### 4. `old_buildings` — 노후건축물 선별
동 전체 표제부에서 사용승인 경과연수를 계산해 노후 건물을 내림차순 정렬. **안전점검·정비사업 대상 1차 선별**에 바로 쓴다.
```
"자양동에서 40년 넘은 노후 건물 뽑아줘"
→ old_buildings(11215, 10500, min_age_years=40)
```
```
총 1551건 중 상위 30건 표시
표제부 6057건 중 경과 40년↑ 1551건 (경과연수 내림차순)
건물명 도로명대지위치 대지위치 주용도코드명 사용승인일 경과연수 연면적 지상층수 세대수
서울특별시 광진구 자양동 268번지 단독주택 1924-07-20 102 16.53 1 0
서울특별시 광진구 자양동 203번지 단독주택 1926-08-20 100 59.50 1 0
...
```
### 5. `price_history` — 공시가격 시계열
주택가격(공시가격)을 호별로 묶어 **연도별 추이·총증감률·연평균상승률(CAGR)**을 낸다. 한 필지의 호(전유부)마다 17년치 공시가가 쌓여 있다. 감정평가·자산분석·중개에. (공개 API값, 소유자 정보 없음)
> **공시가격은 시세가 아니다** — 통상 시세의 60~70% 수준이고 연도별 현실화율 정책 변동을 포함한다. 증감률·CAGR을 실거래가 상승률로 해석하면 안 된다(출력 말미에 경고를 명시).
```
"자양동 24-28번지 공시가격 추이 보여줘"
→ price_history(11215, 10500, bun=24, ji=28)
```
```
[공시가격 시계열] 24-28 · 주택가격 238건 · 14호
최신 공시가 상위 10호 표시 (top_units로 조정)
■ 호 PK…0216 · 새주소 22
최신 4.65억 (2025) · 최초 2.45억 (2009) · 16년간 +89.8% · 연평균 +4.1%
추이: '09 2.45억 → '12 2.64억 → '15 2.64억 → '19 3.44억 → '22 4.54억 → '25 4.65억
※ 공시가격은 시세가 아닙니다(통상 시세의 60~70% 수준, 연도별 현실화율 정책 변동 포함). 증감률·CAGR을 시세·실거래가 상승률로 해석하지 마세요.
출처: 국토교통부 건축HUB (공공데이터포털 data.go.kr)
```
### 6. `demolitions` — 철거멸실 현황 (석면 포함)
철거멸실관리대장을 **최근 철거순**으로, 연면적·용도·구조 + **석면 함유 부위**(천장/단열/지붕/보온/바닥/기타)를 `⚠`로 요약. 석면은 철거 안전·비용에 직결된다. 개발·멸실 신호 파악에. (디벨로퍼·철거업체·공무원)
```
"자양동 2018년 이후 철거된 건물 보여줘"
→ demolitions(11215, 10500, since_year=2018)
```
```
[철거멸실 현황] 철거멸실 1771건 중 2018년↑ 248건 (최근 철거순)
■ 서울특별시 광진구 자양동 680-63번지
철거 · 방송통신시설 · 철골콘크리트구조 · 연면적 34,995.78㎡ · 철거 2020-05-02~2020-10-31 ⚠석면(천장·단열·지붕·보온)
■ 서울특별시 광진구 자양동 680-22번지
철거 · 업무시설 · 철골콘크리트구조 · 연면적 21,558.33㎡ · 철거 2020-05-02~2020-10-31 ⚠석면(천장·보온)
...
```
### 7. `permits_pipeline` — 인허가 파이프라인
건축인허가 기본개요에서 **허가는 났으나 사용승인 전(진행중)** 건만 추려 허가일 최근순으로. 실제착공일 유무로 **착공/미착공** 단계를 구분해 신규 공급 파이프라인을 본다. (디벨로퍼·공무원)
```
"자양동 진행 중인 건축 인허가 보여줘"
→ permits_pipeline(11215, 10500, since_year=2024)
```
```
[인허가 파이프라인] 기본개요 5358건 중 진행중(사용승인 전) 1243건 · 허가 2024년↑
■ 서울특별시 광진구 자양동 613-24번지
신축 · 공동주택 · 연면적 419.12㎡ 12세대 · 허가 2026-04-27 · 단계: 미착공
■ 서울특별시 광진구 자양동 854번지
발코니구조변경 · 공동주택 · 연면적 52,666.24㎡ 204세대 · 허가 2026-04-22 · 단계: 미착공
...
```
> `district_stats`는 **규모 벤치마크**(주용도별 층수·용적률·높이 중앙값)도 함께 집계한다 — "이 동네 공동주택은 보통 몇 층, 용적률 얼마"를 설계 단계에서 바로 참고. (건축사)
---
## 왜 만들었나
대한민국 모든 건물에는 **건축물대장**이 있다. 용도·구조·규모·사용승인일·건폐율·용적률·주차·내진까지 — 부동산 중개, 감정평가, 시공, 디벨로핑, 도시계획, 안전점검의 출발점이 전부 여기다. 이 데이터는 [건축HUB](https://cloud.eais.go.kr)와 [공공데이터포털](https://www.data.go.kr)에 공개돼 있지만, API는 영문 코드 컬럼·페이지네이션·인증키 등록으로 개발자조차 진입장벽이 높다.
이 프로젝트는 그 건축 데이터 시스템을 **12개 도구**로 감싸서, AI 어시스턴트나 스크립트에서 바로 호출할 수 있게 만든다. 코드 한 줄 모르는 실무자도 "자양동 노후건물 뽑아줘"라고 말하면 끝.
---
## 빠른 시작 (remote 커넥터)
원격 서버가 떠 있어 **별도 발급·설정 없이** URL만 등록하면 된다.
> **주소 안내** — 공식 주소는 `https://mcp.gomdori.app/archhub` 다.
> 구 주소 `https://archhub-mcp.fly.dev/mcp` 는 통합 호스트로 이전을 마치고 **운영 종료**했다.
> 구 주소로 등록해 둔 커넥터는 위 공식 주소로 바꿔 주면 된다(설정 변경 외 추가 작업 없음).
### Claude.ai 웹 (설치 없음)
설정 → **커넥터** → **커스텀 커넥터 추가** → URL에 입력:
```
https://mcp.gomdori.app/archhub
```
추가 후 **구성 → 모든 도구 "항상 사용"**으로 설정하면, 채팅에서 "광진구 자양동 노후건물 알려줘"로 바로 사용.
### Claude Code
```bash
claude mcp add --transport http archhub https://mcp.gomdori.app/archhub
```
### Claude Desktop / Cursor / Windsurf
원격 HTTP를 지원하는 클라이언트는 설정 파일 `mcpServers`에 추가:
```json
{
"mcpServers": {
"archhub": { "type": "http", "url": "https://mcp.gomdori.app/archhub" }
}
}
```
Claude Desktop은 원격 HTTP를 직접 못 붙이므로 `mcp-remote` 어댑터 경유 (Node.js 18+):
```json
{
"mcpServers": {
"archhub": { "command": "npx", "args": ["-y", "mcp-remote", "https://mcp.gomdori.app/archhub"] }
}
}
```
---
## 사용 예시
```
"광진구 자양동 법정동코드 알려줘"
→ find_region → sigungu=11215, bdong=10500
"자양동 1-1번지 건물 한눈에 보여줘" → building_profile # 종합카드
"자양동 건축물 통계 내줘" → district_stats # 동 단위 집계
"자양동 40년 넘은 노후 건물 뽑아줘" → old_buildings # 노후 선별
"자양동 1-1번지 표제부 원본 보여줘" → building_data(ledger, 표제부) # 원천 데이터
```
> 주소는 먼저 `find_region`으로 `sigungu_code`/`bdong_code`를 얻은 뒤 다른 도구에 넘긴다. 큰 동은 번지(`bun`/`ji`) 지정 시 빠르다.
---
## 도구 (12개)
| 도구 | 설명 |
|------|------|
| `find_region` | 주소 키워드("광진구 자양동 680-63") → `sigungu_code`/`bdong_code` + 번지 자동 분리(`bun`/`ji`) |
| `building_profile` | **용도지역·정화조 포함 종합카드** — 용도지역·주용도·구조·규모·건폐율/용적률·세대·주차·사용승인·내진·에너지·정화조 (건축·시공·중개·평가) |
| `parcel_history` | **필지 연혁 타임라인** ★ — 인허가(허가→착공→승인) + 철거(석면) + 가설건축물을 오래된 순으로 (민원 대응·매입 실사) |
| `temp_buildings` | **가설건축물 존치 스캔** ★ — 존치만료 경과/임박(180일)/유효/미상 분류 + 우선 점검 후보 (건축행정 공무원) |
| `building_floors` | **층별 구성 스택** — 옥탑→지상→지하 각 층 용도·면적 (리모델링·용도변경·임대구성) |
| `price_history` | **공시가격 시계열** — 호별 연도별 추이·총증감률·연평균상승률(CAGR) (감정평가·자산분석) |
| `district_stats` | **동 단위 통계 + 규모 벤치마크** — 총괄·주용도별·연대별·노후도 분포 + 주용도별 층수·용적률·높이 중앙값 (도시계획·정비사업·건축사) |
| `old_buildings` | **노후건축물 분석** — 사용승인 경과연수 기준 정렬 (안전점검·정비사업 선별) |
| `seismic_check` | **내진 취약 추정 스캔** — 내진 의무화 연혁(1988→2017.12) 기준 미적용 추정 분류 + 취약구조 우선 (안전점검) |
| `demolitions` | **철거멸실 현황** — 최근 철거순 + 석면 함유 부위 ⚠ (디벨로퍼·철거업체·공무원) |
| `permits_pipeline` | **인허가 파이프라인** — 사용승인 전 진행중 건, 착공/미착공 단계 (디벨로퍼·공무원) |
| `building_data` | 원천 데이터 직접 조회(고급) — `kind=ledger`(건축물대장 10종) / `permit`(건축인허가 17종) / `housing`(주택인허가 16종) |
> v0.4.0에서 raw 3종(`building_ledger`/`building_permit`/`housing_permit`)을 `building_data` 하나로 통합했다 — 파라미터가 동일하고 대장 종류만 달라, 도구 수를 줄여 LLM의 도구 선택 혼란과 스키마 토큰을 같이 줄였다. 원본 표 출력은 빈 컬럼·코드/코드명 중복·조회인자 에코를 자동 생략(생략 수 명시)해 토큰을 아낀다.
모든 응답은 공식 API 실측값이며 **출처를 명시**한다. 결과가 없으면 `[NOT_FOUND]`, 에러는 `[EXTERNAL_API_ERROR]` 등 머신 파싱 프리픽스 + "LLM은 추측 금지" 경고로 환각을 차단한다.
---
## 누가 쓰나
| 페르소나 | 주력 도구 | 시나리오 |
|---|---|---|
| **건축직 공무원·공공기관** | `parcel_history` · `temp_buildings` · `district_stats` · `old_buildings` · `seismic_check` · `demolitions` · `permits_pipeline` | 민원 필지 연혁 확인, 가설건축물 존치 관리, 동 단위 노후도·내진 집계, 정비·안전점검 대상 선별 |
| **건축사·시공** | `building_profile` · `building_floors` · `district_stats` · `parcel_history` | 용도지역·규모 규제·정화조, 층별 구성, 동네 규모 벤치마크, 필지 인허가 이력 |
| **디벨로퍼** | `parcel_history` · `district_stats` · `old_buildings` · `demolitions` · `permits_pipeline` | 필지 실사, 노후 분포·철거·진행중 인허가로 사업성·공급 스크리닝 |
| **중개** | `building_profile` · `building_floors` · `price_history` · `parcel_history` | 매물 종합카드 + 층별 임대구성 + 공시가 추이 + 매물 이력 |
| **감정평가** | `building_profile` · `price_history` · `parcel_history` · `building_data` | 용도지역·면적·승인일·주차 + 공시가격 시계열 + 원천 대장 |
### 바로 쓰는 프롬프트 (복사 → 지역/번지만 바꾸기)
**처음이라면 이것만 기억하면 된다:**
1. **그냥 말하면 된다.** 코드도, 메뉴도, API 키도 없다. 커넥터만 등록돼 있으면 채팅창에 "자양동 2-2번지 건물 정보 보여줘"라고 치는 게 전부다.
2. **주소는 "동 이름 + 번지"면 충분하다.** "광진구 자양동 680-63"처럼 쓰면 AI가 알아서 지역코드를 찾고 번지를 분리해 조회한다. 번지를 몰라도 동 이름만으로 동 전체 통계를 낼 수 있다.
3. **목적을 말하면 도구는 AI가 고른다.** "정비사업 검토용이야", "손님한테 보여줄 거야"처럼 용도를 덧붙이면 결과 정리가 더 좋아진다.
4. **없는 데이터는 없다고 답한다.** 모든 숫자는 국토교통부 건축HUB 공식 API 실측값이고 출처가 붙는다. 조회 결과가 없으면 지어내지 않고 `[NOT_FOUND]`로 알려준다.
아래는 전부 자양동(광진구) 실제 데이터로 동작 확인된 예시다. **"자양동"을 우리 동네로, 번지를 실제 번지로 바꾸면 그대로 작동**한다. (`→`는 내부적으로 호출되는 도구)
**🏛️ 건축직 공무원 — 민원·점검·현황 실전 쿼리**
```
자양동 2-2번지 이 필지에 무슨 일 있었는지 연혁 정리해줘 (민원 대응용) → parcel_history
자양동 가설건축물 중 존치기간 만료된 것들 점검 목록 뽑아줘 → temp_buildings
자양동 내진설계 안 됐을 것으로 추정되는 3층 이상 건물 뽑아줘 → seismic_check
광진구 자양동 건축물 노후도랑 용도 구성 통계로 정리해줘 → district_stats
자양동에서 40년 넘은 노후 건물 30개 뽑아줘, 정비사업 검토용이야 → old_buildings
자양동 2018년 이후 철거된 건물 석면 포함해서 보여줘 → demolitions
자양동 지금 진행 중인 건축 인허가 현황 보여줘 → permits_pipeline
자양동 2-2번지 정화조 형식이랑 용량 알려줘 (용도변경 검토용) → building_profile
```
**🏗️ 건축사·시공 — 대지 규제·건물 스펙·규모 벤치마크**
```
자양동 2-2번지 용도지역이랑 건폐율·용적률 현황 한눈에 보여줘 → building_profile
자양동 2-2번지 층별로 무슨 용도가 몇 ㎡씩 있는지 보여줘 → building_floors
자양동 공동주택은 보통 몇 층에 용적률 얼마로 짓나 벤치마크 줘 → district_stats(규모 벤치마크)
```
**💰 디벨로퍼 — 지역 스크리닝·철거·공급 파이프라인**
```
자양동 용도별 건물 구성이랑 노후 분포로 사업성 훑어줘 → district_stats
자양동에서 30년 넘은 단독주택 노후 필지 리스트업해줘 → old_buildings
자양동 최근 철거된 필지들 멸실 현황 보여줘 → demolitions
자양동 허가는 났는데 아직 사용승인 전인 신규 공급 건 보여줘 → permits_pipeline
```
**🤝 중개 — 매물 스펙 카드 + 층별 임대구성 + 시세**
```
자양동 2-2번지 건물 스펙 카드로 정리해줘, 손님한테 보여줄거야 → building_profile
자양동 2-2번지 층마다 무슨 업종이 들어와 있어? → building_floors
자양동 24-28번지 공시가격 최근 몇 년 추이 보여줘 → price_history
```
**📊 감정평가 — 공시가격 시계열·물건 명세**
```
자양동 24-28번지 호별 공시가격 연도별 추이랑 상승률 뽑아줘 → price_history
자양동 4-2번지 리버그린 연면적·대지면적·사용승인일 정리해줘 → building_profile
자양동 5-13번지 총괄표제부 원본 보여줘 → building_data(ledger, 총괄표제부)
```
> 번지를 모르면 그냥 동만 말해도 된다 — 단, 큰 동은 수천 건이라 번지를 지정하면 빠르다.
> 주소만 주면 AI가 먼저 `find_region`으로 코드를 찾은 뒤 알아서 도구를 고른다.
---
## 로컬 실행 (stdio)
원격 서버를 거치지 않고 직접 돌리려면 [data.go.kr 인증키](https://www.data.go.kr)가 필요하다 (건축HUB 서비스 활용신청 → 일반 인증키 Decoding).
```bash
git clone https://github.com/chrisryugj/archhub-mcp && cd archhub-mcp
pip install -e . # console_scripts 진입점 설치
export ARCHHUB_SERVICE_KEY="<디코딩 인증키>" # Windows: set 또는 .env.local
archhub-mcp # stdio 모드 (= python -m archhub)
archhub-mcp --transport http --port 8000 # http 모드
```
또는 설치 없이 `uvx`로:
```bash
ARCHHUB_SERVICE_KEY=... uvx --from . archhub-mcp
```
Claude Code 로컬 등록:
```bash
claude mcp add archhub -e ARCHHUB_SERVICE_KEY=<디코딩 키> -- archhub-mcp
```
`.env.local`에 키를 넣어두면 편하다 (`.env.example` 참고, git 커밋 제외됨).
---
## 테스트 · 개발
```bash
pip install -e ".[dev]" # 먼저 설치(안 하면 bare `pytest`는 ModuleNotFoundError)
pytest tests/ # 외부 API 비의존(네트워크 mock) · 115 케이스
# Docker 와 같은 고정 조합으로 재현하려면: pip install -r requirements.txt && pip install --no-deps PublicDataReader==1.1.1.post2
# (PublicDataReader 가 취약한 requests==2.32.3 을 하드핀해서 --no-deps 로 우회, 사유는 requirements.txt 머리말)
```
변경 이력은 [CHANGELOG.md](CHANGELOG.md) 참고.
응답파싱·키마스킹·카드 계산식·`fetch_all` 페이지·행 상한 절단·동단위 집계·키 만료 계산,
그리고 코드 입력검증·일일 호출 캡·http→https 승격·만 경과연수 계산을 회귀로 막는다.
---
## 배포
프로덕션 서빙은 **통합 호스트 `gomdori-mcp`**(fly 머신 1대에 MCP 5종 동거, 비공개 레포)가 맡는다. 이 레포는 PyPI 미배포라, 통합 호스트가 GitHub main을 **커밋 SHA로 고정**해 `pip install`한다.
```bash
# 1) 이 레포 main에 커밋·푸시
# 2) 통합 호스트 Dockerfile의 핀(pip install git+...@<sha>)을 갱신하고 배포
cd ../gomdori-mcp && fly deploy -c fly.production.toml
curl https://mcp.gomdori.app/healthz # 5종 프로세스 상태
curl https://mcp.gomdori.app/archhub/health # 버전·키 만료 D-day·호출수
```
> 핀 SHA를 안 바꾸면 푸시해도 옛 코드가 그대로 서빙된다(Docker 레이어 캐시).
직접 띄우려면 저장소의 `fly.toml`로 단독 앱을 만들 수도 있다:
```bash
fly launch --no-deploy # fly.toml 인식
fly secrets set ARCHHUB_SERVICE_KEY="<디코딩 키>" # 인증키 주입 (평문 커밋 금지)
fly secrets set ARCHHUB_DAILY_CALL_CAP=9000 # (선택) 일일 호출 상한 — 초과 시 차단
fly deploy
fly scale count 1 # 일일 호출 캡 카운터가 프로세스 로컬 → 단일 머신
```
http 전송은 **stateless**라 `Mcp-Session-Id` 없이 붙는 클라이언트도 그대로 동작한다(대신 GET `/mcp` SSE 스트림은 막히고 POST/DELETE만 허용 — 조회 전용 서버라 영향 없음). 다만 일일 호출 캡 카운터가 프로세스 메모리에 있어 **단일 머신으로 운영**한다. `/health`는 버전·키 적재 여부·**만료 D-day**·오늘/누적 호출수·일일 상한을 노출한다.
> **버전 표기 주의** — 이 패키지의 버전은 `/health`의 `version`(= `0.4.0`)이다. MCP `initialize` 응답의 `serverInfo.version`은 생성자에 `version=`을 주지 않아 **FastMCP 라이브러리 버전**이 그대로 나오므로, 둘이 달라 보여도 정상이다.
---
## 데이터 출처 · 범위
- **출처**: 국토교통부 건축HUB (공공데이터포털 data.go.kr)
- 건축물대장 `1613000/BldRgstHubService`
- 건축인허가 `1613000/ArchPmsHubService`
- 주택인허가 `1613000/HsPmsHubService`
- 영문 컬럼은 한글로 자동 변환 (PublicDataReader 매핑 재활용)
- 법정동코드 테이블은 런타임에 로드 후 캐시
- 동기 도구는 FastMCP가 워커 스레드풀로 위임 → http 동시요청에도 이벤트루프 비차단
## 한계 · 주의
- **트래픽 한도**: 단시간 대량 호출은 외부 API 정책상 제한될 수 있다. `/health`의 호출수(`api_calls`·`calls_today`)로 사용량을 관측하고, 필요하면 `ARCHHUB_DAILY_CALL_CAP`으로 일일 상한을 둔다.
- **위반건축물 조회 불가**: 표제부/기본개요/총괄표제부 어디에도 위반건축물 필드가 없음(실측 확인) → API로 조회 불가.
- **개인정보 제외**: 소유자(소유정보) 조회는 범위 밖.
- **동 전체 조회는 무거움**: 큰 동은 수천 건. `old_buildings`/`district_stats`/`demolitions`/`permits_pipeline`는 전체를 받아 다소 느릴 수 있다. 페이지당 100건 고정이라 1만 행까지 순회 수집하며, 초과분은 응답에 절단을 명시한다. `price_history`는 필지(`bun`) 단위라 가볍다.
---
## 라이선스
[MIT](LICENSE)
---
<sub>국토교통부 건축HUB 공개 데이터를 AI가 바로 읽도록 — Made by Chris</sub>
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessWithin a week