Skip to main content
Glama
R0Wi

mcp-gateway

by R0Wi

MCP Gateway

가볍고 자체 호스팅 방식의 MCP 애그리게이터 게이트웨이: 보호된 백엔드 MCP 서버들을 하나의 공개 MCP 엔드포인트 앞에 두는 구조로, MCP 클라이언트를 상대하는 OAuth 2.1 인가 서버를 갖춘 것이 핵심입니다 — 기존 게이트웨이 대부분이 빠뜨린 부분입니다.

Claude Code / Claude.ai ──OAuth 2.1 (DCR/CIMD + PKCE)──▶ MCP Gateway ──own credentials──▶ GitHub MCP
                                                          │                              ▶ Microsoft Learn MCP
                                                          └── /mcp (Streamable HTTP)      ▶ …more backends

FastAPI + FastMCP 기반이며, 단일 YAML 파일로 설정합니다. 상태를 암호화된 SQLite 데이터베이스 하나에 저장하고, 작고 독립적인 컨테이너 하나로 배포됩니다. 리버스 프록시는 필요하지 않지만 TLS를 위해 원한다면 게이트웨이 앞에 둘 수 있습니다.

기능

클라이언트 측면 (MCP 인증 사양, 2025-11-25):

  • **PKCE(S256)**을 필수로 하는 OAuth 2.1 인가 코드 흐름

  • /register에서 동적 클라이언트 등록(RFC 7591) — claude mcp add가 사전에 자격 증명을 공유하지 않아도 동작

  • 클라이언트 ID 메타데이터 문서(CIMD) — HTTPS URL을 클라이언트 ID로 사용하며 private_key_jwt 클라이언트 인증을 포함, client_id_metadata_document_supported: true로 지원을 광고

  • 인가 서버 메타데이터(RFC 8414) + OIDC 디스커버리 별칭

  • 보호 리소스 메타데이터(RFC 9728); 401 응답에는 Claude의 커넥터가 요구하는 대로 WWW-Authenticate: Bearer resource_metadata="…"가 포함

  • 리소스 인디케이터(RFC 8707)를 수락하고 발급된 토큰에 귀속

  • 수명이 짧은 불투명 액세스 토큰, 회전하는 리프레시 토큰, 일회용 인가 코드 — 모두 해시된 상태로 저장. 클라이언트 기록은 암호화되어 보관

  • 루프백 리다이렉트 URI는 포트에 무관하게 매칭됩니다(Claude Code CLI가 포트 하나로 등록하고 다른 포트로 인가하는 상황 대응). 루프백이 아닌 URI는 정확히 등록해야 합니다

  • Svelte 5 로그인 및 동의 UI (설정 파일의 단일 로컬 사용자)

백엔드 측면:

  • none — 공개 서버 (예: Microsoft Learn MCP)

  • none — 테스트 대상

  • bearer — 고정 토큰 주입 (Authorization: Bearer …, 예: PAT)

  • headers — 임의의 고정 헤더 (API 키)

  • oauth — MCP 사양에 따른 완전한 OAuth 클라이언트: 메타데이터 디스커버리, 업스트림 AS가 지원할 경우 CIMD(게이트웨이 자체의 클라이언트 메타데이터 문서 호스팅), 그 외 DCR 폴백, PKCE, 자동 토큰 갱신. 브라우저에서 한 번만 연결하면 되며 토큰은 암호화(Fernet)되어 SQLite에 저장됩니다

  • 클라이언트가 받은 게이트웨이 토큰은 절대 업스트림으로 전달되지 않습니다(스펙이 요구하는 것처럼 토큰 패스스루 없음). 백엔드는 게이트웨이가 보관한 자격 증명만 볼 수 있습니다

집계:

  • 도구/리소스/프롬프트가 백엔드별로 네임스페이스화됨: github_create_issue, msdocs_microsoft_docs_search, …

  • Streamable HTTP 상에서 라이브 프록시 동작. 다운되거나 아직 연결되지 않은 백엔드는 표류을 망가질 수 있지만, 실제로는 그 백엔드의 도구만 제외될 뿐다

  • 내장 gateway_status 도구

Related MCP server: MCP OAuth Test

빠른 시작

cp config.example.yaml config.yaml
$EDITOR config.yaml                                   # set public_url, users, backends
cp .env.example .env
$EDITOR .env                                           # set MCP_GATEWAY_ENCRYPTION_KEY (openssl rand -base64 32)
docker compose up -d

게이트웨이는 단독 실행되며 :8000 포트에서 수신합니다. docker compose가 .env에서 MCP_GATEWAY_ENCRYPTION_KEY를 자동으로 읽어옵니다. TLS가 필요하면 원하는 리버스 프록시 뒤에 두거나 포트를 직접 노출하세요.

config 파일 암호 해시 생성:

docker compose run --rm mcp-gateway mcp-gateway hash-password

Claude Code (CLI) 연결

