Skip to main content
Glama
beaconfire-projects

mcp-oauth-test

FastMCP OIDC Server

Это MCP-сервер, защищённый входом через OIDC, написанный с использованием FastMCP. Он использует OIDCProxy из FastMCP: MCP-клиент проходит аутентификацию через метаданные OAuth, предоставляемые сервером, а фактический вход и обмен токенами пересылаются в QA OIDC-провайдер.

В настоящее время подключён QA MGT OpenAPI, сгенерированы MCP-инструменты, связанные с трейни, заказами, товарами, клиентами, кампусным наймом и международным наймом.

Адрес обнаружения OIDC по умолчанию настроен как:

https://auth-qa.drillinsight.com/.well-known/openid-configuration

Подготовка к аутентификации

Сначала зарегистрируйте OAuth-приложение в auth-qa.drillinsight.com и добавьте следующий адрес обратного вызова в белый список:

http://localhost:8000/auth/callback

При развёртывании по другому адресу замените http://localhost:8000 на значение BASE_URL. Адрес обратного вызова должен точно совпадать с BASE_URL в FastMCP.

Локальный запуск

cp .env.example .env
# 编辑 .env,至少填写 OIDC_CLIENT_ID 和 OIDC_CLIENT_SECRET
uv sync
uv run mcp-oidc-server

Также можно запустить модуль напрямую:

uv run python -m oidc_mcp_server.server

Сервис по умолчанию прослушивает http://127.0.0.1:8000. Если MCP-клиент работает на другой машине или в контейнере, установите BASE_URL, доступный клиенту, и подходящий HOST (например, 0.0.0.0).

Плагин Claude Code

Репозиторий содержит приватный marketplace Claude Code и MCP-плагин:

.claude-plugin/marketplace.json
└── plugins/mcp-oauth-test/
    ├── .claude-plugin/plugin.json
    ├── .mcp.json
    └── README.md

Плагин только подключает Claude Code к уже развёрнутому удалённому MCP-сервису и не запускает локально Python-сервис. Для разработки и тестирования можно загрузить его напрямую:

claude --plugin-dir ./plugins/mcp-oauth-test

Плагин жёстко подключён к MCP-серверу среды разработки:

https://api-mcp-oauth-dev.beaconfireinc.com/mcp

Также можно установить из приватного marketplace:

/plugin marketplace add /path/to/mcp-oauth-test
/plugin install mcp-oauth-test@authsome-internal

Текущий корень marketplace — это корень репозитория. Пожалуйста, храните этот marketplace в приватном GitHub-репозитории компании и не публикуйте его в публичный marketplace. Для общей среды используйте HTTPS-адрес и ограничьте доступ пользователей компании на стороне корпоративного IdP и MCP-сервера.

Почему используется OIDCProxy

Верхнеуровневый auth-qa.drillinsight.com не требует поддержки DCR или CIMD. OIDCProxy предназначен именно для такого сценария:

ChatGPT ── MCP OAuth / CIMD ──> FastMCP OIDCProxy
                                      │
                                      └── 固定 client_id/client_secret ──> auth-qa.drillinsight.com

Заранее на верхнем уровне нужно зарегистрировать только OAuth-приложение FastMCP и настроить ${BASE_URL}/auth/callback. CIMD, используемый ChatGPT, обрабатывается прокси-слоем FastMCP и не пересылается верхнему OAuth-серверу.

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

При создании пользовательского MCP в ChatGPT в расширенных настройках OAuth выберите «Регистрация клиента»:

客户端标识元数据文档(CIMD)

Текущая информация, генерируемая коннектором ChatGPT:

CIMD Client ID / 客户端元数据 URL:
https://chatgpt.com/oauth/0Buhw3sHVv1-/client.json

ChatGPT Callback URL:
https://chatgpt.com/connector/oauth/0Buhw3sHVv1-

Сам URL CIMD — это client_id, который ChatGPT использует при обращении к OAuth-прокси FastMCP. Его не нужно и не следует регистрировать в верхнем auth-qa.drillinsight.com.

В этом проекте существуют два разных уровня OAuth Client ID:

Цепочка OAuth

client_id

Место настройки

ChatGPT → FastMCP OIDCProxy

https://chatgpt.com/oauth/0Buhw3sHVv1-/client.json

Предоставляется автоматически ChatGPT, после выбора CIMD заполнять вручную не нужно

FastMCP OIDCProxy → auth-qa.drillinsight.com

app_74a4b555-5b87-4212-9dda-d584fa78caf8

OIDC_CLIENT_ID MCP-сервера

Соответствующий поток данных:

ChatGPT
  │ client_id=https://chatgpt.com/oauth/0Buhw3sHVv1-/client.json
  ▼
FastMCP OIDCProxy
  │ client_id=app_74a4b555-5b87-4212-9dda-d584fa78caf8
  ▼
auth-qa.drillinsight.com

Конфигурация переменных окружения MCP-сервера:

OIDC_CLIENT_ID=app_74a4b555-5b87-4212-9dda-d584fa78caf8
OIDC_CLIENT_SECRET=<上游 OAuth Server 颁发的客户端密钥>

Верхнему OAuth-серверу достаточно настроить адрес обратного вызова FastMCP для приложения app_...:

https://heroic-verbally-crawdad.ngrok-free.app/auth/callback

Не настраивайте адрес обратного вызова ChatGPT https://chatgpt.com/connector/oauth/... на верхнем OAuth-сервере; этот адрес используется прокси-слоем FastMCP после завершения аутентификации.

В начале аутентификации в обычных журналах сначала должен появиться CIMD Client ID ChatGPT:

CIMD document fetched and validated
GET /authorize?client_id=https://chatgpt.com/oauth/.../client.json ... 302

Затем FastMCP использует app_74a4b555-... для перехода на верхний OAuth-сервер.

Конфигурация MCP-клиента

Настройте адрес MCP как:

http://localhost:8000/mcp

FastMCP предоставит следующие адреса обнаружения аутентификации:

http://localhost:8000/.well-known/oauth-authorization-server
http://localhost:8000/.well-known/oauth-protected-resource/mcp

Клиент должен автоматически считывать эти конечные точки обнаружения MCP/OAuth. После успешного входа можно вызвать два защищённых инструмента:

  • ping: проверка работоспособности.

  • who_am_i: возвращает client_id, scope и claims, извлечённые FastMCP из текущего токена аутентификации.

Параметры конфигурации

Переменная окружения

Обязательна

Значение по умолчанию

Описание

OIDC_CLIENT_ID

Да

-

Идентификатор клиента верхнего OIDC

OIDC_CLIENT_SECRET

Одно из двух

-

Секрет конфиденциального клиента

JWT_SIGNING_KEY

Одно из двух

-

Ключ подписи токенов FastMCP для public PKCE-клиента или производственной среды

OIDC_CONFIG_URL

Нет

URL обнаружения QA

Адрес обнаружения OIDC

BASE_URL

Нет

http://localhost:8000

Публичный адрес MCP-сервера

OIDC_REQUIRED_SCOPES

Нет

openid

Scope для запроса авторизации OAuth/рекламы по умолчанию; не используется для проверки scope токена доступа

OIDC_TOKEN_ISSUER

Нет

Issuer из обнаружения OIDC

Значение для проверки iss JWT; задаётся при переписывании issuer в auth middleware

OIDC_JWKS_URI

Нет

https://auth-qa.drillinsight.com/oauth/jwks

Адрес JWKS для пользовательского issuer токена

OIDC_TOKEN_AUDIENCE

Нет

-

Необязательное значение для проверки aud JWT

HOST

Нет

127.0.0.1

Адрес прослушивания

PORT

Нет

8000

Порт прослушивания

MGT_API_BASE_URL

Нет

Адрес QA MGT

Базовый URL фактического вызова MGT API

MGT_OPENAPI_SPEC_PATH

Нет

specs/mgt-qa-openapi.json

Путь к локальной спецификации OpenAPI

В производственной среде явно задайте случайный JWT_SIGNING_KEY и используйте BASE_URL с HTTPS. Не коммитьте .env или любые секреты клиента в Git.

Пользовательский Issuer токена

Если iss токена — не issuer, возвращаемый обнаружением OIDC, а переписан auth middleware в адрес арендатора, например:

实际 token iss:
https://api-authsome-qa.drillinsight.com/auth-middleware/t_adecdb63-afab-4346-a1aa-b50bbbae7aee/

Установите:

OIDC_TOKEN_ISSUER=https://api-authsome-qa.drillinsight.com/auth-middleware/t_adecdb63-afab-4346-a1aa-b50bbbae7aee/
OIDC_JWKS_URI=https://auth-qa.drillinsight.com/oauth/jwks

OIDC_CONFIG_URL по-прежнему используется для обнаружения конечных точек входа и авторизации OAuth; OIDC_TOKEN_ISSUER используется только для проверки iss JWT-токена доступа. Они могут различаться. OIDC_TOKEN_ISSUER должен точно совпадать с iss в токене, включая завершающий /.

Текущий проект не проверяет scope или scp claim токена доступа, поскольку исторические токены MGT используют нестандартный формат scope. OIDC_REQUIRED_SCOPES по-прежнему используется для запроса авторизации OAuth, но не блокирует действительные токены без стандартного scope claim. Проверка подписи, issuer, audience, срока действия и JWKS сохраняется.

Интеграция QA MGT OpenAPI

Спецификация QA OpenAPI сохранена в:

specs/mgt-qa-openapi.json

MCP не обращается к онлайн-/api-docs во время выполнения, поэтому в будущем в производственной среде отсутствие открытой документации API не повлияет на работу. Достаточно переключить фактический адрес API через MGT_API_BASE_URL. Docker-образ копирует specs/mgt-qa-openapi.json в /app/specs/mgt-qa-openapi.json и автоматически устанавливает MGT_OPENAPI_SPEC_PATH.

Область API, предоставляемая в первой версии:

/api/v1/user/current
/course/list
/batch/list
/batch/trainee/list
/equity/userequity/give
/api/v1/order/**
/api/v1/item/**
/api/v1/open/getSku*
/api/v1/customers
/api/v1/campus-recruitment/**(排除 export)
/api/v1/recruitment-info/**(排除 export)

Интерфейс ссылки на оплату заказа подключён по текущим требованиям:

/api/v1/order/queryPayLink
/api/v1/order/reGenaratePayLink

По-прежнему исключены интерфейсы возврата, обратного вызова оплаты и экспорта данных клиентов:

/mall/v1/order/refund
/alipay/**
/stripe/**
/weixin/refund/**
/api/v1/customers/export
/api/v1/campus-recruitment/export
/api/v1/recruitment-info/export

При каждом вызове MGT OpenAPI-клиент получает из текущего запроса FastMCP пользовательский OAuth-токен доступа верхнего уровня и отправляет:

Authorization: Bearer <user access token>
X-Application-Id: <token.app_id>

Здесь X-Application-Id не требует дополнительной настройки — он считывается напрямую из claim app_id проверенного JWT. Токены без app_id отклоняются, чтобы не отправлять в MGT неполные запросы.

Поэтому MGT должен доверять пользовательским токенам, выпущенным auth-qa.drillinsight.com, и выполнять контроль прав на основе личности пользователя.

Диагностика таймаута ChatGPT CIMD

Если журнал содержит:

CIMD fetch failed for https://chatgpt.com/.../client.json: Timeout fetching
Unregistered client_id=https://chatgpt.com/.../client.json

это означает, что FastMCP не может напрямую получить доступ к размещённым ChatGPT метаданным клиента. Если текущая машина должна выходить в интернет через доверенный исходящий прокси, настройте:

FASTMCP_SSRF_TRUST_PROXY=true
HTTPS_PROXY=http://127.0.0.1:7897

Затем полностью остановите и перезапустите сервис. Программа автоматически загружает .env из корня проекта перед импортом FastMCP; FastMCP по умолчанию выполняет проверку DNS и фиксацию IP для запросов CIMD/JWKS, поэтому обычные переменные окружения прокси не используются автоматически. После включения этой опции ответственность за защиту от SSRF передаётся указанному прокси, а NO_PROXY игнорируется. Включайте её только для доверенного прокси.

Первый POST /mcp 401 в журнале — это попытка клиента проверить защищённый ресурс до аутентификации; 404 на несколько адресов /.well-known/... — это проверка совместимости ChatGPT. Пока /.well-known/oauth-authorization-server возвращает 200, они не являются причиной сбоя.

Если в журнале отображается Unregistered client_id=app_... или другой не-URL client ID, это означает, что ChatGPT кэшировал старую регистрацию DCR, которая была потеряна из хранилища сервера. Зафиксируйте JWT_SIGNING_KEY, перезапустите сервис, затем удалите и заново создайте этот пользовательский MCP в ChatGPT, чтобы он снова вызвал /register. Простой повтор входа не восстановит старый client ID, неизвестный серверу.

Тестирование

uv run pytest
-
license - not tested
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 Connectors

  • MCP server for AI access to Swagger by SmartBear.

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

  • MCP Server for agents to onboard, pay, and provision services autonomously with InFlow

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/beaconfire-projects/mcp-oauth-test'

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