Skip to main content
Glama
TaegyunB
by TaegyunB
README.md
# github-commits-mcp (Python / stdio)

GitHub 계정의 오늘자 커밋을 조회하고, 로컬 저장소의 git 작업(status/diff/add/commit/push)과 GitHub 이슈 생성을 지원하는 MCP(Model Context Protocol) 서버.

Claude 같은 MCP 클라이언트가 이 서버를 stdio로 실행하면, 아래 tool/resource/prompt를 통해 LLM이 GitHub 활동 조회, 로컬 커밋 작업, 이슈 등록을 대신 수행할 수 있다.

원래 Java(Spring Boot + Spring AI MCP Server)로 구현했던 [Mcp_Git](https://github.com/TaegyunB/Mcp_Git)을 Python MCP SDK로 이식한 버전이다.

## 기술 스택

- Python >= 3.10
- [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk) (`mcp` 패키지, `FastMCP` 고수준 API)
- httpx (GitHub REST API 호출)
- 표준 라이브러리 `subprocess` (로컬 git 명령 실행)

## 아키텍처

MCP 서버는 **stdio transport**로 동작한다 (HTTP 서버, 포트 없음). `FastMCP` 인스턴스에 `@mcp.tool()` / `@mcp.resource()` / `@mcp.prompt()` 데코레이터로 등록된 함수를 클라이언트가 표준 MCP 메서드(`tools/list`, `tools/call`, `resources/list`, `resources/read`, `prompts/list`, `prompts/get`)로 요청하면 해당 함수가 실행된다.

```
mcp_python/
├── pyproject.toml
├── .gitignore
├── scripts/
│   └── smoke_test.py        # 실제 MCP 클라이언트로 서버에 접속해 확인하는 스모크 테스트
└── src/github_commits_mcp/
    ├── __init__.py
    ├── server.py             # 엔트리포인트 — FastMCP 인스턴스, tool/resource/prompt 등록, stdio 실행
    ├── github_tools.py       # GitHub API 연동 (오늘 커밋 조회, 이슈 생성)
    ├── git_tools.py          # 로컬 git 명령 실행 (status/diff/add/commit/push)
    ├── resources.py          # 커밋 메시지 컨벤션 문서 (resource)
    └── prompts.py            # 이슈 생성용 프롬프트 템플릿 (prompt)
```

## 제공 기능

### Tools

| 이름 | 설명 | 파라미터 |
|---|---|---|
| `get_todays_commits` | GitHub 계정(`GITHUB_USERNAME`)이 오늘(한국시간 기준) 올린 모든 레포지토리의 커밋과 각 커밋의 변경 파일 목록을 조회한다. | 없음 |
| `create_issue` | 지정한 레포지토리(`owner/repo`)에 제목/본문으로 이슈를 생성한다. | `repo`, `title`, `body` |
| `git_status` | 로컬 저장소의 변경 파일 목록을 조회한다 (`git status --short`). | `repo_path` |
| `git_diff` | 로컬 저장소의 변경 내용을 조회한다 (`git diff HEAD`, staged/unstaged 모두 포함). | `repo_path` |
| `git_add` | 모든 변경사항을 스테이징한다 (`git add -A`). | `repo_path` |
| `git_commit` | 스테이징된 변경사항을 커밋한다 (`git commit -m`). | `repo_path`, `message` |
| `git_push` | 현재 브랜치를 원격 저장소로 push한다. 되돌리기 어려운 작업이라 실행 전 사용자 확인을 거치도록 tool description에 명시돼 있다. | `repo_path` |

`get_todays_commits`는 KST 자정~자정 범위를 ISO8601(`+09:00` 오프셋)로 만들어 GitHub Search Commits API(`GET /search/commits`)를 `author:` + `committer-date:` 조건으로 호출하고, 커밋마다 상세 API(`GET /repos/{repo}/commits/{sha}`)를 추가 호출해 변경 파일 목록을 채운다.

### Resources

| URI | 이름 | 설명 |
|---|---|---|
| `guide://commit-convention` | 커밋 메시지 컨벤션 | Conventional Commits 기반의 이 프로젝트 커밋 메시지 작성 규칙. `git_diff`로 변경 내용을 확인한 뒤, 이 문서를 참고해 규칙에 맞는 커밋 메시지를 작성하도록 돕는다. |

### Prompts

| 이름 | 설명 | 파라미터 |
|---|---|---|
| `create_issue_prompt` | 배경/작업 내용/기대 결과 형식으로 이슈 본문을 정리해 `create_issue` tool 호출을 안내하는 프롬프트. | `repo`, `title`, `body` |

## 권장 작업 흐름 (커밋)

1. `git_status` / `git_diff` → 변경 내용 확인
2. `git_add` → 스테이징
3. `guide://commit-convention` → 컨벤션 확인
4. (LLM이 메시지 작성)
5. `git_commit`
6. `git_push` (사용자 확인 후)

## 설정

- Transport: **stdio** (표준입출력, HTTP 서버/포트 없음)
- 인증: `GITHUB_TOKEN` 환경변수로 주입되는 GitHub Personal Access Token을 서버가 자체 보유해 사용 (사용자별 별도 OAuth 동의 절차 없음)
- 환경변수
  | 변수명 | 필수 | 기본값 | 설명 |
  |---|---|---|---|
  | `GITHUB_TOKEN` | 필수 (`get_todays_commits`, `create_issue` 호출 시) | 없음 | GitHub REST API 인증용 PAT |
  | `GITHUB_USERNAME` | 선택 | `TaegyunB` | `get_todays_commits`가 조회할 GitHub 계정 |

## 실행 방법

### 사전 준비

```powershell
# GitHub PAT 발급 후 환경변수로 설정 (repo 등 필요한 스코프 부여)
$env:GITHUB_TOKEN = "ghp_xxxxxxxxxxxx"
```

### 가상환경 생성 및 설치

```powershell
py -3 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .
```

### 실행

```powershell
.\.venv\Scripts\python.exe -m github_commits_mcp.server
```

정상 기동 시 stdin/stdout으로 JSON-RPC 기반 MCP 요청을 받는다 (별도 포트 없음).

### 스모크 테스트

`scripts/smoke_test.py`는 실제 MCP 클라이언트로 서버 프로세스를 띄우고 `tools/list`, `resources/list`, `prompts/list`, `resources/read`, `tools/call`을 순서대로 호출해 정상 동작을 확인한다.

```powershell
.\.venv\Scripts\python.exe scripts\smoke_test.py
```

## MCP 클라이언트 연결

stdio transport이므로 클라이언트가 서버 프로세스를 직접 실행한다.

**Claude Code (CLI):**

```powershell
claude mcp add github-commits-mcp -e GITHUB_TOKEN=ghp_xxxxxxxxxxxx -- <프로젝트 경로>\.venv\Scripts\python.exe -m github_commits_mcp.server
```

## 주의사항

- `git_push`, `create_issue`는 원격 상태를 바꾸는 되돌리기 어려운 작업이므로, LLM이 실행 전 사용자 확인을 거치도록 tool description에 명시돼 있다.
- `GITHUB_TOKEN`은 서버가 자체적으로 보유하는 구조라, 이 서버를 실행할 수 있는 누구나 해당 토큰 권한으로 GitHub API를 호출할 수 있다.
- GitHub Search Commits API는 인증된 사용자 기준 **분당 10회** 요청 제한이 있다. `get_todays_commits`는 검색 1회 + 커밋마다 상세 조회 1회씩 호출하므로, 하루에 커밋을 많이 올린 날에는 rate limit(403)에 걸릴 수 있다.
- Windows에서 `subprocess.run`으로 git 명령을 실행할 때 `stdin`을 명시적으로 `DEVNULL`로 지정한다. stdio 서버의 stdin은 부모 프로세스가 비동기로 점유 중인 파이프라, 자식 프로세스가 이를 상속받으면 핸들 충돌로 데드락이 발생할 수 있기 때문이다 (`git_tools.py`의 `_run_git` 참고).