Skip to main content
Glama
README.md
# 회의록 생성 프로젝트 기반 나만의 MCP

비정형 회의 메모를 조회하고, 회의록 작성 프롬프트를 만들고, 초안을 검증한 뒤 사용자 승인 후 저장하는 교육용 로컬 MCP 패키지입니다.

> 이 패키지의 회사명, 인물명, 일정, 장애, 수치, 발언은 모두 교육을 위해 만든 합성 데이터입니다.

## 교육 목표

교육생은 실습을 마치면 다음을 수행할 수 있습니다.

1. MCP의 Host, Server, Tool 역할을 설명한다.
2. Python으로 로컬 STDIO MCP 서버를 실행한다.
3. 비정형 데이터를 읽는 Tool을 구현·수정한다.
4. 검증과 승인 경계가 있는 쓰기 Tool을 설계한다.
5. 자신의 회의록 형식으로 MCP를 커스터마이징한다.
6. Codex 또는 Claude Desktop에 서버를 연결하고 동작을 증명한다.
7. 하네스 엔지니어링 관점에서 도구 설명·스키마·응답·오류를 설계한다.

## 포함 내용

- 난이도별 합성 비정형 회의 메모 3개
- 동작하는 `FastMCP` 서버: 도구 11개, 리소스 3개, 프롬프트 1개
- 표준 회의록 템플릿
- 승인 토큰 기반 저장과 덮어쓰기 감지
- 원문 근거 대조(grounding) 검사기
- 교육생 실습서 5개
- 강사용 정답 예시 1개
- 도메인·근거·하네스 규약 단위 테스트와 STDIO 스모크 테스트

## 빠른 시작

필수 환경: Python 3.11 이상, `uv`

```bash
uv sync --extra dev
uv run pytest -q
uv run python scripts/smoke_stdio.py
```

MCP Inspector를 사용하려면 다음을 실행합니다.

```bash
uv run mcp dev src/meeting_mcp/server.py
```

## 제공 도구

권장 흐름은 아래 순서이며, 모든 응답의 `next_actions` 필드가 다음 단계를 알려줍니다.

```text
DISCOVER → READ → GROUND → DRAFT → CHECK → PREVIEW → [사용자 승인] → SAVED
```

| 단계 | Tool | 읽기/쓰기 | 역할 |
|---|---|---|---|
| DISCOVER | `list_dummy_notes` | 읽기 | 합성 메모 3개 조회 |
| READ | `read_meeting_note` | 읽기 | 원문 조회. 줄 범위 지정과 `L14` 인용 앵커 지원 |
| GROUND | `extract_note_facts` | 읽기 | 결정 후보·날짜·**확정되지 않은 표현**을 줄 번호와 함께 추출 |
| DRAFT | `build_minutes_prompt` | 읽기 | 템플릿과 원문을 결합 |
| CHECK | `validate_minutes_draft` | 읽기 | 구조 검증. `rule_id`·`severity`·`line`·`fix` 제공 (저장 게이트) |
| CHECK | `check_minutes_grounding` | 읽기 | 사람·날짜·수치가 원문에 있는지 대조 (자문, 저장을 막지 않음) |
| PREVIEW | `diff_minutes_against_saved` | 읽기 | 기존 저장본과의 차이 확인 |
| PREVIEW | `preview_save_minutes` | 읽기 | 검증·근거·diff를 묶어 보여 주고 승인 토큰 발급 |
| SAVED | `save_approved_minutes` | **쓰기** | 승인 토큰이 일치할 때만 저장 (유일한 쓰기 도구) |
| OBSERVE | `list_saved_minutes` | 읽기 | 저장된 회의록 목록 |
| OBSERVE | `read_minutes_audit_log` | 읽기 | 저장 감사 로그 조회 |

### 리소스와 프롬프트

| 종류 | URI 또는 이름 | 역할 |
|---|---|---|
| Resource | `note://{note_id}` | 회의 메모 원문 |
| Resource | `template://minutes` | 표준 회의록 템플릿 |
| Resource | `minutes://{note_id}` | 저장된 회의록 |
| Prompt | `write_minutes` | 승인 경계까지 포함한 회의록 작성 워크플로 |

## 하네스 설계

이 서버는 기능뿐 아니라 **모델이 도구를 쓰는 방식**을 설계 대상으로 삼습니다.
자세한 내용은 [실습 5](labs/05-harness-engineering.md)에 있습니다.

- 모든 응답에 `stage`와 `next_actions`가 있어, 모델이 응답만 보고 다음 도구를 고릅니다.
- 오류는 원인 코드·복구 방법·선택 가능한 값을 함께 돌려줍니다.
- 인자 스키마는 평평하게 유지합니다(`{"note_id": "..."}`). Pydantic 모델을 인자
  타입으로 쓰면 `{"params": {...}}`로 중첩되어 호출 형태가 바뀝니다.
