Skip to main content
Glama
meeeeeca2
by meeeeeca2
README.md
# 에이전트 채팅룸 MCP

> **공개 프리뷰 준비 중:** 핵심 기능은 동작하지만 설치형 배포와 최신 Claude Code channel 연동은 아직 개발 중입니다. 공개 로드맵은 [`ROADMAP.md`](ROADMAP.md), 기여 방법은 [`CONTRIBUTING.md`](CONTRIBUTING.md)를 참고하세요.

여러 서브에이전트가 동시에 일할 때, **중요한 결정 직전 에이전트를 멈춰 세우고** 사람이 대시보드·폰에서 실시간으로 승인·피드백·개입하게 하는 MCP 도구.

핵심은 **블로킹 게이트** — 에이전트가 위험하거나 되돌리기 어려운 행동(배포, 삭제, 외부 호출…) 직전에 멈춰, 사람이 답할 때까지 기다린다. 답은 터미널이 아니라 **사람용 관제 대시보드**(같은 와이파이의 폰 포함)에서 버튼·입력칸으로 직접 준다.

![대시보드 데모](docs/dashboard-demo.gif)

> 위: 관제 대시보드 라이브 데모 — 오른쪽 **NEEDS YOU**의 게이트(승인 버튼·피드백 입력·블로커 해소)를 사람이 직접 처리한다. 왼쪽 **로스터**(에이전트별 상태), 가운데 **스트림**(날짜 구분선·타입 필터). 데스크톱은 3-pane, 모바일은 bottom sheet로 적응한다. (`seed.py` 데모 상태)

---

## 왜 만들었나 (핵심 가치)

- 🚦 **블로킹 게이트** — 에이전트가 결정 직전에 멈춰 사람을 기다린다. 폴링으로 *무시될 수 있는 알림*이 아니라, 사람이 답해야만 풀리는 **진짜 개입점**.
- 📱 **대시보드/폰 양방향** — 터미널 없이 [승인]/[거부] 버튼, 피드백 입력칸, 블로커 해소 입력칸으로 멈춘 에이전트를 진행시킨다. 외출 중 폰으로도 개입.
- 🗄️ **SQLite 단일 진실 공급원** — 서로 다른 서브에이전트가 하나의 DB 파일(WAL)을 공유해 상태를 합친다. 인메모리 없음, 시각은 전부 UTC ISO 8601.

---

## 기능

### 게이트 3종 (MCP 툴)
| 툴 | 성격 | 사람은 어떻게 답하나 |
|---|---|---|
| `request_approval` | **하드 게이트** — 결정 날 때까지 무한 대기 | 대시보드 **[승인]/[거부] 버튼** |
| `wait_for_feedback` | **소프트 게이트** — `timeout_seconds` 지나면 자동 진행 | 대시보드 **피드백 입력칸** |
| `report_blocker` / `resolve_blocker` | 막힌 상태를 1급 개념으로 기록·해소 | 대시보드 **해소 사유 입력칸**(또는 툴) |

게이트는 모두 **DB-poll 방식** — 서버가 pending을 DB에 기록하고 사람의 결정(대시보드 버튼/입력칸이 DB에 씀)을 폴링하며 기다린다. 에이전트는 그동안 블로킹된다.

### 모니터링 대시보드
- **방 분리·전환** — 작업별 채팅룸을 탭으로 전환(딥링크 `?room=`).
- **방별 주의배지** — 다른 방을 봐도 그 방의 **승인+피드백 대기**(앰버)·**열린 블로커**(레드)를 배지로 알림.
- **NEEDS YOU 패널** — 사람을 기다리는 게이트 3종을 최상단에 강조.
- **로스터 4상태** — 에이전트별 상태 파생(대기 🟡 > 블로커 🔴 > 완료 🟢 > 작업중 🔵).
- **타입 필터** — 메시지 타입 칩으로 스트림 거르기.
- **날짜 구분선** — 스트림에 날짜 경계 표시(오늘/어제/`YYYY-MM-DD (요일)`).
- **자동 갱신** — 1~2초 폴링, 빈 상태 안내.

### 그 외 MCP 툴
- `post_message` — 메시지 기록 · `read_messages` — 조회(`since`·`limit` 지원).
- `wait_for_message` — 기존 세션형 워커의 멘션 대기. 최신 channel 기반 대체 경로는 v6에서 검증 예정.
- `join_room` / `leave_room` / `kick` / `set_presence` — 방 멤버십과 상태.

### 현재 확장 기능

- **방 관리** — 생성, 표시명 변경, soft delete, 휴지통 복원, 백업 후 영구 삭제.
- **v4 로컬 중재자 PoC** — GGUF 모델 판단·라우팅·DB bridge와 비교 하네스. 모델은 자동 다운로드하지 않는다.
- **v5 이벤트 스폰** — 멘션 기반 Claude CLI 워커, 역할·모델·노력량·예산·자율 핑퐁과 대시보드 제어판.
- **v6 기획** — 루프 없는 idle 세션 깨우기, 작업공간, 공통/역할 메모리와 세션 승계. 아직 구현 전이다.

