test-mcp
test-mcp
Authgear의 DCR(동적 클라이언트 등록) + resource-indicator 지원(docs/specs/dcr.md, docs/specs/access-token-audience-binding.md, authgear-server 리포지토리)을 수동으로 테스트하기 위한 최소 MCP 리소스 서버입니다.
이 서버 자체로는 특별한 기능이 없습니다. Authgear를 권한 부여 서버로 하여 그 뒤에 위치하는 것이 전부이며, 실제 MCP 클라이언트가 전체 흐름을 수행해보도록 하는 것입니다: discovery → DCR 자체 등록 → PKCE 인가 + 동의 → 이 서버의 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 플레이그라운드(또는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와 byte-for-exact해 일치해야 하며, 그리고 이 서버의 실제 오리진(스킴 + 호스트 + 포트)이어야 합니다. 임의의 자리표시자가 아닙니다. 이는 두 가지 독립적인 제약 때문입니다.
Authgear는 모든 Resource URI가
https://이도록 요구합니다 (pkg/lib/resourcescope/formats.go).RFC 9728 보호 리소스 메타데이터의
resource필드는 클라이언트가 실제로 연결한 URL(또는 오리진)과 일치할 것으로 기대되며, 엄격한 클라이언트는 이를 강제합니다.RESOURCE_URI를 서버의 실제 주소 대신 연결 관련 식별자를 지정하면 MCP Inspector는Protected resource ... does not match expected ... (or origin)같은 오류로 연결을 거부합니다.
이 바로 그 조합 때문에 이 서버는 일반 HTTP가 아니라 HTTPS(자체 서명)를 기본으로 서빙합니다. 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와 일치해야 하며, 이 서버의 실제 오리진이어야 합니다(위 참고). |
| unset 가리키지 않음 |
|
실제 MCP 클라이언트로 테스트하기
MCP Inspector (첫 단계로 권장)
npx @modelcontextprotocol/inspector출력된 로컬 URL을 열고 서버 URL을 https://localhost:8090/mcp로 설정한 뒤, 연결하세요. Inspector의 “Auth” 패널이 discovery, DCR, 인가/토큰 교환을 단계별로 진행하므로 각 응답에 무엇이 들어 있는지 정확히 확인할 수 있습니다.
인증서가 자체 서명이므로 Inspector의 자체 요청을 위해 Node에 신뢰를 알려줘야 할 수 있습니다:
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는 기본적으로 제3자/DCR 클라이언트에 불투명(opaque) 토큰을 발급합니다. 이 서버는 불투명 토큰을 전혀 검증할 수 없습니다(JWT가 아니므로), 그래서 모든 도구 호출은 401로 실패합니다. 이는 의도된 동작입니다 (docs/specs/dcr.md,access-token-audience-binding참고): 바인딩되어 있지 않은 제3자token은 Authgear 자체의/oauth2/userinfo`에서만 사용할 수 있고 다른 곳에서는 사용할 수 없는 것입니다.resource=<RESOURCE_URI>요청됨: Authgear는aud: [RESOURCE_URI]を持つ JWT를 발급합니다. 이로 부여된 스코프와 무관하게whoami는 성공해야 합니다.list_widgets/run_widget은 동의 시 해당 스코프(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"— 이 서버가 discovery 메타데이터를 회수 위해AUTHGEAR_ENDPOINT에 접근하지 못했습니다. 실제로 Authgear가 그 주소에서 실행 중인지 확인하세요.JWT 검증 오류와 401 — 토큰은 실제하지만 만료되었거나, 다른 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