内容
# AI 병렬 오케스트레이션 MCP
- Codex 작업 내역을 자동으로 저장하고 중요한 결과를 나중에 다시 찾을 수 있게 돕는 로컬 MCP 서버입니다.
### 배경
- AI 대화는 작업 맥락을 축적·재사용하기 어렵고, 큰 작업을 한 세션에 몰면 결과 검토가 불편해집니다.
- 이 프로젝트는 기억, 실행, 검증, 결과 수집을 분리해 반복 가능한 개발 운영 흐름을 만듭니다.
### 아이디어 제시
- Obsidian vault는 사람이 읽을 수 있는 기억 문서 저장소입니다.
- QMD는 저장 문서를 인덱싱하고 검색합니다.
- Codex CLI는 독립 작업 실행기이며, MCP 서버는 이 기능들을 하나의 도구 집합으로 제공합니다.
### 무엇을 할 수 있나요?
- 중요한 작업 결정이나 메모를 저장하고 나중에 검색할 수 있습니다.
- 독립된 Codex 작업을 실행한 뒤 진행 상태와 최종 결과를 확인할 수 있습니다.
- 큰 작업을 의존 관계에 맞춰 나누거나, 발견된 여러 이슈를 병렬로 처리할 수 있습니다.
- Codex 작업을 시작하면 관련 기억을 자동으로 찾아 참고하고, 성공하면 결과 요약을 자동으로 기억합니다.
### 가장 쉬운 사용 방법
배포된 서비스에 연결된 Codex 또는 MCP 클라이언트에서 자연어로 요청하면 됩니다. 일반 사용자는 서버 설치, QMD, 저장 파일 구조를 알 필요가 없습니다.
#### Codex 대화용 예시 프롬프트
아래 문장을 Codex 대화에 그대로 입력하면 해당 MCP 도구를 호출하도록 요청할 수 있습니다. `<session-id>`와 경로는 앞선 응답 또는 실제 프로젝트 환경에 맞게 바꿉니다.
| 도구 | 예시 프롬프트 |
| --- | --- |
| `health_check` | `orchestration MCP의 health_check를 호출해서 Codex, QMD, vault, session root 설정과 사용 가능한 도구를 확인해줘.` |
| `remember` | `orchestration MCP의 remember로 "배포 결정"을 저장해줘. 내용은 "이번 배포에서는 파일 기반 세션 저장소를 유지한다."이고 태그는 자동으로 분류해줘.` |
| `recall` | `orchestration MCP의 recall로 "파일 기반 세션 저장소 결정"을 최대 5개까지 검색해줘.` |
| `spawn_session` | `orchestration MCP의 spawn_session으로 C:\\Users\\you\\project에서 테스트 실패 원인을 수정해줘. 검증 명령은 npm test야.` |
| `check_inbox` | `orchestration MCP의 check_inbox를 호출해서 실행 중, 성공, 실패한 세션을 요약해줘.` |
| `get_session` | `orchestration MCP의 get_session으로 <session-id> 세션의 상태, 마지막 메시지, 결과와 최근 로그 40줄을 보여줘.` |
| `close_session` | `orchestration MCP의 close_session으로 완료된 <session-id> 세션을 닫아줘.` |
| `send_message` | `orchestration MCP의 send_message로 <session-id> 세션에 "다음 실행에서는 변경 사항을 다시 검토하고 npm test를 실행해줘."를 후속 지시로 저장해줘.` |
| `run_task_dag` | `orchestration MCP의 run_task_dag로 C:\\Users\\you\\project에서 inspect와 fix 작업을 실행해줘. inspect는 원인을 분석하고, fix는 inspect 후 수정하며, 두 작업의 검증 명령은 npm test야.` |
| `run_branch_hunt` | `orchestration MCP의 run_branch_hunt로 C:\\Users\\you\\project를 탐색해 재현 가능한 오류를 최대 3개 찾고 각각 수정해줘. 각 작업의 검증 명령은 npm test야.` |
- `get_session`, `close_session`, `send_message`의 `<session-id>`는 `spawn_session`, `run_task_dag`, `run_branch_hunt`, 또는 `check_inbox` 응답에서 확인합니다.
- `send_message`는 실행 중인 세션에 즉시 전달되지 않으며, 다음 재실행 또는 resume에 사용할 큐에 저장됩니다.
- `run_task_dag`와 `run_branch_hunt`는 검증 명령을 반드시 지정해야 합니다.
### 알아둘 제한
- 이 MCP가 실행한 Codex 세션은 별도 `recall` 요청 없이 시작 전에 기억을 검색하고, 별도 `remember` 요청 없이 성공 후 요약본을 RAG에 저장합니다.
- 원문 대화와 JSONL 실행 로그는 RAG에 저장하지 않습니다. 작업 요약, 결과 요약, 이벤트 수, 검증 명령만 저장합니다.
- 현재 Codex 화면의 일반 대화처럼 이 MCP 밖에서 실행된 대화는 자동 기억 대상이 아닙니다.
- 실행 중인 작업에 실시간 메시지를 주입하지 않습니다. 후속 지시는 다음 재실행을 위한 큐에 저장합니다.
- 서비스가 반환하는 결과의 품질은 연결된 Codex와 검색 데이터의 품질에 영향을 받습니다.
### 핵심 개념
- `remember`: 지식 문서를 저장하고 QMD 인덱싱을 요청합니다.
- `recall`: 저장된 지식을 QMD 검색으로 찾아 표준 JSON으로 돌려줍니다.
- `spawn_session`: 분리된 Codex 세션을 시작하고 실행 결과를 보관합니다.
- 자동 기억: 세션 시작 전에 QMD를 검색해 관련 기억을 프롬프트에 추가하고, 성공 후 요약본을 vault에 저장합니다.
- `Task DAG`: 선행 작업이 끝난 뒤 가능한 작업을 병렬로 실행합니다.
- `Branch Hunt`: 코드 탐색 결과의 이슈를 독립 작업으로 나눕니다.
- `Ralph Loop`: 지정한 검증 명령이 통과할 때까지 수정과 재검증을 요청합니다.
### 구조/아키텍처
```text
MCP client
├─ remember / recall ───────────────> Obsidian vault + QMD
└─ session / DAG / Branch Hunt ────> Codex CLI
├─ 실행 전 QMD 자동 검색
└─ 성공 후 요약 자동 저장
└─ session_root/<session_id>/
metadata, events, result, last message
```
- MCP 인터페이스: 입력을 검증하고 도구 결과를 반환합니다.
- 실행 계층: Codex와 QMD 명령을 실행합니다.
- 저장 계층: 세션 메타데이터, 로그, 결과, 후속 지시를 파일로 보관합니다.
- 자세한 구조는 [ARCHITECTURE.md](ARCHITECTURE.md), 데이터 흐름은 [DATA_FLOW.md](DATA_FLOW.md), 모든 문서의 용도는 [DOC_INDEX.md](DOC_INDEX.md)에서 확인합니다.
### 기술 구성
- Node.js 24와 TypeScript로 작성했습니다.
- MCP SDK로 stdio 도구 서버를 제공하고, YAML 설정과 Zod 입력 검증을 사용합니다.
- 외부 연동은 Codex CLI와 QMD CLI입니다. 각 도구의 세부 동작은 이 프로젝트가 대신 구현하지 않습니다.
### 빠른 시작
1. 의존성을 설치하고 빌드합니다.
```powershell
& 'C:\Program Files\nodejs\npm.cmd' install
& 'C:\Program Files\nodejs\npm.cmd' run build
```
2. 예시 설정을 복사한 뒤, 모든 경로와 실행 정책을 실제 환경에 맞게 채웁니다.
```powershell
Copy-Item .\config.example.yaml .\config.yaml
```
3. Codex에 stdio MCP 서버를 등록합니다. 아래 예시는 프로젝트 전용 `.codex\config.toml`입니다.
```toml
[mcp_servers.orchestration]
command = 'C:\Program Files\nodejs\node.exe'
args = ['C:\Users\you\MCP_Orchestration\dist\src\server.js']
cwd = 'C:\Users\you\MCP_Orchestration'
env = { ORCHESTRATION_CONFIG = 'C:\Users\you\MCP_Orchestration\config.yaml' }
startup_timeout_sec = 15
tool_timeout_sec = 600
```
4. Codex를 새로 시작합니다. Codex가 stdio 서버를 자동으로 시작하며, 서버 창을 따로 열어 둘 필요는 없습니다.
### 설정 방법
- `config.example.yaml`을 `config.yaml`로 복사합니다.
- 모든 설정값은 필수이며, 암묵 기본값을 사용하지 않습니다.
- 주요 설정:
- `codex_executable`: `codex.cmd` 절대 경로
- `workspace_root`: Codex가 작업할 루트 경로
- `session_root`: 세션 산출물 저장 경로
- `obsidian_vault_path`: 기억 Markdown 저장 경로
- `qmd_executable`, `qmd_search_command`, `qmd_index_command`: QMD 실행 정보
- `codex_model`, `codex_sandbox`, `codex_approval_policy`: Codex 실행 정책
- `max_parallel_sessions`, `ralph_max_consecutive_failures`, `session_timeout_seconds`: 실행 한도
- `auto_remember_on_success`: 성공한 MCP Codex 세션의 요약 자동 저장 여부
- `auto_recall_before_session`: Codex 세션 시작 전 기억 자동 검색 여부
- `auto_recall_limit`: 자동 검색 결과 개수
- `auto_summary_max_chars`: 자동 저장 요약의 최대 문자 수
- QMD CLI의 구체 명령은 프로젝트가 추측하지 않습니다. 각 운영 환경에 맞는 명령 템플릿을 설정 파일에 명시해야 합니다.
### 도구 호출 예시
MCP 클라이언트가 도구 입력을 직접 표시하는 경우 다음 JSON을 사용할 수 있습니다. 일반적인 Codex 대화에서는 앞선 자연어 예시처럼 요청해도 됩니다.
```json
{
"title": "배포 결정",
"body": "이번 배포에서는 파일 기반 세션 저장소를 유지한다."
}
```
위 입력은 `remember` 호출입니다. `memory` 기본 태그와 제목·본문에서 분류한 태그가 자동으로 저장되며, `tags`를 직접 전달하면 자동 태그에 추가되어 중복 없이 보관됩니다. 검색은 `recall`에 다음처럼 전달합니다.
```json
{
"query": "파일 기반 세션 저장소 결정",
"limit": 5
}
```
독립 작업 실행 예시입니다.
```json
{
"prompt": "테스트 실패 원인을 찾아 수정하고 결과를 요약해줘.",
"workdir": "C:\\Users\\you\\project",
"validation_commands": ["npm test"]
}
```
위 세션은 실행 전에 프롬프트와 관련된 기억을 자동 검색하고, 성공하면 원문 로그 대신 요약본만 자동 저장합니다. 필요할 때는 `remember`와 `recall`을 직접 호출할 수도 있습니다.
전체 도구 입력과 응답 계약은 [API_SPEC.md](API_SPEC.md)에 정리했습니다.
### 기능 목록
| 도구 | 용도 |
| --- | --- |
| `health_check` | 실행 경로와 등록된 도구를 확인합니다. |
| `remember`, `recall` | 기억을 저장하고 검색합니다. |
| `spawn_session` | 독립 Codex 작업을 실행합니다. |
| `check_inbox`, `get_session`, `close_session` | 작업 결과와 상태를 관리합니다. |
| `send_message` | 다음 실행용 후속 지시를 보관합니다. |
| `run_task_dag` | 의존성 기반 병렬 작업을 실행합니다. |
| `run_branch_hunt` | 이슈 탐색 후 분기 작업을 실행합니다. |
### 운영 방법
- 연결 확인은 `health_check`로 시작합니다.
- 세션 결과는 `check_inbox` 또는 `get_session`으로 조회합니다.
- 서버가 시작되면 이전 서버 인스턴스에서 `queued` 또는 `running`으로 남은 세션을 자동으로 `failed` 처리합니다.
- 복구된 세션은 `get_session`의 `recovery`, `result.json`의 `recovered`, `events.jsonl`의 `startup_recovery` 이벤트로 확인합니다.
- `session_root/<session_id>/`에는 `metadata.json`, `events.jsonl`, `last_message.md`, `result.json`, `queued_messages.jsonl`이 생성됩니다.
- `events.jsonl`에는 자동 검색·저장 성공 또는 실패 상태가 기록됩니다.
- 자동 기억 파일은 vault에 `Codex session <session_id> summary` 제목으로 생성되며 원문 실행 로그를 포함하지 않습니다.
- 현재는 파일 기반 store입니다. 장기간 대량 운영에는 별도 데이터베이스 저장소를 검토해야 합니다.
- 자세한 운영 장애 대응은 [ERROR_HANDLING.md](ERROR_HANDLING.md)를 참고합니다.
### 기존 방법과의 차이점
- 하나의 대화에 모든 맥락을 쌓는 대신, 재사용할 지식과 일회성 실행 결과를 구분합니다.
- 각 실행 결과를 독립 파일로 남겨 나중에 확인할 수 있습니다.
- 관련 기억은 세션마다 자동 검색되고, 성공 결과는 제한된 길이의 요약으로 누적됩니다.
- 실시간 메시지를 주입하지 않습니다. 실행 중 세션에 보낼 후속 지시는 큐에 저장하며, 현재 버전은 자동 resume을 수행하지 않습니다.
### 실험/운영 환경
- 런타임: Node.js 24 이상
- 운영 의존성: Codex CLI, QMD CLI, 쓰기 가능한 Obsidian vault 경로
- 검증: Node.js 내장 test runner와 fake Codex/QMD 실행 파일
### 구현 결과
- 구현 완료 상태: 10개 MCP 도구와 핵심 실행 흐름은 자동 테스트로 검증된 상태입니다.
- 검증 범위와 결과는 [RESULT.md](RESULT.md), 재현 가능한 검증 절차는 [TEST_PLAN.md](TEST_PLAN.md)에 있습니다.
### 결과 평가 및 기존 방법과의 결과 비교
- 장점: 기억과 실행을 분리하고, 병렬 작업의 상태·로그·결과를 재검토할 수 있습니다.
- 장점: 검증 명령을 명시해 실행 결과를 확인 가능한 작업 단위로 남깁니다.
- 주의: 이 프로젝트는 Codex와 QMD를 대체하지 않으며, 두 도구를 연결·관리합니다.
### 한계점 및 추후 계획
- 실행 중 세션에 대한 실시간 제어와 queued message 자동 resume은 지원하지 않습니다.
- 자동 기억은 이 MCP가 실행한 성공 세션에만 적용되며, 실패·시간 초과 세션과 일반 Codex UI 대화는 저장하지 않습니다.
- 하나의 `session_root`는 동시에 하나의 MCP 서버 인스턴스만 사용해야 합니다.
- 실제 QMD 설치 환경의 명령 형식은 운영자가 설정해야 합니다.
- 향후 SQLite 저장소와 세션 대시보드를 검토합니다.