Настоящий OAuth для MCP: как «Authorize» заменяет вставку токенов
claude.ai и ChatGPT ждут OAuth-флоу, а не токен в URL. Вот небольшой OAuth 2.1 сервер, который мы сделали для шлюза — discovery, динамическая регистрация клиента, PKCE.
Вставляешь URL шлюза в ChatGPT, оставляешь auth на OAuth — и ошибка: «MCP server does not implement OAuth». Клиент пытается найти OAuth-конфиг, которого нет. Мы его сделали.
Из чего собрано
Спека авторизации MCP — стандартный OAuth 2.1:
- Discovery —
/.well-known/oauth-protected-resourceуказывает клиенту на authorization server;/.well-known/oauth-authorization-serverперечисляет эндпоинты.401от шлюза несёт заголовокWWW-Authenticate, чтобы клиент нашёл всё сам. - Dynamic Client Registration (RFC 7591) — claude.ai / ChatGPT регистрируются сами и получают
client_id. Без ручной настройки. - Authorize + согласие — пользователь входит в Unyly и разрешает.
- Обмен кода на токен с PKCE.
Приём, который всё упростил
Выданный access-токен — это per-user токен шлюза. Поэтому существующая проверка Authorization: Bearer авторизует его без изменений — второй путь авторизации поддерживать не надо.
Одна оговорка
Куки сессии host-only, поэтому authorization server живёт на unyly.org, а ресурс — gateway.unyly.org/mcp. Стандартный сплит (resource server ≠ authorization server) обходит боль с кросс-субдоменными куками.
Теперь просто выбираешь OAuth и жмёшь Authorize. Попробовать.