Skip to main content
Glama
beaconfire-projects

mcp-oauth-test

Servidor FastMCP OIDC

Este es un servidor MCP protegido por inicio de sesión OIDC, escrito con FastMCP. Utiliza el OIDCProxy de FastMCP: el cliente MCP completa la autenticación a través de los metadatos OAuth expuestos por el servidor, y el inicio de sesión real y el intercambio de tokens se reenvían al proveedor OIDC de QA.

Actualmente está integrado con la API abierta MGT de QA, generando herramientas MCP relacionadas con trainees, pedidos, productos, clientes, reclutamiento en campus y reclutamiento internacional.

La dirección de descubrimiento OIDC ya está configurada por defecto como:

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

Preparación de autenticación

Primero registra una aplicación OAuth en auth-qa.drillinsight.com y añade la siguiente dirección de callback a la lista blanca:

http://localhost:8000/auth/callback

Al desplegar en otra dirección, reemplaza http://localhost:8000 por el valor de BASE_URL. La dirección de callback debe coincidir exactamente con el BASE_URL de FastMCP.

Ejecución local

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

También puedes ejecutar el módulo directamente:

uv run python -m oidc_mcp_server.server

El servicio escucha por defecto en http://127.0.0.1:8000. Si el cliente MCP se ejecuta en otra máquina o en un contenedor, configura un BASE_URL accesible para el cliente y un HOST adecuado (por ejemplo, 0.0.0.0).

Plugin para Claude Code

El repositorio incluye un marketplace privado de Claude Code y un plugin MCP:

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

El plugin solo se encarga de conectar Claude Code al servicio MCP remoto ya desplegado; no inicia el servicio Python localmente. Para pruebas de desarrollo, puedes cargarlo directamente:

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

El plugin está fijado para conectarse al servidor MCP del entorno de desarrollo:

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

También puedes instalarlo desde el marketplace privado:

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

La raíz del marketplace actual es la raíz del repositorio. Mantén este marketplace en un repositorio privado de GitHub de la empresa; no lo envíes a un marketplace público. Los entornos compartidos deben usar direcciones HTTPS y restringir el acceso a usuarios de la empresa tanto en el IdP corporativo como en el lado del servidor MCP.

Por qué usar OIDCProxy

El upstream auth-qa.drillinsight.com no necesita soportar DCR ni CIMD. OIDCProxy está diseñado precisamente para este escenario:

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

Lo único que hay que registrar previamente en el upstream es la aplicación OAuth de FastMCP, y configurar ${BASE_URL}/auth/callback. El CIMD utilizado por ChatGPT lo gestiona la capa de proxy de FastMCP y no se reenvía al servidor OAuth upstream.

Configuración CIMD para ChatGPT

Al crear un MCP personalizado en ChatGPT, en la configuración avanzada de OAuth, en "Registro de clientes", selecciona:

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

La información que genera el conector de ChatGPT actualmente es:

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

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

La URL CIMD es en sí misma el client_id que ChatGPT utiliza al acceder al proxy OAuth de FastMCP. No necesita, ni debe, registrarse en el upstream auth-qa.drillinsight.com.

Este proyecto tiene dos niveles diferentes de ID de cliente OAuth:

Cadena OAuth

client_id

Ubicación de configuración

ChatGPT → FastMCP OIDCProxy

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

Lo proporciona ChatGPT automáticamente; no es necesario rellenarlo manualmente al seleccionar CIMD

FastMCP OIDCProxy → auth-qa.drillinsight.com

app_74a4b555-5b87-4212-9dda-d584fa78caf8

OIDC_CLIENT_ID del servidor MCP

El flujo de datos correspondiente es:

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

Configuración de variables de entorno del servidor MCP:

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

El servidor OAuth upstream solo necesita configurar la dirección de callback de FastMCP para la aplicación app_...:

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

No configures la dirección de callback de ChatGPT https://chatgpt.com/connector/oauth/... en el servidor OAuth upstream; esa dirección la utiliza la capa de proxy de FastMCP después de completar la autenticación.

Al iniciar la autenticación, en los registros normales debería aparecer primero el ID de cliente CIMD de ChatGPT:

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

Después, FastMCP usará app_74a4b555-... para redirigir al servidor OAuth upstream.

Configuración del cliente MCP

Configura la dirección MCP como:

http://localhost:8000/mcp

FastMCP proporcionará las siguientes direcciones de descubrimiento de autenticación:

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

El cliente debería leer automáticamente estos endpoints de descubrimiento MCP/OAuth. Tras iniciar sesión correctamente, se pueden invocar dos herramientas protegidas:

  • ping: comprobación de estado.

  • who_am_i: devuelve el client_id, los scopes y los claims que FastMCP extrae del token de autenticación actual.

Opciones de configuración

Variable de entorno

Requerida

Valor por defecto

Descripción

OIDC_CLIENT_ID

-

ID de cliente OIDC upstream

OIDC_CLIENT_SECRET

Una de las dos

-

Secreto de cliente confidencial

JWT_SIGNING_KEY

Una de las dos

-

Cliente PKCE público o clave de firma de tokens FastMCP en producción