claude mcp add --transport http gateway https://mcp.example.com/mcp

Claude Code가 게이트웨이의 인증 서버를 검색하고, 자체 등록(DCR)하거나 자신의 CIMD 클라이언트 ID를 사용해 브라우저를 엽니다. config.yaml의 사용자로 로그인하고 승인하면 끝입니다. 붙여넣을 토큰은 없습니다.

Claude.ai / Claude Code 웹(사용자 지정 커넥터) 연결

https://mcp.example.com/mcp를 사용자 지정 커넥터로 추가합니다. 브라우저에서 https://claude.ai/api/mcp/auth_callback으로 리다이렉트되어 동일한 로그인/승인 흐름을 거칩니다.

OAuth 백엔드 연결

https://mcp.example.com/8/ui/backends를 열고 로그인한 뒤 각 OAuth 백엔드(예: GitHub MCP) 옆의 Connect을 누릅니다. 백엔드 인증 서버로 한 번 리다이렉트된 이후에는 게이트웨이가 토큰을 자동으로 갱신합니다.

설정

모든 항목은 하나의 YAML 파일에 들어 있습니다(config.example.yaml 참조). 값은 ${ENV_VAR} / ${ENV_VAR:-default} 확장을 지원합니다.

server:
  public_url: https://mcp.example.com   # behind your reverse proxy

auth:
  encryption_key: ${MCP_GATEWAY_ENCRYPTION_KEY}   # encrypts secrets at rest
  users:
    - username: admin
      password_hash: "$2b$12$…"          # mcp-gateway hash-password
  access_token_expiry_seconds: 3600
  refresh_token_expiry_seconds: 2592000

storage:
  path: /data/gateway.db                 # SQLite; the only state

backends:
  github:                                # → tools namespaced github_*
    url: https://api.githubcopilot.com/mcp/
    auth:
      type: oauth
      # GitHub's authorization server supports neither CIMD nor DCR, so
      # register a GitHub OAuth App and provide its credentials directly:
      client_id: ${GITHUB_OAUTH_CLIENT_ID}
      client_secret: ${GITHUB_OAUTH_CLIENT_SECRET}
  microsoft-docs:                        # → tools namespaced microsoft-docs_*
    url: https://learn.microsoft.com/api/mcp
    auth: { type: none }
  something-with-a-pat:
    url: https://example.com/mcp
    auth: { type: bearer, token: "${SOME_PAT}" }

백엔드 추가는 설정 파일만 변경하면 됩니다 — 코드 수정 없이요.

백엔드 인증 참고

type

fields

behavior

none

자격 증명을 보내지 않음

bearer

token

모든 요청에 Authorization: Bearer <token> 헤더를 붙입니다

headers

headers: {Name: value}

정적 헤더(API 키 등)를 붙입니다

oauth

scopes, prefer_dcr, client_id, client_secret

풀타 OAuth 클라이언트: CIMD → DCR 폴백, PKCE, 갱신, 암호화 저장

oauth 백엔드의 경우 게이트웨이는 <public_url>/oauth/client-metadata.json에 자체 Client ID Metadata Document를 호스팅하며, 업스트림 AS가 CIMD 지원을 광고할 때(HTTPS public_url 필요) 이를 클라이언트 ID로 사용합니다. 그렇지 않으면 Dynamic Client Registration으로 폴백됩니다. 만약 업스트림 AS가 둘 다 지원하지 않는 경우(예: GitHub)에는 client_id(기밀 앱이면 client_secret도)를 설정하여 사전 등록된 OAuth 클라이언트를 사용하면 됩니다 — 이 경우 CIMD/DCR은 완전히 건너뜁니다.

로깅

게이트웨이는 stdout/stderr로 레벨(docker logs, docker compose logs -f)을 기록합니다. 기본값은 INFO: 시작/종료, 구성 요약, 로그인 시도, OAuth 인가/동의/토큰발급, 업스트림 백엔드 연결/해제, 백엔드 마운트 상태를 보여줍니다. DEBUG는 클라이언트 생성, 토큰 갱신, CIMD 새로고침, 데저 스토리지 정리 등 더 상세한 정보를 포함합니다. 어떤 수준이든 자격 증명이나 토큰을 기록하지 않습니다.

MCP_GATEWAY_LOG_LEVEL 환경 변수(debug, info, warning, error, critical)로 로그 레벨을 설정합니다:

# .env (picked up by docker compose)
MCP_GATEWAY_LOG_LEVEL=debug
# or inline
docker compose run --rm -e MCP_GATEWAY_LOG_LEVEL=debug mcp-gateway

docker-compose.yml는 이 변수를 이미 컨테이너에 전달하며, 환경 변수가 없으면 기본값은 info입니다.

Docker 외부에서도 mcp-gateway run을 사용할 때 --log-level 옵션이 동일하게 동작되며 환경 변수보다 우선합니다:

mcp-gateway run -c config.yaml --log-level debug

