test-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@test-mcptest the dynamic client registration flow with a tool call"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
test-mcp
A minimal MCP resource server for manually testing Authgear's Dynamic Client
Registration (DCR) + resource-indicator support (docs/specs/dcr.md,
docs/specs/access-token-audience-binding.md in the authgear-server repo).
It does nothing interesting on its own — its only job is to sit behind
Authgear-as-authorization-server and let a real MCP client exercise the
whole flow: discovery → DCR self-registration → PKCE authorize+consent →
token exchange bound to this server's resource → an authenticated MCP tool
call.
How the pieces fit together
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)--Steps 1-2 and 11-12 happen against this server. Everything in between is Authgear, discovered automatically by any spec-compliant MCP client — you don't configure the client with Authgear's URL directly.
Related MCP server: MCP Server OAuth Toy
Prerequisites
A running Authgear instance with DCR enabled, e.g. in
authgear.yaml:oauth: dynamic_client_registration: enabled: true initial_access_token_required: false # open registration, for easy testingA Resource registered in that project matching
RESOURCE_URIbelow, withaccess_policy.allow_dynamic_third_party_client_access: trueon the Resource itself and on every Scope the test tools need — otherwise a DCR client'sresource=request getsinvalid_target/invalid_scope. Create it via the Admin API GraphQL playground (oradmin_api_graphqlin an e2e test, if you're doing this from within theauthgear-serverrepo):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:8090must matchRESOURCE_URIbelow byte-for-byte, and must be this server's own real origin (scheme + host + port), not an arbitrary placeholder. Two independent constraints pin it down:Authgear requires every Resource URI to be
https://(pkg/lib/resourcescope/formats.go).RFC 9728 protected resource metadata's
resourcefield is expected to match the URL (or origin) the client actually connected to, and strict clients enforce this — MCP Inspector will refuse to connect with an error likeProtected resource ... does not match expected ... (or origin)if you pointRESOURCE_URIat an unrelated identifier instead of the server's real address.
That combination is exactly why this server defaults to serving HTTPS (self-signed) rather than plain HTTP:
https://localhost:<PORT>is simultaneously a valid Authgear Resource URI and this server's genuine origin. If you changePORT, update the Resource's URI (andRESOURCE_URIbelow) to match.
Setup
npm install
npm run setup # generates a self-signed TLS cert for localhost (see below)Running
npm startEnvironment variables (all optional):
Var | Default | Meaning |
|
| Port this server listens on. |
|
| Base URL of your Authgear instance. Use |
|
| The RFC 8707 resource identifier — must match the Resource created above, and must be this server's real origin (see above). |
| unset | Set to |
Testing with a real MCP client
MCP Inspector (recommended first step)
npx @modelcontextprotocol/inspectorOpen the printed local URL, set the server URL to https://localhost:8090/mcp,
and connect — Inspector's "Auth" panel walks through discovery, DCR, and the
authorize/token exchange step by step, so you can see exactly what each
response contains.
Since the cert is self-signed, you may need to tell Node to trust it for the Inspector's own outgoing requests:
NODE_EXTRA_CA_CERTS=$(pwd)/certs/localhost.crt npx @modelcontextprotocol/inspector(Only do this for local testing — never disable certificate validation for anything that talks to a real server.)
mcp-remote (for testing against Claude Desktop)
npx mcp-remote https://localhost:8090/mcpand point Claude Desktop's config at the resulting local stdio bridge per
mcp-remote's own docs.
What to look for
No
resource=requested (a plain OIDC client, or an MCP client that doesn't sendresource): Authgear issues an opaque token to a third-party/DCR client by default. This server can't verify an opaque token at all (it isn't a JWT), so every tool call fails with 401 — this is the intended behavior (docs/specs/dcr.md,access-token-audience-binding.md): an unbound third-party token is only usable at Authgear's own/oauth2/userinfo, nowhere else.resource=<RESOURCE_URI>requested: Authgear issues a JWT withaud: [RESOURCE_URI].whoamishould now succeed regardless of granted scopes;list_widgets/run_widgetsucceed only if the corresponding scope (read:tools/execute:tools) was granted at consent time.A resource-bound token from a different resource, or one whose Resource/Scope lacks
allow_dynamic_third_party_client_access: rejected at Authgear itself (invalid_target/invalid_scope) before it ever reaches this server.
Troubleshooting
Failed to connect ... Protected resource <X> does not match expected <Y> (or origin)(MCP Inspector, or another RFC-9728-strict client) —RESOURCE_URIis set to something other than this server's real origin. FixRESOURCE_URI(and the matching Resource in Authgear) to behttps://localhost:<PORT>, not an arbitrary placeholder — see "Prerequisites" above.invalid_targetat/oauth2/authorizeor/oauth2/token— the Resource (and/or the specific Scope) doesn't haveaccess_policy.allow_dynamic_third_party_client_access: true, or theresource=value the client sent doesn't exactly match what's registered.401 from this server with
error_description: "fetch failed"— this server couldn't reachAUTHGEAR_ENDPOINTto fetch discovery metadata; check Authgear is actually running there.401 with a JWT-verification error — the token is real but either expired, signed by a different issuer, or bound to a different
audthanRESOURCE_URI.
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 gradedqualityCmaintenanceA proof-of-concept MCP server implementing OAuth 2.1 authorization with CIMD client registration and PKCE, demonstrating protected resource access and step-up authentication.
- FlicenseNot gradedqualityDmaintenanceA simple MCP server with OAuth 2.0 authentication for testing OAuth support in mcp-cli.
- -licenseNot gradedqualityFmaintenanceA 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.
- AlicenseNot gradedqualityCmaintenanceA demo MCP server protected by OAuth (DCR), enabling hands-on exploration of OAuth flow for local MCP servers.MIT
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
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/tung2744/test-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server