test-mcp
test-mcp
一个用于手动测试 Authgear 动态客户端注册(DCR)+ 资源指示符(resource-indicator)支持的最小 MCP 资源服务器(相关文档见 authgear-server 仓库中的 docs/specs/dcr.md、docs/specs/access-token-audience-binding.md)。
它本身没什么特别之处——它唯一的任务就是位于作为授权服务器的 Authgear 之后,让一个真实的 MCP 客户端走一遍完整流程:发现(discovery)→ DCR 自助注册 → PKCE 授权与同意(authorize+consent)→ 绑定到此服务器 resource 的令牌交换 → 一次经过身份验证的 MCP 工具调用。
各部分如何配合
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)--步骤 1-2 和 11-12 发生在本服务器上。中间的一切都由 Authgear 完成,任何符合规范的 MCP 客户端都会自动发现它——你无需直接用 Authgear 的 URL 来配置客户端。
Related MCP server: MCP Server OAuth Toy
前置条件
一个正在运行且已启用 DCR 的 Authgear 实例,例如在
authgear.yaml中:oauth: dynamic_client_registration: enabled: true initial_access_token_required: false # open registration, for easy testing在该项目中注册一个与下面的
RESOURCE_URI匹配的 Resource,并在 Resource 本身以及测试工具所需的每个 Scope 上都设置access_policy.allow_dynamic_third_party_client_access: true——否则 DCR 客户端的resource=请求会得到invalid_target/invalid_scope。可通过 Admin API GraphQL playground 创建(如果你是在authgear-server仓库内操作,也可以在 e2e 测试中使用admin_api_graphql):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必须与下面的RESOURCE_URI逐字节匹配,并且必须是本服务器自身的真实来源(origin,即协议 + 主机 + 端口),而不能是任意占位符。两个相互独立的约束条件锁定了这一点:Authgear 要求每个 Resource URI 都必须是
https://(见pkg/lib/resourcescope/formats.go)。RFC 9728 受保护资源元数据中的
resource字段应当与客户端实际连接的 URL(或 origin)匹配,严格的客户端会强制校验这一点——如果你将RESOURCE_URI指向无关的标识符而不是服务器的真实地址,MCP Inspector 将拒绝连接,并报出类似Protected resource ... does not match expected ... (or origin)的错误。
正是这种组合,本服务器才默认提供 HTTPS(自签名)而不是纯 HTTP:
https://localhost:<PORT>同时是一个合法的 Authgear Resource URI 和本服务器的真实来源。如果你更改了PORT,请同步更新 Resource 的 URI(以及下面的RESOURCE_URI)以保持匹配。
设置
npm install
npm run setup # generates a self-signed TLS cert for localhost (see below)运行
npm start环境变量(均为可选):
变量 | 默认值 | 说明 |
|
| 本服务器监听的端口。 |
|
| 你的 Authgear 实例的基础 URL。如果你直接访问 |
|
| RFC 8707 资源标识符——必须与上面创建的 Resource 匹配,并且必须是本服务器的真实来源(见上文)。 |
| 未设置 | 设置为 |
使用真实的 MCP 客户端进行测试
MCP Inspector(推荐的第一步)
npx @modelcontextprotocol/inspector打开打印出来的本地 URL,将服务器 URL 设置为 https://localhost:8090/mcp,然后连接——Inspector 的“Auth”面板会逐步走完发现、DCR 以及授权/令牌交换流程,让你能确切地看到每个响应包含什么。
由于证书是自签名的,你可能需要让 Node 信任它,以便 Inspector 自身的出站请求能够正常发起:
NODE_EXTRA_CA_CERTS=$(pwd)/certs/localhost.crt npx @modelcontextprotocol/inspector(只应在本地测试时这样做——切勿为任何与真实服务器通信的对象禁用证书验证。)
mcp-remote(用于配合 Claude Desktop 进行测试)
npx mcp-remote https://localhost:8090/mcp然后按照 mcp-remote 自己的文档,将 Claude Desktop 的配置指向生成的本地 stdio 桥接。
需要关注什么
未请求
resource=(普通的 OIDC 客户端,或不发送resource的 MCP 客户端):Authgear 默认会向第三方/DCR 客户端签发**不透明(opaque)**令牌。本服务器完全无法验证不透明令牌(它不是 JWT),因此每次工具调用都会以 401 失败——这正是预期的行为(docs/specs/dcr.md、access-token-audience-binding.md):未绑定的第三方令牌只能在 Authgear 自己的/oauth2/userinfo端点使用,其他地方都不行。请求了
resource=<RESOURCE_URI>:Authgear 会签发aud: [RESOURCE_URI]的 JWT。此时无论授予了哪些 scope,whoami都应成功;list_widgets/run_widget只有在同意(consent)时授予了相应 scope(read:tools/execute:tools)的情况下才会成功。来自其他资源的资源绑定令牌,或其 Resource/Scope 缺少
allow_dynamic_third_party_client_access的令牌:会在到达本服务器之前就被 Authgear 本身拒绝(invalid_target/invalid_scope)。
故障排查
Failed to connect ... Protected resource <X> does not match expected <Y> (or origin)(MCP Inspector 或另一个严格遵循 RFC 9728 的客户端)——RESOURCE_URI被设置成了本服务器真实来源以外的值。请将RESOURCE_URI(以及 Authgear 中匹配的 Resource)修正为https://localhost:<PORT>,而不是任意占位符——参见上面的“前置条件”。在
/oauth2/authorize或/oauth2/token处出现invalid_target——Resource(和/或特定的 Scope)没有设置access_policy.allow_dynamic_third_party_client_access: true,或者客户端发送的resource=值与已注册的内容不完全匹配。本服务器返回 401,并带有
error_description: "fetch failed"——本服务器无法访问AUTHGEAR_ENDPOINT来获取发现元数据;请检查 Authgear 是否确实在该地址运行。返回 401 并带有 JWT 验证错误——令牌本身是真实的,但要么已过期,要么由不同的签发者(issuer)签名,要么绑定到了与
RESOURCE_URI不同的aud。
This server cannot be deployed
Maintenance
Related MCP Connectors
Minimal streamable HTTP MCP server used for owned-account registry connectivity tests.
Experimental MCP server for current empirical verification of explicit public HTTPS endpoint claims.
- StytchOAuthdev.stytch.mcp
The Stytch MCP server is a reference implementation that demonstrates remote MCP server authentication and authorization using Stytch Connected Apps. It provides OAuth 2.1-compliant authorization (including PKCE), Dynamic Client Registration, and validates Stytch-issued access tokens to enable AI agents to securely interact with external services through permissioned access, supporting scopes like openid, email, profile, and manage:project_data.
MCP server for verifying EUDI/Talao wallet data via OIDC4VP (pull) for AI agents.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA 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