엔드포인트

경로

용도

/mcp

MCP 엔드포인트(Streamable HTTP)

/.well-known/oauth-protected-resource[/mcp]

RFC 9728 보호 리소스 메타데이터

/.well-known/oauth-authorization-server

RFC 8414 AS 메타데이터 (+ OIDC 별칭)

/authorize, /token, /register, /revoke

OAuth 2.1 엔드포인트 (PKCE, DCR, 폐기)

/ui/authorize

로그인 및 동의 (Svelte 5)

/ui/backends

백엔드 연결 상태 / 연결 / 연결 해제

/oauth/client-metadata.json

게이트웨이의 자체 CIMD 문서 (업스트림 걷기)

/oauth/connect/<backend>, /oauth/callback

업스트림 OAuth 연결 흐름

/healthz

활성 확인

보안 참고 사항

  • PKCE(S256)은 필수이며, 인가 코드는 일회성이고 5분 후 만료됩니다.

  • 리프레시 토큰은 사용할 때마다 회전합니다(OAuth 2.1 공개 클라이언트 요건).

  • 액세스/리프레시 토큰·인가 코드는 SHA-256 해시로만 저장합니다.

  • 등록된 클라이언트 레코드와 업스트림 자격 증명은 저장 중 암호화됩니다(auth.encryption_key; 패스프레이즈는 scrypt + 데이터베이스별 salt로 키 확장).

  • 동의 화면에는 클라이언트 이름과 정확한 리다이렉트 대상을 보여주고, 루프백 리다이렉트에 대해서는 사양의 CIMD 로컬호스트 사칭 가이드에 따라 경고합니다.

  • MCP 클라이언트에게 발급된 토큰이 백엔드로 전달되지 않고, 백엔드 자격 증명이 MCP 클라이언트로 유출되지 않습니다.

  • 세션은 서명(itsdangerous)되고, HttpOnly, SameSite=Lax, HTTPS에서 Secure입니다.

  • 자격 증명은 로그에서 절대 노출되지 않습니다.

남은 작업

uv venv && uv pip install -e ".[dev]"     # or: pip install -e ".[dev]"
(cd ui && npm install && npm run build)   # build the Svelte UI
pytest                                    # 35 tests incl. full e2e OAuth flows
mcp-gateway run -c config.yaml

테스트 스위트는 실제 게이트웨이(및 두 번째 인스턴스가 OAuth로 보호된 업스트림 역할)를 실행하여 완전한 DCR/CIMD + PKCE 흐름을 HTTP에서 수행합니다.

아키텍처

  • src/mcp_gateway/authorization_server.py — 클라이언트를 마주하는 OAuth 인가 서버입니다. MCP SDK의 authorization-server 핸들러와 FastMCP의 CIMD 매니저를 기반으로 하여 자체 프로토콜 구현을 하지 않고, SQLite 저장, 로그인/동의 트랜잭션 흐름, 토큰 발급·순환 정책을 추가합니다.

  • src/mcp_gateway/upstreamp.py — 백엔드 클라이언트. OAuth 백엔드는 공식 SDK OAuthClientProvider(디스커버리, CIM/DCR, 갱신)을 암호화된 SQLite 토큰 저장 및 브라우저 기반 연결 흐름으로 확장합니다.

  • src/mcp_gateway/gateway.py — FastMCP 서버. 각 백엔드는 해당

  • src/mcp_gateway/gateway.py — FastMCP 서버.env에서 네임스페이스 아래로 라이브 프록시로 마운트됩니다.

  • src/mcp_gateway/app.py / web.py — FastAPI 애플리케이션. UI JSON API, 업스트림 콜백, CIMD 문서표? (ui), 정적 Svelte 앱을 제공하고, 롯트에 FastMCP 애플리케이션(MCP 엔드포인트 + OAuth 경로 + well-known)을 마운트합니다.

  • ui/ — Svelte 5 + Vite SPA (로그인, 동의, 백엔드).

단일 인스턴스 방식(SQLite + 인메모리 연결 흐름). 독립 실행형으로 TLS 종료를 원한다면 자체 리버스 프록시를 앞에 배치하면 되고, 파일 하나만 백업하면 됩니다.

Maintenance

ActivityMaintained
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Aggregates multiple MCP servers behind a single, secure endpoint with unified tool/resource discovery, OAuth authentication, and resilient request routing. Enables users to manage and interact with multiple MCP backends through one centralized interface with load balancing and circuit breakers.
    2
    -
  • F
    license
    Not graded
    quality
    D
    maintenance
    Multi-tenant MCP server with OAuth 2.1 authorization, enabling tenant-scoped tool access and audit logging.
    -
  • A
    license
    A
    quality
    C
    maintenance
    A federated MCP gateway that consolidates multiple plain-HTTP backends into a single, OAuth-protected MCP server, enabling agents to access diverse tools through one endpoint with centralized authentication and audit.
    5
    12
    MIT