OIDC_CONFIG_URL

No

URL de descubrimiento de QA

Dirección de descubrimiento OIDC

BASE_URL

No

http://localhost:8000

Dirección pública del servidor MCP

OIDC_REQUIRED_SCOPES

No

openid

Scope para la solicitud de autorización OAuth/anuncio por defecto; no se usa para la validación de scopes del token de acceso

OIDC_TOKEN_ISSUER

No

Issuer del descubrimiento OIDC

Valor de validación de iss del JWT; se configura cuando el middleware de autenticación reescribe el issuer

OIDC_JWKS_URI

No

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

Dirección JWKS para emisores de tokens personalizados

OIDC_TOKEN_AUDIENCE

No

-

Valor de validación opcional de aud del JWT

HOST

No

127.0.0.1

Dirección de escucha

PORT

No

8000

Puerto de escucha

MGT_API_BASE_URL

No

Dirección MGT de QA

URL base real de llamada a la API MGT

MGT_OPENAPI_SPEC_PATH

No

specs/mgt-qa-openapi.json

Ruta local del spec OpenAPI

En producción, configura explícitamente un JWT_SIGNING_KEY aleatorio y usa un BASE_URL con HTTPS. No envíes .env ni ningún secreto de cliente a Git.

Emisor de tokens personalizado

Si el iss del token no es el issuer devuelto por el descubrimiento OIDC, sino que el middleware de autenticación lo reescribe a una dirección de tenant, por ejemplo:

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

Configura:

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 se sigue usando para el descubrimiento de los endpoints de inicio de sesión y autorización OAuth; OIDC_TOKEN_ISSUER se usa únicamente para la validación de iss del token de acceso JWT. Ambos pueden ser diferentes. OIDC_TOKEN_ISSUER debe coincidir exactamente con el iss del token, incluida la / final.

El proyecto actual no valida el claim scope ni scp del token de acceso, porque los tokens históricos de MGT usan un formato de scope no estándar. OIDC_REQUIRED_SCOPES se sigue usando para la solicitud de autorización OAuth, pero no bloquea tokens válidos que carezcan del claim de scope estándar. La validación de firma, issuer, audiencia, tiempo de expiración y JWKS se mantiene.

Integración con la API abierta MGT de QA

El spec OpenAPI de QA se ha guardado fijado en:

specs/mgt-qa-openapi.json

MCP no accede a /api-docs en línea durante la ejecución, por lo que en el futuro, si el entorno de producción no expone la documentación de la API, no afectará al funcionamiento. Basta con cambiar la dirección real de la API mediante MGT_API_BASE_URL. La imagen Docker copia specs/mgt-qa-openapi.json a /app/specs/mgt-qa-openapi.json y configura automáticamente MGT_OPENAPI_SPEC_PATH.

El alcance de la API expuesta en la primera versión:

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

La interfaz de enlace de pago de pedidos se integra según los requisitos actuales:

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

Se siguen excluyendo las interfaces de reembolso, callback de pago y exportación de datos de clientes:

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

En cada llamada a MGT, el cliente OpenAPI obtiene el token de acceso OAuth upstream del usuario de la solicitud FastMCP actual y envía:

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

Donde X-Application-Id no requiere configuración adicional; se lee directamente del claim app_id del JWT ya validado. Los tokens sin app_id se rechazan para evitar enviar solicitudes incompletas a MGT.

Por lo tanto, MGT debe confiar en los tokens de usuario emitidos por auth-qa.drillinsight.com y aplicar el control de permisos según la identidad del usuario.

Diagnóstico de timeout CIMD en ChatGPT

Si los registros contienen:

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

Significa que FastMCP no puede acceder directamente a los metadatos del cliente alojados por ChatGPT. Si la máquina actual debe acceder a Internet a través de un proxy de salida de confianza, configura:

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

Luego detén y reinicia el servicio por completo. El programa carga automáticamente el .env de la raíz del proyecto antes de importar FastMCP; FastMCP realiza por defecto validación DNS y fijación de IP para las solicitudes CIMD/JWKS, por lo que no usa automáticamente las variables de entorno de proxy normales. Al activar esta opción, la responsabilidad de protección SSRF se delega al proxy especificado y se ignora NO_PROXY. Solo se puede activar con un proxy de confianza.

El primer POST /mcp 401 en los registros es el cliente sondeando el recurso protegido antes de la autenticación; los 404 para varias direcciones /.well-known/... también son sondeos de compatibilidad de ChatGPT. Mientras /.well-known/oauth-authorization-server devuelva 200, no son la causa de este fallo.

Si los registros muestran Unregistered client_id=app_... u otro ID de cliente que no sea una URL, significa que ChatGPT ha almacenado en caché un registro DCR antiguo que ya se ha perdido del almacenamiento del servidor. Fija JWT_SIGNING_KEY, reinicia el servicio y luego elimina y vuelve a crear el MCP personalizado en ChatGPT para que vuelva a llamar a /register. Solo reintentar el inicio de sesión no recuperará un ID de cliente antiguo desconocido para el servidor.

Pruebas

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