Skip to main content
Glama
unohee

Ecount MCP Server

by unohee
README.md
# ecount-mcp

이카운트(ECOUNT) ERP OpenAPI를 감싸는 **MCP 서버**. Claude 등 MCP 클라이언트에서
이카운트 ERP의 재고·판매·구매·회계 데이터를 도구로 호출한다.

## 구조

```
src/ecount_mcp/
  config.py   # 환경변수 → EcountConfig (인증 정보, 테스트/운영 도메인)
  client.py   # Zone → Login(SESSION_ID) → Data API 인증 흐름 + REST 호출
  server.py   # FastMCP 서버. @mcp.tool 로 엔드포인트 노출
docs/
  ecount-openapi.md   # 이카운트 OpenAPI 인증/엔드포인트 구조 정리
```

## 설치

```bash
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
```

## 설정

`.env.example` → `.env` 로 복사 후 채운다 (또는 MCP 클라이언트 env로 주입):

```
ECOUNT_COM_CODE=...
ECOUNT_USER_ID=...
ECOUNT_API_CERT_KEY=...
ECOUNT_DOMAIN=sboapi   # 테스트=sboapi, 운영=oapi
```

API 인증키는 이카운트 ERP 관리자 화면에서 발급한다(테스트키/운영키 구분).

## 실행

```bash
ecount-mcp            # stdio 트랜스포트 (Claude Desktop 등)
```

또는 모듈 직접 실행:

```bash
python -m ecount_mcp.server
```

### Claude Desktop 등록 예

```json
{
  "mcpServers": {
    "ecount": {
      "command": "ecount-mcp",
      "env": {
        "ECOUNT_COM_CODE": "...",
        "ECOUNT_USER_ID": "...",
        "ECOUNT_API_CERT_KEY": "...",
        "ECOUNT_DOMAIN": "sboapi"
      }
    }
  }
}
```

## 도구

| 도구 | 설명 |
|------|------|
| `ecount_call(endpoint, payload)` | 임의의 `OAPI/V2/...` 엔드포인트 호출 |
| `ecount_save_customer(customers)` | 거래처등록 (매뉴얼 §4.1) |
| `ecount_save_invoice(invoices)` | 매출·매입전표 II 자동분개 (매뉴얼 §9) — **세금계산서 발행 직전 분개** |
| `ecount_web_export_tax_invoices()` | 전자(세금)계산서 리스트(매입) **웹 세션 추출** → 행(JSON). OAPI 미지원, 헤드리스 무인 |

> 저장 도구는 부분실패를 처리한다: 반환값 `{success_cnt, fail_cnt, slip_nos, failures[], all_ok}`.
> `ecount_save_invoice`는 호출 전 입력검증(매출=CR_CODE, 매입=DR_CODE 필수)으로 rate limit을 보호한다.

### 웹 세션 추출 (`ecount_web_export_tax_invoices`) — OAPI 미지원 보완

OAPI에 없는 화면(전자세금계산서 리스트 등)은 **인증된 웹 세션 + Playwright**로 추출한다(`[web]` extra).

```bash
pip install -e ".[web]" && playwright install chromium
```

- **무인 헤드리스 로그인**: 신뢰기기 프로필(`ECOUNT_WEB_PROFILE_DIR`) + `ECOUNT_COM_CODE`/`ECOUNT_USER_ID`/`ECOUNT_USER_PW` 환경변수로 자동 로그인(2FA 생략).
- **zone 지정 (필수)**: 웹 호스트는 `login{zone}.ecount.com`. 자기 회사 zone을 `ECOUNT_WEB_ZONE`에 넣는다 — 기본값은 없다. zone 값은 OAPI Zone API 반환값과 같다.
- **메뉴 해시**: 화면 진입 경로는 회사별 메뉴 구성에 따라 다를 수 있다. 기본값이 안 맞으면 `ECOUNT_WEB_TAX_MENU_HASH`로 덮어쓴다(브라우저 주소창의 `#...` 부분).
- **선행 1회(부트스트랩)**: 사람이 신뢰기기를 등록해야 한다 —
  `python testing/hometax_invoice_export_260612_v3.py --run --headed` 로 1회 GUI 로그인(2FA 통과).
  이후 그 프로필로 무인 추출이 된다. 신뢰기기 만료 시 재부트스트랩.