- 반환값은 Pydantic 모델이라 `outputSchema`가 자동으로 생깁니다.
- 확실한 검사(구조)만 저장을 막고, 휴리스틱 검사(근거)는 경고로만 알립니다.
- 모든 도구에 `readOnlyHint` / `destructiveHint`를 달아 쓰기 도구를 구분합니다.

## Codex 연결

패키지 루트에서 다음 명령을 실행합니다.

```bash
codex mcp add personal-meeting -- uv --directory "$PWD" run python src/meeting_mcp/server.py
codex mcp list
```

Codex 앱에서는 `Settings → MCP servers → Add server`에서 STDIO 서버로 추가할 수도 있습니다. OpenAI 공식 문서 기준으로 Codex 앱, CLI, IDE 확장은 동일 호스트의 MCP 설정을 공유합니다.

## Claude Desktop 연결

`config/claude_desktop_config.example.json`의 `ABSOLUTE_PROJECT_PATH`를 이 폴더의 절대 경로로 교체한 뒤 Claude Desktop 설정에 반영합니다. 앱을 완전히 종료한 후 다시 실행해야 합니다.

## 권장 실습 프롬프트

```text
personal-meeting MCP에서 사용 가능한 더미 회의 메모를 보여주세요.
```

```text
training_design 메모를 읽고, 제공된 회의록 템플릿에 맞춰 초안을 작성하세요.
원문에 없는 담당자와 기한은 추정하지 마세요.
```

```text
incident_review 메모에서 extract_note_facts로 ambiguity_flags를 먼저 확인하고,
확정되지 않은 항목은 전부 '미정'으로 남긴 회의록을 작성하세요.
```

```text
작성한 회의록을 validate_minutes_draft와 check_minutes_grounding으로 검증하고,
통과하면 preview_save_minutes까지만 실행하세요. 저장은 아직 하지 마세요.
```

## 교육 진행 순서

1. [START_HERE.md](START_HERE.md)
2. [실습 1: 데이터와 Tool](labs/01-data-and-tools.md)
3. [실습 2: 회의록 프롬프트](labs/02-prompt-and-template.md)
4. [실습 3: 검증과 승인](labs/03-validation-and-approval.md)
5. [실습 4: 클라이언트 연결](labs/04-connect-and-demo.md)
6. [실습 5: 하네스 엔지니어링](labs/05-harness-engineering.md)

## 검증 명령

```bash
uv run pytest -q
uv run python scripts/smoke_stdio.py
uv run python scripts/validate_package.py
```

## 설계 원칙

- MCP는 별도 LLM API를 호출하지 않습니다.
- Codex 또는 Claude가 요약하고 MCP는 데이터·검증·저장을 담당합니다.
- 원문에서 확인되지 않은 정보는 생성하지 않으며, 근거 검사기가 이를 기계적으로 대조합니다.
- 최종 저장은 미리보기에서 발급한 승인 토큰과 **사용자의 명시적 승인**이 모두 있어야 합니다.
- 승인 토큰은 (note_id, 본문) 해시라서 승인한 내용과 저장되는 내용이 달라질 수 없습니다.
- 도메인 로직(`core`, `grounding`)과 도구 규약(`server`, `harness`)을 분리합니다.
- 실제 교육에서는 고객·임직원·계약 관련 데이터를 사용하지 않습니다.

## 참고

- 기반 참고 저장소: <https://github.com/kyopark2014/mcp>
- Codex MCP 공식 문서: <https://developers.openai.com/codex/mcp>
- MCP Python SDK: <https://github.com/modelcontextprotocol/python-sdk>

TDQS

A4.5/5.0

Scored across 11 tools

Disambiguation5/5

Each tool targets a distinct step in the meeting-minutes workflow: listing/reading notes, extracting facts, building prompts, validating structure, checking grounding, previewing, saving, listing saved minutes, and auditing. Even similar-sounding tools (diff, preview, check) serve clearly different purposes—diff compares against saved, preview gates with a token, and check verifies source grounding.

Naming Consistency5/5

All tools follow a consistent verb_noun snake_case pattern (list_dummy_notes, read_meeting_note, validate_minutes_draft, save_approved_minutes). Verbs clearly indicate action and objects are always the minute/note entity, making tool selection predictable.

Tool Count5/5

With 11 tools, the surface is well-scoped for a single domain: creating, validating, and saving meeting minutes. Each tool contributes a distinct function from note discovery through audit logging, with no redundancy or bloat.

Completeness5/5

The set covers the full lifecycle: list/read source notes, extract anchors, build prompt, validate draft, check grounding, preview with approval token, save (including overwrite protection via diff), list saved minutes, and audit. The only write path is gated and logged, so there are no dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues