Skip to main content
Glama
R0Wi

mcp-gateway

by R0Wi

MCP Gateway

Лёгкий агрегирующий MCP-шлюз для самостоятельного развёртывания: один публичный MCP-эндпоинт перед любым количеством защищённых внутренних MCP-серверов, а также совместимый со спецификацией OAuth 2.1 сервер авторизации, обращённый к MCP-клиенту, — именно то, чего недостаёт большинству существующих шлюзов.

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):

  • Поток авторизации по коду OAuth 2.1 с обязательным PKCE (S256)

  • Динамическая регистрация клиента (RFC 7591) на /register — claude mcp add работает без предварительно согласованных учётных данных

  • Документы метаданных идентификатора клиента (CIMD) — HTTPS-URL в качестве идентификаторов клиента, включая аутентификацию клиента private_key_jwt, публикуются через client_id_metadata_document_supported: true

  • Метаданные сервера авторизации (RFC 8414) + псевдоним обнаружения OIDC

  • Метаданные защищённого ресурса (RFC 9728); ответы 401 содержат WWW-Authenticate: Bearer resource_metadata="…", как того требует коннектор Claude

  • Индикаторы ресурса (RFC 8707) принимаются и привязываются к выдаваемым токенам

  • Недолговечные непрозрачные токены доступа, ротация refresh-токенов, одноразовые коды авторизации — всё хранится в виде хешей; записи клиентов зашифрованы при хранении

  • Loopback-URI перенаправления сопоставляются независимо от порта (CLI Claude Code регистрирует один порт, а авторизуется с другим); для не-loopback URI требуется точная регистрация

  • Небольшой интерфейс входа и согласия на Svelte 5 (единственная локальная учётная запись из конфигурационного файла)

Бэкендная часть:

  • none — публичные серверы (например, Microsoft Learn MCP)

  • bearer — подстановка статического токена (Authorization: Bearer …, например, PAT)

  • headers — произвольные статические заголовки (ключи API)

  • oauth — полноценный OAuth-клиент по спецификации MCP: обнаружение метаданных, CIMD, если вышестоящий AS это поддерживает (шлюз размещает собственный документ метаданных клиента), запасной вариант DCR, PKCE, автоматическое обновление токенов. Подключение выполняется однократно через браузер; токены сохраняются в SQLite в зашифрованном виде (Fernet).

  • Токен шлюза, выданный MCP-клиенту, никогда не передаётся на бэкенды (без сквозной передачи токенов, как требует спецификация); бэкенды видят только те учётные данные, которые хранятся в самом шлюзе.

Агрегация:

  • Инструменты/ресурсы/промпты изолированы по пространству имён каждого бэкенда: 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 автоматически берёт MCP_GATEWAY_ENCRYPTION_KEY из .env. Разместите его за обратным прокси по своему выбору для TLS или откройте порт напрямую.

Сгенерируйте хеш пароля для конфигурационного файла:

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-идентификатор клиента) и открывает ваш браузер: войдите с пользователем из config.yaml, подтвердите согласие — готово. Вставлять токены не нужно.

Подключение Claude.ai / Claude Code web (пользовательский коннектор)

Добавьте https://mcp.example.com/mcp как пользовательский коннектор. Перенаправление браузера на https://claude.ai/api/mcp/auth_callback проходит через тот же поток входа и согласия.

Подключение OAuth-бэкендов

Откройте https://mcp.example.com/ui/backends, войдите и нажмите Подключить рядом с нужным OAuth-бэкендом (например, GitHub MCP). Один раз вас перенаправит на сервер авторизации бэкенда; дальше шлюз автоматически обновляет токены.

Конфигурация

Всё находится в одном 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}" }

Добавление бэкенда — это только изменение конфигурации, без правок кода.

Справочник по аутентификации бэкендов

тип

поля

поведение

none

—

учётные данные не отправляются

bearer

token

Authorization: Bearer <token> при каждом запросе

headers

headers: {Name: value}

статические заголовки (ключи API и т.п.)

oauth

scopes, prefer_dcr, client_id, client_secret

полный OAuth-клиент: CIMD → запасной вариант DCR, PKCE, обновление токенов, зашифрованное хранение

Для бэкендов oauth шлюз публикует собственный документ метаданных клиента (Client ID Metadata Document) по адресу <public_url>/oauth/client-metadata.json и использует его как идентификатор клиента в тех случаях, когда вышестоящий AS заявляет поддержку CIMD (требуется public_url через HTTPS); в остальных случаях применяется резервный путь через 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 флаг --log-level у команды mcp-gateway run работает так же и приоритетнее переменной окружения:

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

метаданные AS (RFC 8414) + псевдоним OIDC

/authorize, /token, /register, /revoke

эндпоинты OAuth 2.1 (PKCE, DCR, revoking)

/ui/authorize

вход и согласие (Svelte 5)

/ui/backends

статус подключения бэкендов / подключение / отключение

/oauth/client-metadata.json

собственный CIMD-документ шлюза (вышестоящее звено)

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

поток подключения вышестоящего OAuth

/healthz

проверка жизнеспособности

Замечания по безопасности

  • PKCE (S256) обязателен; коды авторизации одноразовые и истекают через 5 минут.

  • Refresh-токены ротируются при каждом использовании (требование OAuth 2.1 для публичных клиентов).

  • Токены доступа, refresh-токены и коды авторизации хранятся только в виде SHA-256-хешей.

  • Зарегистрированные клиентские записи и учётные данные вышестоящих серверов зашифрованы при хранении (Fernet): используется auth.encryption_key, парольные фразы растягиваются через scrypt с солью, уникальной для каждой базы.

  • Экран согласия показывает имя клиента и точный адрес перенаправления, а при loopback- redirect предупреждает (в соответствии с рекомендациями CIMD о защите от подмены localhost).

  • Токены, выданные 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/oauth_server.py — сервер авторизации для клиентской стороны. Строится на обработчиках авторизационного сервера из MCP SDK и на CIMD-менеджере FastMCP, а не на собственной реализации протокола; шлюз добавляет хранение в SQLite, транзакционный поток login/consent и политику выдачи/ротации токенов.

  • src/mcp_gateway/upstream.py — клиенты бэкендов. OAuth-бэкенды используют официальный SDK OAuthClientProvider (discovery, CIMD/DCR, refresh) с зашифрованным хранением токенов в SQLite и процессом подключения через браузер.

  • src/mcp_gateway/gateway.py — FastMCP-сервер; каждый бэкенд монтируется как прокси в реальном времени в своём пространстве имён.

  • src/mcp_gateway/app.py / web.py — FastAPI-приложение: JSON API для UI, callback от вышестоящего сервера, CIMD-документ, статический Svelte; приложение FastMCP (MCP-эндпоинт + OAuth-маршруты + well-known) смонтировано в корне.

  • ui/ — SPA на Svelte 5 + Vite (вход, согласие, бэкенды).

Однозначная архитектура по замыслу (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