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 종료를 원한다면 자체 리버스 프록시를 앞에 배치하면 되고, 파일 하나만 백업하면 됩니다.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

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
    B
    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
    10
    MIT

View all related MCP servers

Related MCP Connectors

  • Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.

  • MCP Hub: AI service discovery, per-user OAuth, and multi-service workflow orchestration

  • An authenticated remote MCP server for user-owned devices and one-shot capability invocation.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/R0Wi/mcp-gateway'

If you have feedback or need assistance with the MCP directory API, please join our Discord server