Skip to main content
Glama
choizeus02

chem-inventory-mcp

by choizeus02
README.md
# mcp_test — 시약 재고 MCP 서버 (chem-inventory)

MCP(Model Context Protocol) 표준 규격을 지킨 서버. SQLite에 mock 시약 데이터를 담고
검색·상세조회·재고차감·사용이력 기능을 제공한다. 통신 검증용 도구(ping/echo)도 유지.

## 구성

| 파일 | 역할 |
|------|------|
| `server.py` | MCP 서버. 통신 검증 도구 + 시약 재고 도구 9종, Resource 2종, Prompt 2종 |
| `db.py` | SQLite 스키마 생성 + mock 데이터 시딩(멱등) + 조회/차감 함수 |
| `test_client.py` | 테스트 클라이언트. 핸드셰이크부터 DB 쓰기·에러 처리까지 14개 항목 검증 |
| `chem.db` | SQLite 데이터 파일 (첫 실행 시 자동 생성·시딩, 삭제하면 초기화됨) |

## 기능 (Tools)

| 도구 | 설명 |
|------|------|
| `search_chemicals(keyword)` | 국문명/영문명/CAS 번호 부분 일치 검색 |
| `get_chemical(cas_no)` | GHS 유해성, 보관 위치, 재고 상세 조회 |
| `low_stock_report()` | 발주 기준 미달 시약 목록 (부족률 순) |
| `use_chemical(cas_no, amount, used_by)` | 재고 차감 + 사용 이력 기록. 재고 부족 시 에러 |
| `usage_history(cas_no?, limit)` | 최근 사용 이력 조회 |
| `ping` / `echo` / `add` / `get_server_info` | 통신 검증용 |

Resources: `chem://inventory` (전체 재고 현황판), `info://server`
Prompts: `safety_review(cas_no)` (안전 취급 검토 요청), `greeting`

Mock 데이터: 아세톤, 황산, 수산화나트륨, 메탄올, 염산, 톨루엔, 과산화수소 7종
(수산화나트륨·메탄올은 의도적으로 재고 부족 상태 → low_stock_report 테스트용)

## 요구사항

```
python -m pip install mcp --trusted-host pypi.org --trusted-host files.pythonhosted.org
```

주의: `pip` 단독 실행 시 다른 사용자 계정의 Python에 설치될 수 있으므로
반드시 `python -m pip` 사용.

## 실행

### 1. stdio 전송 (로컬, Claude Desktop 등)

```
python test_client.py          # server.py를 서브프로세스로 띄워 자동 테스트
```

### 2. Streamable HTTP 전송 (서버 간 네트워크 통신 테스트)

```
# 터미널 1 — 서버
python server.py --http --port 8765          # 로컬만: 127.0.0.1
python server.py --http --host 0.0.0.0       # 다른 서버에서 접속 허용

# 터미널 2 — 클라이언트 (다른 호스트라면 IP만 바꾸면 됨)
python test_client.py --url http://127.0.0.1:8765/mcp
```

## 테스트 항목 (14개)

1. `initialize` — MCP 핸드셰이크, 프로토콜 버전 협상
2. `tools/list` — 도구 9종 등록 확인
3~6. `ping` / `echo`(한글 무결성) / `add` / `get_server_info` — 통신 검증
7. `search_chemicals('산')` — 부분 일치 검색
8. `get_chemical(황산)` — 상세 조회 값 검증
9. `use_chemical(아세톤 250mL)` — DB 쓰기(재고 차감) 및 잔량 계산 검증
10. 재고 초과 사용 요청 — `isError`로 거부되는지 확인
11. `usage_history` — 방금 기록한 이력이 조회되는지 확인
12. `low_stock_report` — 발주 필요 목록
13. `resources/read chem://inventory` — 재고 현황판
14. `prompts/get safety_review` — 안전 검토 프롬프트

참고: Windows 콘솔에서 한글이 깨지면 `$env:PYTHONIOENCODING='utf-8'; python -X utf8 test_client.py`로 실행.

## Docker

| 파일 | 역할 |
|------|------|
| `Dockerfile` | python:3.11-slim 기반, HTTP 모드(0.0.0.0:8765)로 기동 |
| `docker-compose.yml` | 포트 8765 노출, `./data` 볼륨으로 SQLite 영속화 |
| `images.tar.gz` | `docker save` 결과물 (약 59MB) — EC2 전송용 |

### 로컬 실행

```powershell
docker build -t chem-inventory-mcp:latest .
docker compose up -d
python test_client.py --url http://127.0.0.1:8765/mcp   # 검증
docker compose down                                      # 중지
```

SQLite 데이터는 `./data/chem.db`에 저장되어 컨테이너를 재생성해도 유지됨.
초기화하려면 `data/` 삭제 후 재기동.

### EC2 배포 (상세: D:\prj\docs\ec2-deploy-guide.md)

```
로컬:  docker save chem-inventory-mcp:latest | gzip > images.tar.gz
       copy images.tar.gz Z:\prj\mcp_test\          # 공유드라이브로 VDI 전달
       (코드는 sgpush로 전송 — .sgignore에 *.tar.gz, chem.db, data/ 포함할 것)
VDI:   scp -i <key.pem> images.tar.gz ec2-user@<EC2_IP>:~/
       scp -i <key.pem> -r ~/prj/mcp_test ec2-user@<EC2_IP>:~/mcp_test/
EC2:   docker load < ~/images.tar.gz
       cd ~/mcp_test && mkdir -p data && docker compose up -d
```

이 서버는 `.env`가 필요 없음 (비밀값 없음).

## Claude Desktop / Claude Code 연동 예시

```json
{
  "mcpServers": {
    "connectivity-test": {
      "command": "python",
      "args": ["D:\\prj\\test\\mcp_test\\server.py"]
    }
  }
}
```