Skip to main content
Glama
tung2744
by tung2744

test-mcp

Un servidor de recursos MCP mínimo para probar manualmente el soporte de Dynamic Client Registration (DCR) e indicador de recurso de Authgear (docs/specs/dcr.md, docs/specs/access-token-audience-binding.md en el repositorio authgear-server).

No hace nada interesante por sí solo: su único trabajo es situarse detrás de Authgear como servidor de autorización y permitir que un cliente MCP real ejercite todo el flujo: descubrimiento → auto-registro DCR → autorización+consentimiento PKCE → intercambio de token vinculado al resource de este servidor → una llamada a herramienta MCP autenticada.

Cómo encajan las piezas

MCP client  --1. GET /mcp (no token)-->  test-mcp
            <--2. 401 + WWW-Authenticate: Bearer resource_metadata="..."--

MCP client  --3. GET /.well-known/oauth-protected-resource-->  test-mcp
            <--4. { resource, authorization_servers: [Authgear] }--

MCP client  --5. GET /.well-known/oauth-authorization-server-->  Authgear
            <--6. { registration_endpoint, authorization_endpoint, ... }--

MCP client  --7. POST /oauth2/register-->  Authgear   (DCR)
MCP client  --8. /oauth2/authorize + consent, resource=<RESOURCE_URI>--> Authgear
MCP client  --9. POST /oauth2/token, resource=<RESOURCE_URI>-->  Authgear
            <--10. JWT access token, aud=[RESOURCE_URI]--

