Skip to main content
Glama
README.md
# ALIO 공공기관 내규 검색 MCP

공공기관 경영정보 공개시스템(ALIO, alio.go.kr)에 공개된 공공기관 355곳의 **내부규정(사규)** 을 Claude 같은 AI 도구에서 찾아 읽고 비교하는 MCP 서버입니다.

- 규정을 제목과 **본문(조문)** 으로 검색하고, 전문을 조문 단위로 읽습니다.
- 모든 결과에 「공공기관의 혁신에 관한 지침」 기준 개정일을 붙이고, 새 개정이 있으면 알려 줍니다.
- 검토 결과를 보고서 양식의 **한글(HWPX) 문서**로 저장합니다.
- API 키는 필요 없습니다.

## 설치

### Claude 데스크톱 앱 (권장, Windows·macOS)

1. [최신 릴리스](https://github.com/chromehearts79/alio-mcp/releases/latest)에서 `alio-mcp-<버전>.mcpb` 파일을 받습니다.
2. 받은 파일을 더블클릭하거나 Claude 앱 **설정 → 확장 프로그램** 화면에 끌어다 놓고 **설치**를 누릅니다.
3. (선택) 설치 화면에서 **저장 폴더**를 고릅니다. 비워 두면 `문서/alio-mcp` 에 저장합니다.

Node.js는 따로 설치할 필요가 없습니다(Claude 앱에 들어 있음).

### 다른 MCP 클라이언트 (Claude Code, Cursor 등)

Node.js 20 이상이 필요합니다. 먼저 내려받아 설치합니다.

```bash
git clone https://github.com/chromehearts79/alio-mcp.git
cd alio-mcp && npm install --omit=optional
```

`--omit=optional` 은 OCR·이미지 처리용 선택 패키지(수백 MB)를 받지 않게 합니다. 이 도구에는 필요 없습니다.

클라이언트의 MCP 설정에 추가하세요. `<경로>` 는 내려받은 위치입니다.

```json
{
  "mcpServers": {
    "alio": {
      "command": "node",
      "args": ["<경로>/alio-mcp/src/server.js"]
    }
  }
}
```

Claude Code에서는 명령 한 줄로 추가할 수 있습니다.

```bash
claude mcp add alio -- node <경로>/alio-mcp/src/server.js
```

## 사용 예

- "한국인터넷진흥원 경영혁신 규정에서 위원회 구성 조항 보여줘"
- "공기업 복무규정 중 유연근무를 규정한 곳 찾아줘"
- "우리 기관 혁신 규정을 현행 지침과 다른 기관 규정에 비추어 검토하고 개정안을 한글 파일로 만들어줘"

프롬프트 `review_rule`(기관명·규정 키워드)을 고르면 아래 검토 절차가 자동으로 적용됩니다.

## 도구

| 도구 | 설명 |
|---|---|
| `alio_list_orgs` | 공공기관 355곳 목록/필터 |
| `alio_search_rules` | 제목 키워드로 규정 검색 (기관명·기관 유형·주무부처 필터) |
| `alio_read_rule` | 규정 하나의 현행본 본문을 조문 단위로 읽기 — 목차 / 조문 지정(`제16조의2`, `부칙`, `별표 3`) / 본문 검색어 |
| `alio_search_text` | 여러 기관 규정의 **본문(조문)** 검색 — 예: 제목 '복무' 규정들에서 '유연근무\|시차출퇴근' |
| `alio_get_rule_files` | 규정 첨부(제정·개정 이력) fileNo 목록 |
| `alio_download_rule` | 현행본(가장 나중에 등록된 첨부) 파일 저장 |
| `alio_guideline` | 「공공기관의 혁신에 관한 지침」 최신성 확인 + 조문별 변경점(지난 확인 이후 / 기준일 이후 / 직전 개정 대비), 현행 조문 읽기 |
| `alio_write_hwpx` | 마크다운을 한글(HWPX) 보고서로 저장 — 신구조문 대비표 지원 |

### 기준 지침 최신성 확인 (기본 동작)
- **모든 도구 결과 맨 위**에 `📌 기준 지침: …(개정일) (ALIO 게시일, 최신성 확인일)`을 붙인다. 지난 확인 이후 새 개정이 게시됐거나 아직 확인한 적이 없으면 `⚠️`로 알리고 `alio_guideline` 호출을 요구한다. 확인에 실패하면 실패했다고 표시한다(5초 제한, 6시간 캐시).
- 출처는 ALIO '공공기관 법령/지침' 게시판(재정경제부 게시)이다. 한국공공기관연구원 자료실도 ALIO를 출처로 재게시하지만 빠진 개정본이 있어(13건 중 9건) 공식 게시판을 쓴다.
- `alio_guideline`은 개정본 첨부를 받아 조문으로 나눈 뒤 비교한다. 정부조직 개편에 따른 명칭 변경(기획재정부→재정경제부)만 있는 조문은 '명칭만 변경'으로 따로 세어 실질 개정이 묻히지 않게 한다. `since`에 검토 대상 규정의 시행일을 주면 그 규정이 만들어진 뒤 달라진 점을 보여준다.
- **검토 기본 프레임**은 MCP 서버 안내문(instructions)과 프롬프트 `review_rule`에 들어 있다: 0 기준 최신성 → 1 자사 규정 → 2 기준 대조 → 3 비교군 → 4 조문 비교 → 5 개정안(필수/권고 구분, 근거·기준 개정일 명시).

### 한글 문서 (`alio_write_hwpx`)
[kordoc](https://www.npmjs.com/package/kordoc)의 보고서 양식으로 만든 뒤 아래 서식을 입힌다.

| 항목 | 기준 |
|---|---|
| 글꼴 | 함초롬바탕. ※(당구장 표시)·별첨으로 시작하는 문단은 함초롬돋움 |
| 크기 | 본문 15pt, 표(2행·2열 이상) 안 12pt. 제목·요약·장 제목 상자는 양식 크기 유지 |
| 줄 나눔 | 한글 어절, 영어 단어 |
| 정렬 | 양쪽 정렬 (제목·표 머리행의 가운데 정렬은 유지) |
| 신구조문 대비표 | 머리행이 `현 행 \| 개 정 안 \| 사유·근거` 인 표는 열 너비 37:37:26, `**굵게**` 표시한 바뀐 부분은 밑줄 |

- 표 행 높이는 바뀐 글자 크기로 다시 계산해 글자가 잘리지 않게 한다.
- 같은 이름의 파일이 있으면 덮어쓰지 않고 `(2)` 를 붙인다.
- HWPX 의 한글 줄 나눔 값은 이름과 동작이 반대다: `breakNonLatinWord="BREAK_WORD"` 가 어절, `KEEP_WORD` 가 글자 단위(한글 저장본 기준).

### 검색·응답 방식
- 검색 결과는 모든 페이지를 읽으며, 조회에 실패한 기관은 결과에서 조용히 빠지지 않고 "조회 실패 N곳"으로 따로 표시된다.
- **응답 시간:** MCP 클라이언트는 기본 60초 안에 응답이 없으면 요청을 끊는다. 기관 355곳을 순차 조회하면 약 82초가 걸리므로 동시에 4곳씩 조회한다(전 기관 약 20초). 도구마다 40초 시간 예산을 두고, 넘기면 처리한 만큼 돌려주면서 못 한 기관·규정을 "⏱️ 시간 제한으로 처리하지 못함"으로 명시한다. 같은 요청을 다시 실행하면 캐시로 이어서 처리한다.
- **캐시:** 기관 목록 6시간·제목 검색 10분(메모리), 본문 추출 결과(파일번호별)·첨부 목록(최종 수정일·시행일이 같으면 재사용, 7일마다 재확인)은 디스크. ALIO 규정 상세 페이지가 건당 약 1.5초로 가장 느려서, 한 번 읽은 규정은 다시 열지 않는다(재검색 27초 → 1초).
- **취소·오류:** 클라이언트가 요청을 취소하면 진행 중인 조회를 멈춘다. 실패하면 종류(`NETWORK`·`SCHEMA`·`PARSE` 등)와 다음 조치를 함께 알려 준다. 응답은 10만 자에서 자른다.
- **파일 저장:** 같은 이름이 있으면 번호를 붙이고, 저장 자리에 링크(바로가기)가 있으면 따라가지 않는다. 내려받은 원문은 임시 파일에 쓴 뒤 바꿔 넣어 중간에 끊겨도 기존 파일이 깨지지 않는다.
- stdout 은 MCP 통신 전용이라, 의존 라이브러리가 콘솔에 찍는 글은 stderr 로 돌린다.
- 같은 기관에 같은 이름으로 여러 건 올라온 규정(옛 버전을 따로 등록한 경우)은 시행일이 가장 늦은 것만 최신으로 보고 나머지는 `⚠️옛 버전 추정`으로 표시한다. 본문 검색은 기본으로 최신본만 읽는다(`includeOld`로 포함).

### 본문 검색 (`alio_read_rule`, `alio_search_text`)
- 첨부의 현행본(HWP·HWPX·PDF·DOCX, ZIP 묶음 포함)을 kordoc으로 텍스트 추출한 뒤 조문·부칙·별표(별지)로 나눈다. 조문 구조가 없는 안내서형 지침은 Ⅰ·Ⅱ 같은 제목 단위 구간으로 나눈다.
- 검색어: 공백 = 모두 포함, `|` = 둘 중 하나, 띄어쓰기 차이는 무시("직장내괴롭힘" ↔ "직장 내 괴롭힘").
- 추출 결과는 캐시 폴더에 파일번호별로 저장된다. 새 개정본이 올라오면 파일번호가 바뀌어 자동으로 다시 읽는다.
- ZIP 첨부 안에 개정 이력 전 버전이 들어 있는 경우가 있어(예: 13개 버전), ZIP 이름과 같은 문서 → 파일명 날짜가 가장 늦은 문서 순으로 하나만 고른다. 특정할 수 없으면 추측하지 않고 실패로 알린다.
- **한계:** 2단 편집 PDF나 전체가 표로 추출되는 PDF는 조문 경계를 되살리지 못한다. 이때도 글자는 검색되며, 조문 번호가 빠진 문서에는 "조문 번호 누락" 경고가 붙는다. 스캔 이미지 PDF는 본문을 추출할 수 없다고 알린다.
- 실제 규정 105건(복무 45·보수 30·윤리 30) 점검 결과 101건이 조문 번호 누락 없이 분할되었고, 나머지 4건은 모두 경고가 표시되었다(1건은 원문에 해당 조문이 실제로 없음).

## 저장 위치·환경변수

| 변수 | 기본값 | 내용 |
|---|---|---|
| `ALIO_OUTPUT_DIR` | `문서/alio-mcp` | 만든 한글 문서. 내려받은 원문은 그 아래 `downloads` |
| `ALIO_CACHE_DIR` | Windows `%LOCALAPPDATA%\alio-mcp\cache`, macOS `~/Library/Caches/alio-mcp`, Linux `~/.cache/alio-mcp` | 본문 추출·지침·첨부 목록 캐시 (지워도 다시 받음) |
| `ALIO_CONCURRENCY` | 4 | 동시 조회 수 |
| `ALIO_TOOL_BUDGET_MS` | 40000 | 도구 시간 예산 |
| `ALIO_DELAY_MS` | 60 | 요청 간 대기 |

## 개발

```bash
git clone https://github.com/chromehearts79/alio-mcp.git && cd alio-mcp && npm install
npm test                     # 오프라인: test/fixtures 의 실제 응답으로 검증 (네트워크 불필요)
npm run test:live            # 실서버 점검: ALIO 사이트 구조가 바뀌었는지 확인
node test/e2e-smoke.mjs      # 빈 홈 폴더에서 서버를 띄워 모든 도구를 실제로 호출
npm run bench                # 실제 내규 106건 조문 분할 회귀 벤치(ALIO 응답 구조 변화도 감지)
npm run fixtures             # 사이트 구조가 바뀐 뒤 테스트용 실제 응답을 다시 저장
npm run bundle               # Claude 데스크톱 확장 dist/alio-mcp-<버전>.mcpb 생성
npm run check -- --bundle    # 출시 전 검사(버전·CHANGELOG·패키지 파일·번들 구성)
npm run smoke                # 번들을 풀어 빈 홈 폴더에서 실행(--live 로 ALIO 실호출까지)
```

`npm run bundle` 은 실행에 필요한 파일과 의존성만 모아(선택 의존성 제외, 약 13MB) 묶는다.

**출시:** 바뀐 점을 `CHANGELOG.md` 의 `[Unreleased]` 에 적고 `npm version patch`(또는 `minor`) → `git push --follow-tags`. 태그가 올라가면 GitHub Actions 가 테스트·검사·번들 점검을 거쳐 릴리스에 `.mcpb` 를 게시한다. CI 는 Windows·macOS·Linux × Node 20·22 에서 돌고, 매주 월요일 ALIO 실서버 점검과 벤치를 돌린다. 개발 규칙은 [CLAUDE.md](CLAUDE.md).

오류 종류: `HTTP`(재시도 불가 상태코드) / `NETWORK`(429·5xx·연결 실패를 재시도한 뒤에도 실패) / `SCHEMA`(응답 구조가 예상과 다름 — 사이트 개편·차단 의심) / `NO_FILE`(첨부 없음) / `PARSE`(본문 추출 실패·스캔 PDF·ZIP 안 현행본 특정 불가).

### 정기 점검 — 스윕/변경감지 스크립트
전 기관을 키워드로 훑어 스냅샷을 저장하고, **직전 대비 신설·개정·폐지**를 리포트한다.

```bash
node src/sweep.js --keyword 혁신
```
- 첫 실행: `snapshots/snap_혁신_YYYY-MM-DD.json` 저장 (기준선)
- 이후 실행: 직전 스냅샷과 비교해 🆕신설 / ✏️개정(시행일·명칭 변경) / 🗑️폐지 리포트
- 규정은 고유번호(idx)로 대조하므로 명칭만 바뀐 규정은 개정으로 잡힌다.
- 조회에 실패한 기관의 규정은 신설·폐지 판정에서 제외하고 따로 알린다.

정기 자동화는 cron/스케줄러로 이 명령을 주기 실행(예: 분기 1회).

### API 계약 (리버스 엔지니어링)
```
기관목록  POST /item/itemOrganListSusi.json  {apbaType:[],jidtDptm:[],area:[],apbaId:"",reportFormRootNo:"21110"}
규정검색  POST /item/itemReportListSusi.json  {pageNo,apbaId,apbaType,reportFormRootNo:"21110",search_word,search_flag:"title",bid_type,enfc_istt:""}
상세→fileNo GET /item/itemBoard21110.do?apbaId&table_name=COMM_RULE&idx_name=RULE_NO&idx&reportGbn=N&bid_type
파일다운   GET /download/rulefiledown.json?fileNo=<fileNo>
지침목록  GET /etc/findEtcLawList.json?type=title&word=&pageNo=
```
분류코드: K1100 인사·복무·징계 / K1200 보수 / K1300 직제 / K1400 기타 / K1500 정관

## ⚠️ 면책 및 이용 주의 (Disclaimer)

- 본 도구는 **ALIO(alio.go.kr) 운영기관 및 재정경제부와 무관한 비공식 프로젝트**입니다.
- ALIO의 **문서화되지 않은 내부 JSON 엔드포인트**를 사용하므로, 사이트 개편 시 예고 없이 동작이 중단될 수 있습니다.
- 조회 대상은 ALIO가 **공개하는 공공기관 경영정보(내부규정)**입니다. 도구는 데이터를 재배포하지 않고 **사용자 요청 시점에 각자의 PC에서 직접 조회**만 합니다.
- **ALIO 이용약관 준수는 사용자 책임**입니다. 과도한 요청을 삼가고, 정당한 연구·업무·벤치마크 목적으로만 사용하세요.
- 동시 조회는 기본 4곳, 요청 간격은 기본 60ms이며 `ALIO_CONCURRENCY`·`ALIO_DELAY_MS`로 조정합니다. 대량 수집은 야간 배치를 권장합니다.
- `robots.txt`는 전면 허용(`Allow: /`)이나, 서버 부하를 유발하지 않도록 정중히 호출하세요.
- 본문 추출은 kordoc 라이브러리로 로컬에서 처리하며, 추출 결과 캐시는 개인 PC에만 저장합니다.
- 도구가 만든 개정안·검토 결과는 AI가 작성한 초안입니다. 반드시 원문과 대조해 확인하세요.
- 라이선스: MIT (무보증, AS-IS).