Skip to main content
Glama
lchenter
by lchenter
README.md
# WYEA-WORKFLOW-MCP

**AI가 결정이 필요할 때 GitHub 이슈를 만들고, 이메일로 알린 뒤, 사람의 댓글을 받아 작업을 이어가게 하는 MCP 서버입니다.**

```text
AI의 결정 요청 → 비공개 GitHub 이슈 + 이메일 → 사람의 댓글 → AI가 확인하고 작업 재개
```

기존 GitHub·Google 계정을 사용합니다. 별도 AI API 키나 상시 클라우드 서버는 필요 없습니다. MCP를 실행하는 PC와 사용하는 AI 앱은 켜져 있어야 합니다.

[빠른 설치](#빠른-설치) · [사용법](#사용법) · [문제 해결](#문제-해결) · [MIT 라이선스](LICENSE)

## 빠른 설치

### 1. 준비하고 실행하기

필요한 것: **Node.js 22 이상**, **GitHub CLI**, GitHub 계정, Google 계정, MCP를 지원하는 AI 앱.

- [Node.js 설치](https://nodejs.org/en/download)
- [GitHub CLI 설치](https://cli.github.com/)
- Git이 없다면 이 페이지의 **Code → Download ZIP**으로 받은 뒤 압축을 풉니다.

```sh
git clone https://github.com/lchenter/WYEA-WORKFLOW-MCP.git
cd WYEA-WORKFLOW-MCP
npm ci
npm run setup
```

### 2. 설치 마법사 따라가기

| 순서 | 사용자가 할 일 | 마법사가 하는 일 |
| --- | --- | --- |
| GitHub 연결 | 열린 브라우저에서 로그인 | GitHub CLI의 공식 브라우저 로그인 실행. 이미 로그인했다면 건너뜀 |
| 이슈 보관함 | 비공개 저장소 `OWNER/REPO` 입력. 없다면 `new` 입력 | GitHub 저장소 생성 페이지 열기, 비공개 여부·이슈 기능·권한 확인 |
| 담당자·이메일 | 담당 GitHub 계정과 **메일을 받을 주소 한 개** 입력 | 담당자 지정 가능 여부 확인, 임의의 연결 키 생성 |
| Google 연결 | Apps Script에 준비된 코드를 붙여넣고 최초 배포 | Apps Script 새 프로젝트 페이지 열기, 개인용 코드 생성·클립보드 복사 |
| 마무리 | 웹 앱 URL 한 번 붙여넣기 | 이메일·연결 키 일치 확인, MCP 설정 파일 생성 |

**이 공개 저장소는 프로그램 배포용입니다. 작업 요청과 승인 내용은 각 사용자의 별도 비공개 저장소에 저장됩니다.** 이메일 수신자는 해당 비공개 이슈를 볼 수 있는 GitHub 계정으로 로그인해야 합니다.

브라우저가 자동으로 열리지 않으면 터미널에 표시된 링크를 누르세요. 자동 열기를 끄려면 `npm run setup -- --no-open`을 씁니다. 브라우저 로그인은 [GitHub CLI의 공식 인증 흐름](https://cli.github.com/manual/gh_auth_login)을 사용합니다. 토큰을 코드에 붙여넣지 않습니다.

### 3. Apps Script 최초 배포 — 한 번만

마법사가 [Apps Script 새 프로젝트](https://script.google.com/home/start)를 엽니다. **메일을 보낼 Google 계정**으로 로그인합니다. 수신 이메일은 이 계정과 달라도 됩니다.

1. 프로젝트 이름을 `Workflow 알림`으로 정합니다.
2. 기본 `Code.gs` 내용을 지우고 마법사가 복사한 코드를 붙여넣어 저장합니다. 복사가 안 됐다면 프로젝트의 `.local/Code.gs`를 열어 전체 내용을 복사합니다.
3. **배포 → 새 배포 → 유형 선택 → 웹 앱**을 선택합니다.
4. **실행 사용자: 나**, **액세스 권한: 모든 사용자**로 설정합니다.
5. 배포하며 Google 권한을 승인하고, 표시된 **웹 앱 URL(`/exec`)**을 마법사에 붙여넣습니다.

Google 인증·권한 승인·최초 배포는 사용자 본인이 해야 합니다. 이 부분까지 자동 로그인하거나 배포하는 기능은 없습니다. [Google 웹 앱 배포 안내](https://developers.google.com/apps-script/guides/web).

“확인되지 않은 앱” 안내가 보이면 본인이 방금 만든 프로젝트·계정이 맞는지 확인하고 Google의 안내에 따릅니다. 회사·학교 Google 계정에서 외부 액세스 또는 권한 승인이 차단되면 관리자의 허용이 필요할 수 있습니다.

생성한 코드는 이메일 발송만 담당하며 Drive·Sheets·Gmail 받은편지함을 읽지 않습니다. 외부 요청은 무작위 연결 키로 인증하고, 수신자는 배포된 코드에 고정됩니다. 설정 완료 검사는 메일을 보내지 않습니다. [MailApp 권한 안내](https://developers.google.com/apps-script/reference/mail/mail-app).

### 4. AI 앱에 연결하기

마법사가 **현재 PC의 절대 경로**를 넣은 파일을 만듭니다. 다른 사람의 경로를 복사할 필요가 없습니다.

| 앱 | 연결 방법 |
| --- | --- |
| Codex | 생성된 `.local/codex.toml` 내용을 `~/.codex/config.toml`에 추가. 동일 이름의 기존 항목은 중복 추가하지 말고 교체 |
| Claude Code | 아래 CLI 명령 실행 또는 `.local/mcp.json`의 항목을 프로젝트 `.mcp.json`에 병합 |
| Claude Desktop / 다른 stdio MCP 앱 | `.local/mcp.json`의 `mcpServers` 항목을 앱의 MCP 설정에 병합 |

프로젝트 폴더에서 CLI로 연결하는 방법도 있습니다. `<절대경로>`는 **이 프로젝트의 전체 경로**로 바꿉니다.

```sh
codex mcp add wyea-workflow -- node "<절대경로>/server.mjs"
claude mcp add --transport stdio --scope user wyea-workflow -- node "<절대경로>/server.mjs"
```

두 명령을 모두 실행할 필요는 없습니다. 사용하는 앱 하나만 설정합니다. Codex는 긴 댓글 대기를 위해 `tool_timeout_sec = 600`을 설정할 수 있습니다. [Codex MCP 안내](https://developers.openai.com/codex/mcp), [Claude Code MCP 안내](https://code.claude.com/docs/en/mcp).

앱을 재연결한 뒤 AI에게 **“wyea_status로 연결 상태를 확인해 줘”**라고 합니다. `ready: true`면 준비됐습니다. `npm run check`로도 확인할 수 있습니다.

## 사용법

### 첫 사용: 이슈와 메일 한 통 만들기

AI에게 아래처럼 요청합니다.

> wyea-workflow로 검토 요청을 만들어 줘. 제목 맨 앞에는 실제 실행 모델명과 추론 강도를 AUTH:LLM(모델명-추론강도) 형식으로 적어. 질문은 “현재 변경을 반영할까요?”, 선택지는 “반영”과 “보류”야. 이슈와 메일은 한 번만 만들고 내 댓글을 기다려.

AI가 호출하는 예시입니다. **아래 모델 표기는 예시이므로 실제 실행 설정으로 바꿉니다.**

```json
{
  "title": "AUTH:LLM(GPT-6-Astra-high) 변경 반영 검토",
  "question": "현재 변경을 반영할까요?",
  "options": ["반영", "보류"],
  "context": "관련 변경과 검증 결과를 여기에 적습니다.",
  "maxWaitSec": 45
}
```

위 인자를 `wyea_ask`에 전달하면 다음을 수행합니다.

1. 설정한 비공개 저장소에 이슈 생성·담당자 지정.
2. `[WYEA 작업] …` 이메일 **한 통** 요청. 메일에는 이슈 링크가 포함됩니다.
3. 새 댓글을 기다림. 기본 확인 간격은 60초입니다.
4. 답을 받으면 `decision`, 댓글 본문, 선택지 정보를 AI에게 반환.

이메일이 도착하면 링크를 열어 **GitHub 이슈에 댓글**을 답니다. 이메일 답장을 직접 읽는 기능은 없습니다.

### 사람은 어떻게 답하나요?

| 댓글 첫 줄 | 의미 |
| --- | --- |
| `승인` 또는 `approve` | 승인 |
| `거부` 또는 `deny` | 거부 |
| `1`, `2`, `2번` | 해당 선택지 선택 |
| `내일 진행하고 문구부터 바꿔 주세요` | 자유 지시. AI가 본문 전체를 읽고 판단 |

추가 설명은 둘째 줄부터 적으면 됩니다. 자동 분류는 첫 줄을 기준으로 하며, 같은 GitHub 계정을 쓰더라도 도구가 작성한 댓글은 답으로 세지 않습니다. 모델명 표시는 호출자가 적는 식별 표시이며 모델 신원을 암호학적으로 증명하는 기능은 아닙니다.

### 답이 아직 없거나 이어서 물어볼 때

- `status: timeout`이면 **`wyea_ask({"issue": 이슈번호})`만 다시 호출**합니다. 새 이슈·메일은 생성하지 않습니다.
- 기존 이슈에서 **새 질문**을 하려면 `wyea_ask({"issue": 이슈번호, "question": "다음 질문…"})`. 질문 댓글과 메일 한 통을 추가합니다.
- 단순 진행 보고는 `wyea_comment`. **메일은 가지 않습니다.** 메일도 필요한 추가 요청은 `wyea_notify` 또는 질문이 있는 `wyea_ask`를 씁니다.
- `wyea_create_issue` 자체에 메일 요청이 포함됩니다. 생성 직후 `wyea_notify`를 또 호출하지 않습니다.
- `mail.ok: true`는 메일 서버 처리 응답입니다. 실제 수신 여부는 받은 사람이 확인합니다. 실패·시간초과 시 자동 재발송하지 않습니다.

이 MCP는 **AI가 도구를 호출한 요청**을 처리합니다. 모든 터미널 승인창을 자동으로 가로채거나, GitHub 웹에서 직접 만든 모든 이슈에 자동 메일을 보내지는 않습니다. 앱이 종료되면 로컬 댓글 대기도 멈추며, 재시작 후 이슈 번호로 다시 기다릴 수 있습니다.

### 도구 목록

| 도구 | 용도 |
| --- | --- |
| `wyea_status` | 인증·비공개 저장소·메일 엔드포인트 확인 |
| `wyea_ask` | 이슈 또는 질문 댓글 → 메일 → 댓글 대기 → 답 해석 |
| `wyea_create_issue` | 이슈 생성·할당·메일 한 번. 제목 `AUTH:LLM(Modelname-thinkinglevel)` 필수 |
| `wyea_notify` | 기존 이슈의 추가 요청을 메일로 알림 |
| `wyea_wait` | 새/수정 댓글 대기 |
| `wyea_check` | 새/수정 댓글 한 번 확인 |
| `wyea_snapshot` | 읽고 처리한 댓글까지 기준 갱신 |
| `wyea_comment` | 진행 또는 결과 댓글. 메일 없음 |
| `wyea_close` | 작업 완료 후 이슈 닫기 |

### 터미널에서 사용하기

```sh
npm run check
node cli.mjs parse "2번" --option "반영" --option "보류"
node cli.mjs check 12
node cli.mjs ask --issue 12 --max 45
```

아래 명령은 **실제로 이슈와 이메일을 만듭니다.** 모델 표기를 현재 설정으로 바꾸세요.

```sh
node cli.mjs create "AUTH:LLM(GPT-6-Astra-high) 검토 요청" "변경 내용을 검토한 뒤 댓글로 의견을 남겨 주세요."
```

CLI 결과는 JSON입니다. `ask` 종료 코드 `0`은 답을 받음, `3`은 아직 답이 없음, `1`은 오류입니다. `notify`, `comment`, `close` 상세 인자는 [cli.mjs](cli.mjs) 상단을 참조하세요.

## 설정 변경

- **수신 이메일 변경:** `npm run setup`을 다시 실행해 새 이메일 입력 → 생성된 `.local/Code.gs`로 기존 Apps Script 코드 교체 → **배포 관리 → 수정 → 새 버전** 배포 → 같은 `/exec` URL 입력. 기존 연결 키는 재사용합니다.
- **GitHub 계정 변경:** `gh auth switch` 또는 `gh auth login --web` 후 `npm run setup`. 이전 이슈 기록과 새 계정의 접근 권한을 확인합니다.
- **키 분실·노출:** 현재 작업을 멈추고 `.local/.notify.env`를 별도 안전한 장소에 보존한 뒤 새 설정 키를 생성·배포합니다. 구버전 배포도 비활성화해야 구키 사용이 중단됩니다.
- **다른 PC로 이동:** 새 PC에서 설치를 다시 진행합니다. `.local`을 공유 저장소에 올리지 않습니다.

고급 설정은 로컬 `wyea-workflow.config.json`입니다. `WYEA_CONFIG`, `WYEA_REPO`, `WYEA_ASSIGNEE`, `WYEA_STATE_DIR`, `WYEA_SECRET_FILE`, `WYEA_NOTIFY_URL`, `WYEA_AGENT` 환경 변수도 지원합니다. 설정 파일의 상대 경로는 해당 설정 파일 위치를 기준으로 계산합니다.

## 개인정보와 저장 위치

- 이 배포본에는 운영자의 실제 이메일, 비공개 저장소 설정, Google 배포 ID, 인증 파일, 개인 작업 기록을 포함하지 않습니다.
- GitHub 인증은 GitHub CLI가 관리합니다. 이 프로젝트가 GitHub 토큰을 복사해 저장하지 않습니다.
- `.local/`에는 개인 코드·연결 키·댓글 상태·MCP 연결 파일이, `wyea-workflow.config.json`에는 저장소·배포 URL 설정이 저장됩니다. 모두 `.gitignore` 대상입니다.
- 질문·댓글은 사용자가 설정한 GitHub 저장소에, 메일 내용은 Google과 수신 메일 서비스에 전달됩니다. 메일 본문에 민감한 내용을 넣지 마세요. 패턴 검사는 일부 전화번호·비밀값 등을 차단하지만 모든 개인정보를 알아낼 수는 없습니다.
- Apps Script 웹 앱 URL과 연결 키를 함께 공개하지 마세요. 준비된 코드를 붙여넣은 뒤 클립보드를 다른 내용으로 덮어쓰는 것이 좋습니다.
- 하나의 이슈에 대한 대기는 한 프로세스가 맡으세요. 여러 에이전트가 동시에 같은 상태 파일을 수정하는 분산 잠금 기능은 없습니다.

## 문제 해결

| 증상 | 해결 |
| --- | --- |
| `gh`를 찾지 못함 | GitHub CLI 설치 후 터미널을 다시 열기 |
| GitHub 인증/권한 오류 | `gh auth status` 확인. 계정·비공개 저장소 접근·담당자 권한 확인 |
| 공개 저장소라 거부됨 | 코드 배포 저장소가 아닌 별도의 **비공개 작업 이슈 저장소**를 지정 |
| Apps Script 연결 실패/HTML 응답 | `/dev`가 아닌 `/exec` 주소인지, 실행 사용자와 “모든 사용자” 액세스인지 확인 |
| `forbidden` | `.local/Code.gs`의 최신 키와 실제 배포 버전이 같은지 확인. 편집만 하고 새 버전 배포를 생략하지 않기 |
| 메일이 안 옴 | 결과의 `mail`과 `.local/state/issue-N.json`의 `mailAttempts` 확인. 추가 질문에 메일 도구를 호출했는지 확인. `ok:true`여도 수신함·필터·스팸 및 Google 할당량은 별도 확인. 원인을 단정하거나 자동 재발송하지 않기 |
| 메일이 두 통 옴 | `create_issue`/새 `ask` 뒤 `notify`를 중복 호출했는지 확인 |
| 대기 도중 앱 시간초과 | `maxWaitSec`를 앱의 제한보다 짧게 설정(예: 45). 이후 이슈 번호만 넣어 다시 대기 |
| 모델명 접두사 오류 | 제목 **맨 앞**에 `AUTH:LLM(실제모델명-high)`처럼 실제 모델·추론 강도 입력 |
| 도구 수정이 반영되지 않음 | 실행 중인 MCP 연결을 다시 시작 |

메일은 배포한 Google 계정의 [Apps Script 할당량](https://developers.google.com/apps-script/guides/services/quotas)을 따릅니다.

## 개발 및 검증

```sh
npm ci
npm test
node setup.mjs --help
```

테스트는 GitHub·메일·Apps Script 객체를 모의 구현으로 대체합니다. 실제 이슈 생성이나 메일 발송은 하지 않습니다. CI는 Windows와 Linux의 Node.js 22/24에서 실행합니다. 각 사용자의 Google 조직 정책·최초 권한 승인과 실제 메일 도착은 설치 후 별도로 확인해야 합니다.

[실험용 ACP 프로브](experimental/README.md)는 기존 개발 도구를 보존한 별도 실험입니다. 기본 MCP의 설치·사용에는 필요 없으며 자동 승인 중계 기능이 완성됐다는 뜻이 아닙니다.

## 라이선스

[MIT](LICENSE). 의존 패키지에는 각각의 라이선스가 적용됩니다.

TDQS

A3.7/5.0

Scored across 9 tools

Disambiguation3/5

The baseline/seen polling model is spread across wyea_check, wyea_wait, wyea_snapshot, and wyea_ask, and mail sending appears in wyea_create_issue, wyea_notify, and wyea_ask, creating real overlap. Descriptions explicitly warn against calling some together (e.g. not calling wyea_notify after wyea_create_issue), which mitigates but does not eliminate misselection risk.

Naming Consistency4/5

All tools share a consistent wyea_ prefix with clear, mostly single-word verbs or short verb_noun names (wyea_create_issue). Minor deviation: some are nouns/short tokens (wyea_status, wyea_wait) while others are actions, but the pattern is still readable and predictable.

Tool Count4/5

Nine tools is a reasonable, well-scoped size for a comment/decision workflow. A few tools (wyea_ask vs wyea_wait/wyea_snapshot, wyea_notify vs wyea_create_issue) are somewhat redundant, so not every tool strictly earns its place.

Completeness4/5

The surface covers the lifecycle: status check, issue creation, commenting, notifying, waiting, baseline snapshots, and closing. Minor gaps exist (no update/edit or reopen, no issue listing/get), but core agent workflows are covered.

Maintenance

ActivityMaintained
ResponsivenessNo issues