main
Gitea에 동적 클라이언트 등록이 없어 MCP 클라이언트가 URL만으로 OAuth 연결을 못 하는 문제를 이 브리지가 인가 서버 역할을 대신해 해결한다. G3X의 plane-mcp-oauth-bridge(upstream_oauth 모드)에서 가져와 Gitea 전용으로 정리했다: Plane PAT 연결 페이지·워크스페이스 헤더·bridge_mode 분기를 없앴다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gitea-mcp-oauth-bridge
Gitea에는 동적 클라이언트 등록(DCR)이 없어서, claude.ai·Cursor 같은 MCP 클라이언트가 URL만으로 OAuth 연결을 못 한다. 이 브리지가 OAuth 인가 서버 역할(DCR 포함)을 대신하고, 로그인은 Gitea로 받아 사용자별 Gitea 토큰을 암호화해 둔 뒤 MCP 요청을 gitea-mcp로 넘긴다. 각 사용자는 자기 Gitea 계정 권한으로 동작한다.
- 주소:
https://git-mcp.sejong.dev(MCP 엔드포인트는/mcp) - 구성: 클라이언트 → Caddy → 브리지(NAS 13332) →
gitea-mcp-oauth컨테이너(호스트 포트 없음, 도커 네트워크gitea-mcp-oauth_default)
클라이언트 --OAuth(MCP, DCR)--> 브리지 --OIDC--> Gitea (git.sejong.dev)
|-- Gitea 토큰 암호화 저장 (SQLite, data/bridge.db)
`-- MCP 프록시 --> http://gitea-mcp-oauth:8080/mcp
브리지가 발급하지 않은 Bearer 토큰(Gitea PAT 등)은 그대로 gitea-mcp로 넘긴다(PASSTHROUGH_UNKNOWN_TOKENS, 기본 켜짐).
그래서 PAT를 넣어 쓰던 클라이언트도 계속 동작한다.
클라이언트 연결
- claude.ai: 설정 → 커넥터 → 커스텀 커넥터 추가 → URL
https://git-mcp.sejong.dev/mcp. 고급 설정은 비워 둔다. - Claude Code:
claude mcp add --transport http gitea https://git-mcp.sejong.dev/mcp후/mcp에서 인증. - Cursor:
"gitea": { "url": "https://git-mcp.sejong.dev/mcp" }
환경 변수
.env.example 참고. .env는 NAS에만 두고(권한 600) 리포에는 올리지 않는다.
| 이름 | 설명 |
|---|---|
PUBLIC_BASE_URL |
https://git-mcp.sejong.dev (발급자·콜백 주소의 기준) |
UPSTREAM_MCP_URL |
http://gitea-mcp-oauth:8080/mcp |
UPSTREAM_HOST_HEADER |
git-mcp.sejong.dev. gitea-mcp -oauth는 -oauth-public-url 호스트만 받는다 |
OIDC_ISSUER |
https://git.sejong.dev |
OIDC_CLIENT_ID / OIDC_CLIENT_SECRET |
아래 Gitea OAuth2 앱 |
OIDC_SCOPES |
기본 openid profile email write:repository write:issue write:user write:organization write:notification write:package write:misc |
ALLOWED_MCP_CLIENTS |
고정 클라이언트 client_id|redirect_uri 콤마 구분. 비우면 DCR만 |
TOKEN_ENCRYPTION_KEY |
Gitea 토큰 암호화·세션 키 (openssl rand -hex 32). 바꾸면 모두 다시 로그인해야 한다 |
PASSTHROUGH_UNKNOWN_TOKENS |
기본 true |
DCR_ENABLED |
기본 true |
Gitea OAuth2 앱
Gitea → 설정 → 애플리케이션 → OAuth2 애플리케이션 생성.
- 이름:
gitea-mcp-oauth-bridge - Redirect URI:
https://git-mcp.sejong.dev/oidc/callback - Confidential Client 체크 (브리지가 client secret으로 토큰을 받는다)
운영 (NAS)
cd /volume1/docker/gitea-mcp-oauth-bridge
git pull --ff-only
sudo -n /usr/local/bin/docker compose up -d --build
sudo -n /usr/local/bin/docker compose logs -f bridge
gitea-mcp-oauth(/volume1/docker/gitea-mcp-oauth)가 먼저 떠 있어야 한다(외부 네트워크 gitea-mcp-oauth_default).
개발
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
pytest
코드 레이아웃
| 경로 | 역할 |
|---|---|
app/main.py |
FastAPI: OAuth AS(메타데이터·DCR·authorize·token), Gitea OIDC 로그인, /mcp 프록시 |
app/dcr.py |
RFC 7591 등록 검증·레이트 리밋 |
app/config.py |
환경 변수 |
app/db.py |
SQLite: 사용자·Gitea 토큰·OAuth 코드·액세스 토큰·등록 클라이언트 |
app/crypto.py |
토큰 Fernet 암호화 |
tests/ |
pytest (Gitea·gitea-mcp는 모킹) |
Languages
Python
99.4%
Dockerfile
0.6%