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) на /registerclaude 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_idclient_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, ставьте перед ним свой обратный прокси, а в качестве резервной копии сохраняйте один файл.

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