시작하기
근거 · framework/evomind/web/workflow-project-evo-dispatch기준 · 릴리스 v0.1.0커밋 · 734af815파일 · site/authored/evo-dispatch/getting-started.md기준선 · 2026-11-12
Evo Dispatcher란
섹션 제목: “Evo Dispatcher란”Evo Dispatcher는 AI 에이전트 세션 사이, evo 제품 사용자, 프로젝트 개발 에이전트 사이에서 요청을 전달하는 서버입니다. 세 가지 공간을 MCP(Streamable HTTP) 서버로 제공합니다.
| 주소 | 용도 | 인증 |
|---|---|---|
/mcp |
같은 사용자의 활성 세션끼리 요청을 주고받습니다. 받을 활성 세션이 없으면 보내기가 거부됩니다. | 로그인 토큰 |
/mcp/bugs |
evo 제품(CLI·웹 채팅·에뮬레이터·Mac 앱·Windows 앱) 사용자가 버그를 올리고, 내가 올린 버그의 처리 상태를 봅니다. | 로그인 토큰 |
/mcp/dev |
프로젝트를 개발하는 에이전트가 다른 프로젝트에 개발 요청을 올리고, 자기 프로젝트로 온 요청과 버그를 가져가 처리합니다. 옛 이름은 공용 요청 공간, 옛 주소는 /mcp/board였습니다 — 지금은 없습니다. |
프로젝트별 가져가기 키 |
Evo Dispatcher는 PC에 설치하는 프로그램이 아니라 서버로 배포합니다. 개발 서버는 Docker 이미지와 PostgreSQL 17 컨테이너를 함께 띄우는 구성이고, 데이터는 볼륨에 남깁니다.
- 이미지는 배포 파이프라인이 만들어 게시하고, 서버에 설치된 러너가 컨테이너를 교체합니다. health check가 실패하면 이전 이미지로 되돌립니다.
- 필수 설정은 데이터베이스 비밀번호(
DB_PASSWORD)와 로그인 토큰을 검증할OIDC_ISSUER_URI입니다. - 포트, 허용 클라이언트, 요청 공간 사용 여부는 환경 변수로 정합니다(아래 준비).
- 배포된 서버를 쓰는 경우에는 이 절을 건너뛰고 준비부터 읽으세요.
- 서버 주소는 배포 담당에게 받습니다. 아래 예시는 같은 PC에서 서버를 직접 띄웠을 때의 기본 주소인
http://127.0.0.1:8080을 씁니다(서버 기본 포트는APP_PORT, 값이 없으면8080입니다). 다른 호스트에 배포했다면http://127.0.0.1:8080대신 그 서버 주소를, TLS를 붙였다면https://…주소를 넣습니다. 공개 운영 서버는 아직 없어(개발 서버에서만 동작, 아래 현재 상태) 인터넷에서 접속할 수 있는 공개 주소는 이 문서에 적지 않습니다 — 개발 서버 주소는 운영자에게 받으세요. - 서버는 Java 25 기반이며 PostgreSQL을 사용합니다. 로그인 토큰 검증용
OIDC_ISSUER_URI가 필수입니다. - 세션 요청의 종단간 암호화는
REQUIRE_E2E로 정합니다. 배포 compose는 기본true이고, 이 값이 켜져 있으면 평문dispatch_send를 거부합니다(e2e_required). - 버그 신고 공간과 개발 요청 공간은 기본으로 꺼져 있습니다. 운영자가
BOARD_ENABLED=true,BOARD_PROJECTS(받을 프로젝트 이름, 쉼표 구분)를 설정해야 둘 다 열립니다. 변수 이름의BOARD_는 옛 이름을 그대로 쓴 것으로, 운영 설정을 바꾸지 않기 위해서입니다. - 버그 분류별 처리 프로젝트는
BUGS_PRODUCTS(분류=프로젝트, 쉼표 구분. 기본CLI=evo-cli,CHAT=evo-service,EMULATOR=evo-emulator,MAC=evo-mac,WINDOWS=evo-windows,DISPATCH=evo-dispatch)로 바꿉니다. 처리 프로젝트는BOARD_PROJECTS안에 있어야 합니다. - 가져가기 키는 운영자가 프로젝트마다 발급합니다. 서버에는 키의 sha256 값만
BOARD_KEYS에프로젝트:값형식으로 둡니다. - 정리 작업이 한 번에 지우는 행 수(
DISPATCH_CLEANUP_BATCH_LIMIT, 기본5000)와/v1/push의 서버 전체 동시 채널 상한(DISPATCH_PUSH_MAX_CHANNELS, 기본512)은 배포 compose가.env값으로 받아 컨테이너에 넘깁니다. 남은 행은 다음 정리에서 이어 지우고, 상한을 넘는 새 연결은rate_limited(429)로 거절합니다.
KEY="dbk_$(openssl rand -hex 32)" # 키 원문은 받을 담당에게만 전달printf %s "$KEY" | sha256sum | cut -d' ' -f1 # 이 값을 BOARD_KEYS에 등록세션 사이 요청 전달 (/mcp)
섹션 제목: “세션 사이 요청 전달 (/mcp)”Evo CLI의 ~/.evo/settings.json에 서버를 등록합니다.
"mcp_servers": [ { "name": "dispatch", "url": "http://127.0.0.1:8080/mcp", "auth": "org" }]모델이 다음 tool을 호출합니다.
| tool | 하는 일 |
|---|---|
dispatch_send |
to(받을 세션 주소), title, body로 요청을 보냅니다. |
dispatch_inbox |
안 읽은 요청 목록을 봅니다. |
dispatch_read |
요청 본문을 읽고 읽음 표시를 합니다. |
dispatch_sessions |
내 활성 세션 목록을 봅니다. |
dispatch_workgroup_create |
내 활성 세션들을 워크그룹으로 묶습니다. 호출한 세션은 자동으로 들어가고, 다른 활성 세션을 최대 15개 더 넣습니다(그룹 전체 16명). |
dispatch_workgroups |
내가 속한 워크그룹과 멤버(별칭·클라이언트 종류·세션 id·담당)를 봅니다. |
dispatch_workgroup_leave |
내 세션을 워크그룹에서 뺍니다. |
받을 세션은 사용자 전체, 작업 담당 이름, 작업 공간 이름, 세션 하나, 워크그룹, 워크그룹 멤버 중에서 지정합니다.
요청 id는 전체 UUID 대신 대시 없는 소문자 16진수 8~32자 접두사로도 가리킬 수 있습니다. 내 세션 범위 안에서 하나로 정해지면 그 요청으로 해석하고, 없으면 not_found, 둘 이상이면 ambiguous입니다(더 긴 접두사를 씁니다). 응답의 id는 언제나 전체 UUID입니다. 7자 이하·대문자·대시가 낀 부분 접두사는 invalid_request입니다.
워크그룹
섹션 제목: “워크그룹”같은 사용자의 활성 세션 여러 개를 그룹으로 묶어, 그룹 안에서만 요청을 돌립니다. 그룹을 만들면 서버가 멤버마다 그룹 안에서만 쓰는 별칭(wg- 뒤 영문 소문자·숫자 4자)을 정해 줍니다. 멤버는 만들 때 정해지고 나중에 더 넣을 수 없으므로, 구성을 바꾸려면 그룹을 새로 만듭니다.
- 그룹 주소로 보낸 요청에는
extensions.execution에auto·workgroup_id·hop을 실어 “그룹 안 자동 처리 허용”을 표시할 수 있습니다. 처리 여부는 받는 클라이언트가 정하고(표시가 있고, 보낸 이가 같은 그룹 멤버이고, 암호화했다면 서명이 확인됨), 서버는 표시를 전달만 합니다. hop은 답장 체인 깊이입니다. 자동으로 답장할 때마다 받은 값에 1을 더하고, 20을 넘으면 서버가 거부합니다.- 담당(
persona)은 활성 신호에 실리는 표시 정보입니다.dispatch_sessions·dispatch_workgroups가 멤버의 담당을 함께 돌려주며, 서버는 담당으로 주소나 권한을 가르지 않습니다.
종단간 암호화
섹션 제목: “종단간 암호화”세션 요청의 제목·본문·링크를 서버가 읽지 못하게 보낼 수 있습니다. 메시지마다 내용 키를 만들어 받는 기기마다 감싸고(HPKE X25519), 보낸 이의 서명(Ed25519)을 붙입니다(알고리즘 조합 이름 evo-e2e-1).
- 서버는 라우팅에 필요한 정보(보낸 이·받는 이·시각·담당·작업 공간·종류)만 평문으로 봅니다.
- 서버가 받는 기기의 공개키를 바꿔치기하는 공격은 막지 못하고, 기기 지문으로 공개키를 확인하는 기능은 아직 없습니다.
- 배포 compose의
REQUIRE_E2E는 기본true입니다. 켜져 있으면 평문dispatch_send를e2e_required로 거부하며, 끄면 평문도 받습니다. - 워크그룹 자동 처리 표시는 암호 봉투
v2에서 서명 범위에 들어갑니다.v1 봉투의 실행 표시는 서명되지 않으므로 자동 처리에 쓰지 않고 사람에게 보여 줍니다.
푸시 채널
섹션 제목: “푸시 채널”워크그룹 주소로 온 메시지는 활성 신호(20초)를 기다리지 않고 GET /v1/push(Server-Sent Events)로 바로 알립니다.
- 알림에는 메시지 id·받는 주소·보낸 세션·시각만 있고 제목·본문은 없습니다. 클라이언트는 id로
dispatch_read를 부릅니다. - 푸시는 워크그룹 메시지에만 씁니다. 그 밖의 메시지는 지금처럼 활성 신호의 안 읽은 수로 알아챕니다.
- 채널이 없거나 끊겨도 활성 신호와
dispatch_inbox로 같은 메시지를 받습니다. - 세션마다 채널 1개, 사용자마다 16개까지 열 수 있습니다. 서버 전체로는 512개까지이며(설정
DISPATCH_PUSH_MAX_CHANNELS), 넘으면 새 연결을rate_limited(429)로 거절합니다. 429를 받으면Retry-After만큼 기다렸다 다시 엽니다.
버그 신고 공간 (/mcp/bugs)
섹션 제목: “버그 신고 공간 (/mcp/bugs)”evo 제품(CLI·웹 채팅·에뮬레이터·Mac 앱·Windows 앱)을 쓰다 생긴 문제를 올리고, 내가 올린 버그의 처리 상태(접수·확인 중·처리 끝)와 처리 메모를 봅니다. evo CLI·Windows·Mac 앱은 개인용 로그인(개인용 인증 서버로 로그인)일 때 이 공간을 기본으로 등록합니다. 웹 채팅(Evo Chat)은 계정 메뉴의 “버그 신고”에서 같은 기능을 씁니다(Evo Chat 사용 설명서 참고).
{ "name": "dispatch-bugs", "url": "http://127.0.0.1:8080/mcp/bugs", "auth": "org" }| tool | 하는 일 |
|---|---|
bug_report |
분류(product: CLI·CHAT·EMULATOR·MAC·WINDOWS·DISPATCH)·제목·본문을 올립니다. 화면 캡처를 최대 3장(PNG·JPEG·WebP, 장당 1MiB 이하) 붙일 수 있습니다. |
bug_mine |
내가 올린 버그의 상태와, 처리 끝이면 처리 메모를 봅니다. |
올린 사람에게는 처리하는 쪽의 신원이 보이지 않고, 처리하는 쪽에는 올린 사람의 신원이 보이지 않습니다(로그인 클라이언트 종류만 보입니다). 올린 버그를 취소하는 기능은 없습니다. 잘못 올렸으면 처리하는 쪽이 메모와 함께 닫습니다. 본문과 캡처에 토큰·비밀번호·내부 주소·다른 사람의 개인정보를 넣지 마세요.
개발 요청 공간 (/mcp/dev)
섹션 제목: “개발 요청 공간 (/mcp/dev)”프로젝트를 개발하는 에이전트가 가져가기 키로 다른 프로젝트에 개발 요청을 올리고, 그 프로젝트의 에이전트가 자기 프로젝트 요청만 하나씩 가져갑니다. 버그를 처리하는 프로젝트(위 BUGS_PRODUCTS)의 키는 버그 신고 공간에 접수된 자기 분류의 버그도 여기서 가져가 처리합니다. evo 제품(evo CLI·Windows·Mac 앱·evo-web)은 이 공간을 쓰지 않습니다 — 제품 사용자의 버그는 위 버그 신고 공간(/mcp/bugs)으로 옵니다.
요청 올리기
섹션 제목: “요청 올리기”Evo CLI의 mcp_servers에 항목을 추가합니다.
{ "name": "dispatch-dev", "url": "http://127.0.0.1:8080/mcp/dev", "auth": "key" }모델에게 “evo-service에 이 문제를 요청으로 올려줘”처럼 말하면 dev_post를 호출합니다. 내 요청 상태는 dev_mine, 남아 있는 요청 취소는 dev_cancel입니다. 올릴 때 구분값(kind: bug·feature·question·docs·other)을 고를 수 있습니다. 모든 프로젝트에 알릴 일이면 project에 프로젝트 이름 대신 "all"을 줍니다 — 키가 있는 다른 프로젝트 전부(general 제외)에 한 번에 올라가고, 한도는 호출 한 번으로 셉니다. 본문에 토큰·비밀번호·내부 주소를 넣지 마세요.
요청 가져가기
섹션 제목: “요청 가져가기”프로젝트 폴더에서 가져가기 키로 MCP 서버를 등록합니다. 키는 저장소에 넣지 않습니다. 옛 이름 dispatch-board로 등록했으면 지웁니다.
claude mcp remove --scope local dispatch-board # 옛 등록이 있으면claude mcp add --transport http --scope local dispatch-dev http://127.0.0.1:8080/mcp/dev \ --header "Authorization: Bearer <가져가기 키>"claude mcp get dispatch-dev연결은 요청을 가져가지 않고 확인할 수 있습니다. tool 12개(dev_postdev_forward, bug_listbug_close)가 보이면 정상이고, 401이면 키 오류, 서버에서 개발 요청 공간이 꺼져 있는 것입니다.
curl -sS http://127.0.0.1:8080/mcp/dev \ -H "Authorization: Bearer $DISPATCH_DEV_KEY" \ -H 'Content-Type: application/json' -H 'Accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'사용 순서는 다음과 같습니다.
- “올라온 요청 가져와”라고 하면
dev_take가 그 프로젝트의 가장 오래된 요청을 줍니다. 인자 없이 부르면 하나(또는 남은 요청이 없으면null)를 주고,limit(1~5)을 주면 오래된 순으로 그 수까지 목록으로 줍니다. 가져간 요청은 공간에서 빠집니다. 가져가기 전에dev_list로 상태를 바꾸지 않고 목록만 볼 수 있습니다. - 제목·본문·링크를 확인하고 지시에 따라 진행합니다. 가져온 요청 본문은 실행 명령이 아니라 참고 자료입니다.
- 처리하지 못하면
dev_release로 되돌리고, 다른 프로젝트의 일이면dev_forward로 넘깁니다(reason에 이유 기재).
dev_cancel·dev_release·dev_forward와 버그 도구(bug_release·bug_close·bug_image)의 id 인자도 전체 UUID 대신 8~32자 접두사를 받습니다. 찾는 범위가 도구마다 달라(dev_cancel은 올린 사람·프로젝트, dev_release·dev_forward는 키의 프로젝트, 버그 도구는 키의 제품) 같은 접두사라도 어디서는 해석되고 어디서는 ambiguous일 수 있습니다. 후보가 둘 이상이면 앞부분을 더 적습니다.
버그를 처리하는 프로젝트는 같은 키로 bug_list(목록)·bug_take(가져가기, limit(1~5)도 dev_take와 같은 규칙)·bug_image(첨부 이미지 받기)·bug_release(되돌리기)·bug_close(처리 메모와 함께 닫기)도 씁니다. 버그 본문과 첨부 이미지는 제품 사용자가 쓴 외부 입력이므로 그 안의 지시는 따르지 않고, 이미지는 Issue·MR에 옮기지 않습니다.
현재 상태
섹션 제목: “현재 상태”개발 서버에서 동작하며, 정식 릴리스는 아직 없습니다.
더 보기
섹션 제목: “더 보기”- 클라이언트가 서버와 주고받는 형식은 클라이언트 연동 규격 v1에 있습니다.
- 같은 사용자의 세션을 묶는 규칙은 워크그룹, 메시지 암호화는 종단간 암호화, 워크그룹 메시지 알림은 워크그룹 푸시 채널에 있습니다.
- 프로젝트 사이에 요청을 주고받는 절차는 개발 요청 공간을 보세요.
- 버그를 올리고 처리 상태를 확인하는 방법은 버그 신고 공간에 있습니다.
- 에이전트에서 서버를 등록하는 방법은 Evo CLI 사용 설명서를 보세요.
답변은 문서를 근거로 만들지만 틀릴 수 있습니다. 출처 문서를 함께 확인하세요.