mcp-gateway
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/mcpClaude 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}" }Добавление бэкенда — это только изменение конфигурации, без правок кода.
Справочник по аутентификации бэкендов
тип | поля | поведение |
| — | учётные данные не отправляются |
|
|
|
|
| статические заголовки (ключи API и т.п.) |
|
| полный 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-gatewaydocker-compose.yml уже передаёт эту переменную в контейнер; если она не задана, по умолчанию используется info.
Вне Docker флаг --log-level у команды mcp-gateway run работает так же и приоритетнее переменной окружения:
mcp-gateway run -c config.yaml --log-level debugЭндпоинты
Путь | Назначение |
| MCP-эндпоинт (Streamable HTTP) |
| метаданные защищённого ресурса (RFC 9728) |
| метаданные AS (RFC 8414) + псевдоним OIDC |
| эндпоинты OAuth 2.1 (PKCE, DCR, revoking) |
| вход и согласие (Svelte 5) |
| статус подключения бэкендов / подключение / отключение |
| собственный CIMD-документ шлюза (вышестоящее звено) |
| поток подключения вышестоящего OAuth |
| проверка жизнеспособности |
Замечания по безопасности
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-бэкенды используют официальный SDKOAuthClientProvider(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, ставьте перед ним свой обратный прокси, а в качестве резервной копии сохраняйте один файл.
This server cannot be installed
Maintenance
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
- FlicenseNot gradedqualityNot gradedmaintenanceAggregates 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
- FlicenseNot gradedqualityBmaintenanceMulti-tenant MCP server with OAuth 2.1 authorization, enabling tenant-scoped tool access and audit logging.
- AlicenseAqualityCmaintenanceA 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.510MIT
- AlicenseNot gradedqualityCmaintenanceAuthenticating reverse proxy for MCP servers providing credential isolation, OAuth2 token management, and composite tool aggregation.BSD Zero Clause
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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