- 반환: `{columns, rows(dict 리스트), count}`. 인증 산출물(`.ecount_profile/`·`*.xlsx`)은 `.gitignore`.

## 세금계산서 워크플로우 (이 프로젝트의 핵심 목적)

```
[자동: MCP]                                    [수동: 사람]
거래처 확인/등록 → ecount_save_invoice(분개) → ERP에서 전표 검수 → 발행 버튼
(ecount_save_customer)   ↑ 전표번호 발급         ↑ 전자세금계산서 발행은 OAPI 범위 밖
```

- **분개(`ecount_save_invoice`)까지가 MCP 범위.** 매출: `TAX_GUBUN="11"` + `CR_CODE`(예 "4019" 상품매출),
  매입: `TAX_GUBUN="21"` + `DR_CODE`(예 "1469" 상품). + `CUST`, `SUPPLY_AMT`, `VAT_AMT`.
- **전자세금계산서 발행은 사람이 ERP에서 검수 후 직접** (의도된 검수 게이트 — 발행=법적효력).
- `CUST`/`CR_CODE`/`DR_CODE`/`TAX_GUBUN` 코드값은 **OAPI로 조회 불가**(매뉴얼에 코드 조회 API 없음)
  → ERP에 등록된 값을 사용. 상세: [`docs/ecount-openapi.md`](docs/ecount-openapi.md) ★섹션.

새 엔드포인트는 `src/ecount_mcp/server.py` 에 `@mcp.tool` 로 얇게 추가한다.
- 전체 API 명세: 이카운트 공식 OpenAPI 매뉴얼 (벤더 저작물이라 이 저장소에 포함하지 않는다.
  ERP 로그인 후 `자기설정 > OpenAPI` 에서 받아 `docs/ecount-api-manual.md` 로 두면 아래 문서들의 참조가 맞는다)
- 코드 매핑·함정: [`docs/ecount-openapi.md`](docs/ecount-openapi.md)

## 상태

**핵심 목표(세금계산서 분개 자동화) 실서버 검증 완료** (2026-06-02, 테스트존 sboapi).
end-to-end 실호출로 확인:
- Zone → Login(SESSION_ID) → 거래처등록 → **매출분개 성공(전표번호 발급)**
- stdio MCP 핸드셰이크(initialize/tools/list) 정상, 입력검증·부분실패 파싱 동작
- 단위 테스트 16 passed

나머지 엔드포인트(품목/영업/구매/생산/재고/쇼핑몰/근태/게시판)는 매뉴얼 편입 완료, 도구화는
필요 시 추가 (`docs/ecount-openapi.md` TODO). 일부 매뉴얼 Example은 본문 잘림으로 보강 대기.

> **구현 스펙·자동화 가능/불가 범위 전체 정리**: [`docs/IMPLEMENTATION-STATUS.md`](docs/IMPLEMENTATION-STATUS.md)
> (구현된 도구, OAPI로 가능한 미도구화 엔드포인트, 구조적으로 불가능한 부분, 운영 제약, 다음 작업 후보)

TDQS

B3.4/5.0

Scored across 4 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: ecount_call is a generic API caller, while ecount_save_customer, ecount_save_invoice, and ecount_web_export_tax_invoices handle specific operations. There is no overlap between saving customers, saving invoices, and exporting tax invoices.

Naming Consistency3/5

Naming is mixed: 'ecount_save_customer' and 'ecount_save_invoice' follow a verb_noun pattern, but 'ecount_call' is just a verb and 'ecount_web_export_tax_invoices' includes a modifier and longer verb phrase. The inconsistency reduces predictability.

Tool Count5/5

With only 4 tools, the server is well-scoped for its purpose of handling customers, invoices, and tax invoice export. Each tool earns its place without redundancy or overload.

Completeness4/5

The server covers the core workflow of saving customer and invoice data and extracting tax invoices. The generic ecount_call can access other endpoints, mitigating gaps, but dedicated retrieval or update tools for customers/invoices are absent.

Maintenance

ActivityMaintained
ResponsivenessSyncing