# Dabit.Mcp — AI로 LED 전광판을 제어하는 MCP 서버 Claude Desktop 같은 AI 클라이언트가 자연어로 LED 전광판을 **읽고(상태 조회) + 표시하고(텍스트/색) + 설정하는(화면·밝기·시간·보드)** MCP(Model Context Protocol) 서버다. > 예) "정문 전광판 밝기 50%로", "화면 빨강으로 채워", "시간 맞춰", "가나다라를 4색으로 왼쪽으로 흘려" → AI가 해당 도구를 호출 → 이 서버가 기존 검증된 `DibdProtocol` 코드로 바이트를 조립해 컨트롤러에 전송. ## 동작 구조 ``` [사람] → [Claude Desktop (AI)] ──MCP(stdio, JSON-RPC)──> [Dabit.Mcp.exe] ──> [전광판 컨트롤러] (이 프로젝트) (COM/TCP) ``` - 새로 만든 건 이 서버(어댑터)뿐. 바이트 조립·통신은 `DibdProtocol.Core`(프로토콜) + `DibdProtocol.Transport`(시리얼/TCP)를 그대로 재사용한다. - 각 도구의 조립은 정본 `DabitChe.Desktop/ViewModels/SettingsViewModel.cs`를 본떠 **byte-identical**. - `LedControlService`는 `DabitChe.AutoSend`의 전송 패턴을 축약한 것(WPF 의존성 제거). **Phase 2에서 `DibdProtocol.Transport.Rpc.DibdRpcClient`(신 프로토콜 96 method)로 교체 예정인 폐기성 코드.** ## 도구 (20개) ### 읽기 / 상태 | 도구 | 설명 | |------|------| | `get_firmware_info` | 펌웨어 모델/버전/화면 크기 (HEX 0x6F) | | `get_screen_size` | 화면 가로×세로 (펌웨어 응답에서 추출) | | `get_time` | 컨트롤러 RTC 시각 (HEX 0x66, BCD 파싱) | | `get_connection_status` | 설정된 연결 정보 — 통신 안 함(스모크용) | ### 콘텐츠 표시 ⚠️ 쓰기 | 도구 | 설명 | |------|------| | `display_text` | 단색 텍스트 한 줄 즉시 표시 (실시간 메시지) | | `display_message` | 글자별 색 + 입장/퇴장 이동효과 + 속도/유지 | ### 화면 · 밝기 · 전원 ⚠️ 쓰기 | 도구 | 설명 | |------|------| | `set_screen_size` | 화면 크기(단/열) 설정 (HEX 0x40) | | `fill_screen` | 전체 단색 채우기, 8색 (HEX 0x42) | | `load_background_image` | 저장된 배경이미지 로드 (HEX 0x4F) | | `set_brightness` | 밝기 0~4단계 (100/75/50/25/5%) (HEX 0x44) | | `led_power_on` / `led_power_off` | LED 전원 (HEX 0x41) | ### 페이지 메시지 ⚠️ 쓰기 | 도구 | 설명 | |------|------| | `set_page_count` | 페이지 개수 1~10 (ASCII "60") | | `reset_page_message` | 페이지 초기화 (전체/개별) (ASCII "61") | | `set_section_effect` | 섹션 동시/개별 표출 (ASCII "62") | ### 표출신호 (HUB75) ⚠️ 쓰기 | 도구 | 설명 | |------|------| | `set_display_signal` | 대표 신호 7종 이름으로 설정 (HEX 0x49) | | `send_custom_signal` | 사용자 신호 코드 직접 전송 (ASCII "44") | ### 시간 · 보드 설정 (고급) | 도구 | 종류 | 설명 | |------|------|------| | `sync_controller_time` | ⚠️ 쓰기 | PC 시간으로 RTC 동기화 (HEX 0x47, 7B BCD) | | `read_board_settings` | 읽기 | 디버그/포트기능/통신속도 (ASCII "B3") | | `save_board_settings` | ⚠️ 쓰기 | 보드기능 저장 (ASCII "B2") | > **제외(블록 전송)**: 폰트(0x98)·펌웨어(0x9F)·이미지(DAT/BGP/PLA)·스케줄. 대용량 다블록 전송이라 PoC 범위 밖. ## 빌드 · 실행 ```powershell dotnet build Dabit.Mcp/Dabit.Mcp.csproj dotnet run --project Dabit.Mcp ``` ## Claude Desktop 연결 `claude_desktop_config.json`의 `mcpServers`에 등록한다(아래는 실증된 Serial COM2 설정): ```json { "mcpServers": { "dabit-led": { "command": "D:\\Gitea\\dabitche-mcp\\Dabit.Mcp\\bin\\Debug\\net9.0-windows\\Dabit.Mcp.exe", "env": { "DABIT_TRANSPORT": "Serial", "DABIT_COM": "COM2", "DABIT_BAUD": "115200" } } } } ``` (개발 중엔 `command`를 `dotnet` + `args:["run","--project","...Dabit.Mcp"]`로 둘 수도 있으나, exe 직접 실행이 빠르고 안정적.) ### 환경변수 (연결 설정) | 변수 | 의미 | 기본값 | |------|------|--------| | `DABIT_TRANSPORT` | `TcpClient` 또는 `Serial` | `TcpClient` | | `DABIT_HOST` / `DABIT_PORT` | TCP 호스트 / 포트 | `192.168.0.201` / `5000` | | `DABIT_COM` / `DABIT_BAUD` | 시리얼 포트 / 속도 | `COM1` / `9600` | | `DABIT_RESPONSE_LATENCY` | 응답 타임아웃(ms) | `1000` | ## 제약 · 주의 - ⚠️ **COM 포트 동시 점유 불가** — WPF 앱(DabitChe.Desktop/AutoSend)과 같은 COM 포트를 동시에 못 연다. 시리얼 사용 시 **WPF 앱을 끄고** MCP 서버를 실행한다. - ⚠️ **로그는 반드시 stderr** — stdio는 stdout을 JSON-RPC에 쓴다. `Program.cs`에서 `ClearProviders()` + 콘솔 로그를 stderr로 보낸다(Windows EventLog 로거 제거 포함). - ⚠️ **요청 순서 비보장** — MCP 서버가 여러 요청을 병렬 처리한다. `LedControlService._gate`가 전송은 한 번에 하나로 직렬화하지만 **진입 순서는 보장 안 함**. 한 번에 여러 명령을 몰아 보내면(예: sync 직후 get_time) 실행 순서가 뒤바뀔 수 있다. 순서 의존 작업은 응답을 받고 다음을 보낸다. - **FlashWrite 명령**(시간·보드·화면크기·페이지·밝기·표출신호·fill·배경)은 응답이 느려 `timeoutMsOverride: 5000` 적용. - ✅ **scroll 4방향(left/right/up/down) 실기 검증 완료**(2026-06-02, DIBD600T V3.6.1). 🟡 미검증: `bpp` 색심도 의미, 밝기 index1 ASCII(75)≠HEX(0x48) 레거시값. ## 로드맵 | Phase | 내용 | |-------|------| | **0 (완료)** | 읽기 4 + 콘텐츠 2 + 설정 14 = 20 도구. stdio. 얇은 LedControlService | | 1 | 밝기 고급(13B 시간대별/CDS)·컨트롤러 재시작/초기화·기타 고급(스케줄속도/깜빡임/잔상/릴레이) | | 2 | 백엔드를 `DibdRpcClient`(JSON-RPC 96 method)로 승격 — 신 프로토콜 실기 검증 후 | | 3 | HTTP/SSE transport + HMAC 인증 → 원격/B2B | ## 검증 상태 (2026-06-01) - ✅ 빌드(경고 0/오류 0), stdio 스모크(20개 도구 노출, tools/call 왕복, 환경변수 로딩, stdout 청결성) - ✅ 이중 코드 리뷰 반영 — Anthropic `code-reviewer`(byte 조립 정합·죽은코드·timeout) + OpenAI `codex`(HEX status 체크: 거부 응답을 성공으로 오보하던 것 수정) - ✅ **실기 검증** (DIBD500S 펌웨어 V3.4.8, COM2 @ 115200): - 읽기: `get_firmware_info`, `get_time`(BCD), `read_board_settings`(7필드) - 표시: `display_text`(환영합니다 빨강), `display_message`(가나다라 4색 좌이동) - 설정: `set_brightness`(50%), `fill_screen`(빨강), `sync_controller_time`(2026 적용 확인) — 모두 status 0x00 - ✅ **실기 검증 추가** (2026-06-02, DIBD600T 펌웨어 V3.6.1, COM2 @ 115200): - scroll 4방향 전부 정상: `scroll_left`(우→좌) · `scroll_right`(좌→우) · `scroll_up`(아래→위) · `scroll_down`(위→아래) — 육안 확인 - `display_message` 글자별 색(`colors`) 정상 — colors를 쉼표 구분 문자열로 변경해 배열 바인딩 버그 수정 - 🟡 미검증: bpp 색심도, save_board_settings 실기 반영