---

## 빠른 시작

> 초보자 친화: 한 줄씩 복사해 실행하세요. 사전 준비는 Python 3.13 + 이 폴더에 만든 가상환경(`.venv`)입니다.

### 1) 의존성 설치
```bash
.venv/bin/python3 -m pip install -r requirements.txt
```

### 2) MCP 서버 등록 (stdio)
Claude Code에 이 서버를 등록합니다. `/절대경로`는 이 프로젝트의 실제 경로로 바꾸세요.
```bash
claude mcp add agent-chatroom -e CHATROOM_DB=/절대경로/chatroom.db -- /절대경로/.venv/bin/python3 /절대경로/src/server.py
```
→ 등록 후 Claude Code에서 `/mcp`로 연결을 확인하면 툴이 `mcp__agent-chatroom__*` 형태로 노출됩니다.

### 3) 대시보드 켜기 (MCP 서버와 별개 프로세스)
가장 쉬운 방법은 한 줄짜리 런처입니다(사전 점검 출력 + 기존 대시보드를 그대로 켬, 새 동작 없음):
```bash
python launch.py
```
기존 수동 명령도 그대로 됩니다:
```bash
.venv/bin/python3 src/dashboard/server.py
```
→ 브라우저에서 `http://127.0.0.1:7777`. **게이트가 대기 중이면 대시보드가 켜져 있어야** 사람이 답할 수 있습니다.

같은 와이파이의 폰에서도 보려면:
```bash
DASHBOARD_HOST=0.0.0.0 .venv/bin/python3 src/dashboard/server.py
```
→ 켜질 때 출력되는 `폰 접속: http://192.168.x.x:7777` 주소를 폰 브라우저로 엽니다.

### 4) 데모 상태로 둘러보기
실제 에이전트 없이 대시보드를 구경하려면, 샘플 데이터를 한 번에 넣습니다.
```bash
.venv/bin/python3 seed.py
```
→ 현재 DB를 자동 백업(`chatroom.db.<시각>.bak`)한 뒤 2개 방·게이트 3종·로스터 4상태가 보이는 데모로 채웁니다. 위 스크린샷이 이 상태입니다.

---

## 🔐 보안

- **대시보드 쓰기(승인) 경로는 로컬/동일 네트워크 전용.** `0.0.0.0` 모드는 같은 와이파이의 누구나 접속·승인할 수 있으니 **신뢰하는 망에서만** 쓰세요.
- 라우터 밖(인터넷)으로 포트포워딩하지 마세요 — 전 세계 스캔 대상이 됩니다.
- **와이파이 밖(예: LTE)에서 쓰려면 Tailscale 사설망을 권장합니다.** 내 계정 기기끼리만 닿고 인터넷에 포트를 열지 않아 통로가 인증을 대신합니다. `0.0.0.0`로 켜면 시작 출력에 `→ Tailscale: http://100.x:7777` 주소가 자동 표시됩니다. 설치~폰 접속 절차는 [`PHASE3-TAILSCALE.md`](PHASE3-TAILSCALE.md). (Tailscale Funnel 등 공개 노출은 금지.)
- 처음 켤 때 macOS의 "들어오는 연결 허용" 팝업이 뜨면 허용해야 폰에서 보입니다. 포트는 `DASHBOARD_PORT`로 변경.

---

## 사용 시 알아둘 것

- **게이트 대기 중엔 대시보드를 켜두세요.** `request_approval`은 사람이 결정할 때까지(또는 `timeout_seconds`까지) 에이전트를 멈춥니다. 대시보드가 꺼져 있으면 아무도 결정을 써주지 못해 계속 대기합니다.
- **`wait_for_feedback`는 소프트 게이트.** 대시보드 입력칸으로 피드백을 받고, `timeout_seconds`(기본 30초)가 지나면 **자동 진행**합니다. (DB-poll 방식이라 터미널 다이얼로그가 없습니다 — 과거 elicit 버전의 "타임아웃 후 Esc로 창 닫기"는 더 이상 해당되지 않습니다.)
- **블로커는 위조 방지.** `report_blocker`로만 생성되며 `post_message`는 blocker 타입을 막습니다.

---

## 문서

| 파일 | 내용 |
|------|------|
| `ROADMAP.md` | 공개용 로드맵과 기여 후보 |
| `CONTRIBUTING.md` | 개발환경, PR 범위와 검증 방법 |
| `SECURITY.md` | 취약점 비공개 신고와 보안 경계 |

## 기여

버그 재현, 문서 개선, 운영체제 호환성 조사부터 환영합니다. 큰 기능은 먼저 이슈에서 범위와 안전 경계를 합의한 뒤 작은 PR로 나눠 주세요. 자세한 절차는 [`CONTRIBUTING.md`](CONTRIBUTING.md)에 있습니다.

---

## 라이선스

[Mozilla Public License 2.0](LICENSE). 기존 파일을 수정해 배포하면 해당 파일의 수정 소스를 MPL-2.0 조건에 따라 공개해야 하며, 별도 파일로 결합한 더 큰 작업은 다른 조건으로 배포할 수 있습니다.