Files
gitea-mcp-oauth-bridge/README.md
T
ysj7705andClaude Opus 5.5 916d149ab5 Gitea MCP OAuth 브리지 (DCR, Gitea 로그인)
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>
2026-10-22 18:20:02 +09:00

3.6 KiB

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는 모킹)