MCP client  --11. POST /mcp, Authorization: Bearer <token>-->  test-mcp
            <--12. tool result (or 401 if scope/audience don't match)--

Los pasos 1-2 y 11-12 ocurren contra este servidor. Todo lo demás es Authgear, descubierto automáticamente por cualquier cliente MCP que cumpla con la especificación: no configuras el cliente con la URL de Authgear directamente.

Related MCP server: MCP Server OAuth Toy

Requisitos previos

  • Una instancia de Authgear en ejecución con DCR habilitado, por ejemplo en authgear.yaml:

    oauth:
      dynamic_client_registration:
        enabled: true
        initial_access_token_required: false # open registration, for easy testing
  • Un Resource registrado en ese proyecto que coincida con RESOURCE_URI más abajo, con access_policy.allow_dynamic_third_party_client_access: true en el propio Resource y en cada Scope que necesiten las herramientas de prueba; de lo contrario, una solicitud resource= de un cliente DCR obtiene invalid_target/invalid_scope. Créalo mediante el playground de GraphQL de la Admin API (o admin_api_graphql en una prueba e2e, si lo haces desde el repositorio authgear-server):

    mutation {
      createResource(input: {
        resourceURI: "https://localhost:8090"
        name: "test-mcp"
        accessPolicy: { allowDynamicThirdPartyClientAccess: true }
      }) {
        resource { id }
      }
    }
    
    mutation {
      createScope(input: {
        resourceURI: "https://localhost:8090"
        scope: "read:tools"
        accessPolicy: { allowDynamicThirdPartyClientAccess: true }
      }) {
        scope { id }
      }
    }
    
    mutation {
      createScope(input: {
        resourceURI: "https://localhost:8090"
        scope: "execute:tools"
        accessPolicy: { allowDynamicThirdPartyClientAccess: true }
      }) {
        scope { id }
      }
    }

    https://localhost:8090 debe coincidir byte a byte con RESOURCE_URI más abajo, y debe ser el origen real de este servidor (esquema + host + puerto), no un marcador de posición arbitrario. Dos restricciones independientes lo fijan:

    • Authgear exige que cada URI de recurso sea https:// (pkg/lib/resourcescope/formats.go).

    • El campo resource de los metadatos de recurso protegido RFC 9728 se espera que coincida con la URL (u origen) a la que el cliente realmente se conectó, y los clientes estrictos lo aplican: MCP Inspector se negará a conectarse con un error como Protected resource ... does not match expected ... (or origin) si apuntas RESOURCE_URI a un identificador no relacionado en lugar de la dirección real del servidor.

    Esa combinación es exactamente la razón por la que este servidor sirve HTTPS (autofirmado) por defecto en lugar de HTTP simple: https://localhost:<PORT> es simultáneamente una URI de recurso válida de Authgear y el origen genuino de este servidor. Si cambias PORT, actualiza la URI del Resource (y RESOURCE_URI más abajo) para que coincidan.

Configuración

npm install
npm run setup   # generates a self-signed TLS cert for localhost (see below)

Ejecución

npm start

Variables de entorno (todas opcionales):

Variable

Por defecto

Significado

PORT

8090

Puerto en el que escucha este servidor.

AUTHGEAR_ENDPOINT

http://localhost:4000

URL base de tu instancia de Authgear. Usa http://localhost:3000 si estás accediendo directamente al proceso make start, o http://localhost:3100 si pasas por el proxy nginx de desarrollo local convencional (docker compose up -d proxy) — en cualquier caso, debe ser donde realmente resuelva /.well-known/openid-configuration.

RESOURCE_URI

https://localhost:<PORT>

El identificador de recurso RFC 8707 — debe coincidir con el Resource creado arriba, y debe ser el origen real de este servidor (ver arriba).

USE_HTTP

unset

Establécelo a 1 para servir HTTP simple en lugar de HTTPS. No recomendado: con USE_HTTP=1, RESOURCE_URI ya no puede ser igual al origen real de este servidor (tendría que ser http://..., que Authgear rechaza como URI de recurso), por lo que la comprobación de coincidencia de recurso de un cliente MCP estricto fallará. Úsalo solo con un cliente que sepas que no aplica esa comprobación.

Pruebas con un cliente MCP real

MCP Inspector (primer paso recomendado)

npx @modelcontextprotocol/inspector

Abre la URL local impresa, establece la URL del servidor en https://localhost:8090/mcp y conéctate: el panel "Auth" de Inspector recorre el descubrimiento, DCR y el intercambio de autorización/token paso a paso, para que puedas ver exactamente qué contiene cada respuesta.

Dado que el certificado es autofirmado, es posible que debas indicar a Node que lo confíe para las solicitudes salientes del propio Inspector:

NODE_EXTRA_CA_CERTS=$(pwd)/certs/localhost.crt npx @modelcontextprotocol/inspector

(Solo haz esto para pruebas locales: nunca deshabilites la validación de certificados para nada que hable con un servidor real).

mcp-remote (para probar con Claude Desktop)

npx mcp-remote https://localhost:8090/mcp

y apunta la configuración de Claude Desktop al puente stdio local resultante según la propia documentación de mcp-remote.

Qué buscar

  • Sin resource= solicitado (un cliente OIDC simple, o un cliente MCP que no envía resource): Authgear emite un token opaco a un cliente de terceros/DCR por defecto. Este servidor no puede verificar un token opaco en absoluto (no es un JWT), por lo que cada llamada a herramienta falla con 401 — este es el comportamiento previsto (docs/specs/dcr.md, access-token-audience-binding.md): un token de terceros no vinculado solo es utilizable en el propio /oauth2/userinfo de Authgear, en ningún otro lugar.

  • resource=<RESOURCE_URI> solicitado: Authgear emite un JWT con aud: [RESOURCE_URI]. whoami debería tener éxito ahora independientemente de los scopes otorgados; list_widgets/run_widget solo tienen éxito si el scope correspondiente (read:tools/execute:tools) se otorgó en el momento del consentimiento.

  • Un token vinculado a un recurso diferente, o uno cuyo Resource/Scope carece de allow_dynamic_third_party_client_access: rechazado en el propio Authgear (invalid_target/invalid_scope) antes de que llegue a este servidor.

Solución de problemas

  • Failed to connect ... Protected resource <X> does not match expected <Y> (or origin) (MCP Inspector, u otro cliente estricto RFC-9728) — RESOURCE_URI está configurado a algo distinto del origen real de este servidor. Corrige RESOURCE_URI (y el Resource correspondiente en Authgear) para que sea https://localhost:<PORT>, no un marcador de posición arbitrario — ver "Requisitos previos" arriba.

  • invalid_target en /oauth2/authorize o /oauth2/token — el Resource (y/o el Scope específico) no tiene access_policy.allow_dynamic_third_party_client_access: true, o el valor resource= que envió el cliente no coincide exactamente con lo registrado.

  • 401 de este servidor con error_description: "fetch failed" — este servidor no pudo alcanzar AUTHGEAR_ENDPOINT para obtener los metadatos de descubrimiento; comprueba que Authgear esté realmente ejecutándose allí.

  • 401 con un error de verificación JWT — el token es real pero o bien ha expirado, está firmado por un emisor diferente, o está vinculado a un aud distinto de RESOURCE_URI.

A
license - permissive license
Not graded
quality - not tested
C
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
    C
    maintenance
    A proof-of-concept MCP server implementing OAuth 2.1 authorization with CIMD client registration and PKCE, demonstrating protected resource access and step-up authentication.
  • -
    license
    Not graded
    quality
    F
    maintenance
    A minimal remote (Streamable HTTP) MCP server that is an OAuth 2.1 resource server, demonstrating the MCP authorization spec with token validation and audience checks.
  • A
    license
    Not graded
    quality
    C
    maintenance
    A demo MCP server protected by OAuth (DCR), enabling hands-on exploration of OAuth flow for local MCP servers.
    MIT

View all related MCP servers

Related MCP Connectors

  • MCP server for verifying EUDI/Talao wallet data via OIDC4VP (pull) for AI agents.

  • Self-hosted federated MCP gateway: one OAuth 2.1 MCP server in front of N apps, user-level scopes.

  • The official MCP Server from Mia-Platform to interact with Mia-Platform Console

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/tung2744/test-mcp'

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