# 0. 문서 상태 이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다. - 상태: confirmed - 문서 ID: dcy-013_20260707_docker-network-mcp-deployment - 이슈명: Jarca Ledger 독립 Docker 배포 및 network MCP endpoint 제공 - 작성 시각(KST): 2026-07-07 22:23 KST - 마지막 갱신 시각(KST): 2026-07-07 22:23 KST - 대체됨: 없음 - 후속 Discovery 참조: 없음 - 생성된 REQ 참조: `REQ-019` # 1. 계획 상태 요약 - 연계 문서 현황: - 선행 Discovery: `docs/discovery/dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing.md` — Phase 8 optional HTTP adapter를 Deferred 후보로 남겼다. - 관련 REQ/BAT: `REQ-018`/`BAT-014`는 MCP/Streamlit adapter surface narrowing과 baseline refresh를 완료했으나, network MCP 배포 자체는 Out of Scope였다. - 관련 baseline 문서: `docs/project-structure.md`, `docs/runtime-flows.md` - 관련 runbook: `docs/runbooks/docker-network-mcp-deploy.md` - 해석: - 재무관리 에이전트가 `genichin-agent`의 stdio `docker exec` 실행에 의존하지 않고 Jarca Ledger를 사용하려면, Jarca Ledger 자체가 Docker daemon 아래 독립 서비스로 실행되고 network MCP endpoint를 직접 제공해야 한다. - 이번 문서는 이미 수행된 긴급 배포 작업을 StagePilot 추적성 안으로 편입해, Dockerfile/compose/transport 설정/DB 이전/검증 evidence를 REQ/BAT 기준으로 남기는 post-implementation SDLC 보정 문서다. # 2. 요구사항 판정 결과 - 판정: 신규 후속 주기 - 근거 - dcy-011은 Phase 8 optional HTTP adapter를 구현하지 않고 Deferred로 남겼으므로, network MCP endpoint와 Docker service 배포는 dcy-011의 하위 구현이 아니라 별도 deployment/interface 반복이다. - 기존 stdio MCP는 클라이언트가 프로세스를 실행하는 모델이어서 `genichin-agent` 실행 환경에 의존한다. 이번 요청은 `jarca-ledger` 컨테이너가 자체 생명주기와 endpoint를 갖도록 하는 운영 구조 변경이다. # 3. 문제점의 요약 - 현재 상태 - 기존 `jarca` 컨테이너에는 `/root/.local/share/jarca/ledger.sqlite3` 운영 DB가 존재했고, `accounts=8`, `transactions=6312`, `import_batches=13`, `category_rules=46`, `ledger_categories=62`가 들어 있었다. - 새 `jarca-ledger` 컨테이너 초기 배포 직후 `/data/ledger.sqlite3`는 빈 schema 상태였고, 운영 DB 이전이 누락되어 있었다. - 기존 MCP entrypoint는 FastMCP 기본 stdio 실행만 사용했으며, network MCP transport 설정과 Docker 배포 정의가 StagePilot 문서에 반영되어 있지 않았다. - `docs/project-structure.md`와 `docs/runtime-flows.md`는 MCP stdio/local dashboard 중심 baseline을 유지했고, network MCP/Docker service flow를 아직 반영하지 않았다. - 기대 상태 - `jarca-ledger` 컨테이너는 `genichin-agent`와 독립적으로 `restart: unless-stopped` 정책 아래 실행된다. - 컨테이너는 `streamable-http` MCP endpoint `http://:8000/mcp`를 직접 제공한다. - 운영 DB는 `/volume1/docker/jarca-ledger/data/ledger.sqlite3`에 영속화되며, 기존 `jarca` 운영 DB 데이터가 일관성 snapshot 방식으로 이전된다. - 재무관리 에이전트는 Docker exec/attach가 아니라 network MCP endpoint를 소비한다. - 이해관계자 - 가계 재무관리 에이전트 — Jarca Ledger MCP tools를 안정적으로 호출하는 소비자 - 가웨인/dev-butler — 배포 구조와 기술 기준을 관리하는 개발 책임자 - 주인님/운영자 — Synology Docker volume과 운영 DB의 실제 소유자 - 주요 사용자 시나리오 - 재무관리 에이전트가 `http://192.168.55.253:8000/mcp`에 접속해 `ledger_health_check`, `get_ledger_db_status`, 거래/계좌/리포트 도구를 호출한다. - `genichin-agent` 컨테이너가 재시작되거나 중단되어도 `jarca-ledger` 컨테이너와 DB는 계속 유지된다. - 운영자가 Docker 상태, healthcheck, bind mount, DB integrity/hash/table counts를 evidence로 확인한다. # 4. 이번에 정의할 변경 - FastMCP runtime transport 설정화: `JARCA_MCP_TRANSPORT`, `JARCA_MCP_HOST`, `JARCA_MCP_PORT`, `JARCA_MCP_STREAMABLE_HTTP_PATH`로 stdio와 streamable-http 실행을 선택할 수 있게 한다. - 독립 Docker service 배포: `Dockerfile`, `.dockerignore`, `docker-compose.yml`을 추가하고 `container_name=jarca-ledger`, volume `/volume1/docker/jarca-ledger/data:/data`, port `8000:8000`, restart `unless-stopped`를 고정한다. - 운영 DB 이전 및 검증: 기존 `jarca` 컨테이너 DB를 SQLite backup API로 snapshot한 뒤 새 volume으로 이전하고, MCP smoke와 DB status로 동일 데이터를 검증한다. - baseline 문서 갱신: `docs/project-structure.md`, `docs/runtime-flows.md`, deployment runbook이 network MCP 배포 구조를 반영해야 한다. ## 영향 범위 - 코드 영향: - `jarca_ledger_mcp/adapters/mcp/server.py` - `tests/test_mcp_http_runtime.py` - 배포 영향: - `Dockerfile`, `.dockerignore`, `docker-compose.yml` - Synology host path `/volume1/docker/jarca-ledger/data` - 문서 영향: - `docs/runbooks/docker-network-mcp-deploy.md` - `docs/project-structure.md`, `docs/runtime-flows.md` - StagePilot Discovery/SRS/Batch register와 verification evidence # 5. 요구사항 목록 ## 기능 요구사항 - FR-1: MCP server는 기존 stdio 기본값을 유지하면서 환경변수로 `streamable-http` transport를 활성화할 수 있어야 한다. - FR-2: Docker 배포는 `jarca-ledger` 컨테이너가 독립 실행되고 `/volume1/docker/jarca-ledger/data`를 `/data`로 bind mount해야 한다. - FR-3: network MCP endpoint는 `http://:8000/mcp`에서 tool discovery와 `ledger_health_check`를 성공시켜야 한다. - FR-4: 기존 `jarca` 운영 DB는 일관성 snapshot으로 이전되어 주요 table counts와 integrity가 보존되어야 한다. - FR-5: baseline docs와 runbook은 Docker network MCP 운영 흐름과 `genichin-agent` 비의존 원칙을 반영해야 한다. ## 비기능 요구사항 - NFR-1 (operational independence): `jarca-ledger` 컨테이너 생명주기는 `genichin-agent`가 아니라 Docker daemon/restart policy에 의해 관리되어야 한다. - NFR-2 (financial data safety): 운영 DB 이전 전 새 빈 DB 백업을 남기고, 기존 DB는 SQLite backup API로 snapshot해 복사해야 한다. - NFR-3 (contract preservation): 기존 MCP tool 이름과 주요 응답 shape는 network transport 도입 후에도 유지되어야 한다. ## 범위 경계 - In Scope - FastMCP streamable-http transport 설정화 - Docker image/compose 배포 - Synology volume 기반 운영 DB 이전 - MCP network smoke 및 DB integrity verification - StagePilot/baseline/runbook 문서 반영 - Out of Scope - 별도 FastAPI/REST business API 구현 - 외부 공개용 reverse proxy/TLS/auth 설계 - 자동 백업 스케줄러 - dcy-012 review-decision/workbench 기능 구현 # 6. 리스크/가정 목록 ## 리스크 - R-1 (High): 운영 DB 이전 누락 또는 잘못된 DB 교체 시 재무관리 에이전트가 빈 ledger를 source of truth로 오인할 수 있다. - 완화 방안: 이전 전후 table counts, sha256, integrity_check, MCP `get_ledger_db_status`를 verification evidence로 남긴다. - R-2 (Medium): `127.0.0.1:8000`은 `genichin-agent` 내부에서는 agent 컨테이너 자신을 의미하므로 smoke endpoint를 잘못 잡을 수 있다. - 완화 방안: agent 컨테이너에서 검증할 때는 Synology host IP `192.168.55.253:8000` 또는 공유 Docker network DNS를 사용한다고 runbook에 명시한다. - R-3 (Medium): network MCP endpoint가 내부망에 열리므로 접근제어/TLS가 없는 상태에서 외부 노출되면 금융 tool surface가 위험해질 수 있다. - 완화 방안: 현재 범위는 내부망 배포로 제한하고, 외부 공개/reverse proxy/auth는 별도 후속 Discovery로 분리한다. ## 가정 - A-1: Synology Docker daemon은 `/volume1/docker/jarca-ledger/data` bind mount를 생성/사용할 수 있다. - A-2: 재무관리 에이전트는 streamable-http MCP client 또는 Hermes remote MCP 설정을 통해 endpoint를 소비할 수 있다. - A-3: 기존 `jarca` 컨테이너의 `/root/.local/share/jarca/ledger.sqlite3`가 현 시점 운영 ledger source였다. ## 오픈 질문 - 없음 — 이번 배포 범위와 endpoint/volume/컨테이너 이름은 사용자 지시와 실제 배포 evidence로 확정되었다. # 7. 초기 성공 기준 - S-1: `docker inspect jarca-ledger`에서 `state=running`, `health=healthy`, `restart=unless-stopped`, mount `/volume1/docker/jarca-ledger/data -> /data`가 확인된다. - S-2: MCP streamable-http client가 `http://192.168.55.253:8000/mcp`에서 56개 tool을 발견하고 `ledger_health_check`에 성공한다. - S-3: `get_ledger_db_status`가 `/data/ledger.sqlite3`, `integrity_check=ok`, `accounts=8`, `transactions=6312`, `import_batches=13`, `category_rules=46`, `ledger_categories=62`를 보고한다. - S-4: `python -m pytest -q`와 신규 runtime config 테스트가 통과한다. - S-5: baseline docs와 runbook이 network MCP 배포와 운영 DB 이전 흐름을 설명한다. ## 측정 방식 및 데이터 출처 - S-1: `docker inspect`, `docker logs`, Docker healthcheck - S-2: Python `mcp.client.streamable_http.streamablehttp_client` smoke - S-3: MCP `get_ledger_db_status` 및 SQLite integrity/table count probe - S-4: pytest output - S-5: `docs/project-structure.md`, `docs/runtime-flows.md`, `docs/runbooks/docker-network-mcp-deploy.md`, BAT-015 verification # 8. REQ로 넘기기 전 확인 체크 - [x] 컨테이너명/volume/endpoint 확정 - [x] 기존 DB source와 이전 대상 확인 - [x] network MCP transport 지원 가능성 확인 - [x] 배포 및 smoke evidence 확보 - [x] baseline 문서 갱신 요구 명시 # 9. 파일 처리 결과 - 처리 결과: 생성 - 생성 경로: `docs/discovery/dcy-013_20260707_docker-network-mcp-deployment.md` - 참조 문서: - `docs/discovery/dcy-011_20260703_backend-refactor-phase4-write-import-workflow-adapter-narrowing.md` - `docs/srs/Interface/req-018_adapter-surface-narrowing-baseline-refresh.md` - `docs/project-structure.md` - `docs/runtime-flows.md` - `docs/runbooks/docker-network-mcp-deploy.md` - `stage-pilot/templates/project-structure.md` - `stage-pilot/templates/runtime-flows.md` # 10. 사용자 결정 필요 항목 요약 ## DECIDE - 없음 ## CONFIRM - 없음 ## DATA - 없음 # 11. Discovery Freeze ## 섹션 참조 - 범위: [# 5. 요구사항 목록 > 범위 경계](#5-요구사항-목록) - 리스크/오픈 질문: [# 6. 리스크/가정 목록](#6-리스크가정-목록) - 성공 기준: [# 7. 초기 성공 기준](#7-초기-성공-기준) ## Freeze 플래그 - Handoff Decision: confirmed - Handoff Rationale: 사용자 지시에 따라 Docker network MCP 배포와 운영 DB 이전이 이미 완료되었고, 검증 evidence가 확보되어 REQ/BAT post-implementation 문서화로 인계한다. - Ready for REQ Drafting: true - Confirmed By: 진환 고 - Confirmed At (KST): 2026-07-07 22:23 KST