-
Notifications
You must be signed in to change notification settings - Fork 11
feat: Add server auth conformance tests #105
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
pcarleton
wants to merge
12
commits into
main
Choose a base branch
from
server-auth-conformance
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The runner regex expects the server to output the full MCP endpoint URL. Updated auth-test-server to output http://localhost:PORT/mcp and the runner to match URLs with /mcp suffix.
commit: |
- Add /introspect endpoint to fake auth server (RFC 7662) - Replace custom bearer auth middleware with SDK's requireBearerAuth - Auth-test-server now fetches AS metadata and uses introspection endpoint - Removes ~50 lines of custom auth code in favor of SDK primitives
- Default clientIdMetadataDocumentSupported=true in fake auth server - Add cimd-client-id check when URL-based client ID is detected - Add clientMetadataUrl to ConformanceOAuthProvider for CIMD support - Update test expectations to accept either CIMD or DCR - Explicitly disable CIMD in token-endpoint-auth tests that require client_secret
- Update MCP Authorization spec refs from 2025-06-18 to 2025-11-25 - Fix anchor links for updated spec headings - Simplify fake-auth-server.ts by using ServerLifecycle for all cases - Add optional port parameter to ServerLifecycle.start() - Add introspection endpoint to fake-auth-server output
…flags - Remove --auth-url and --auth-command flags - Reuse existing --url and --command patterns for auth suite - --command with --suite auth spawns fake AS automatically - --url with --suite auth tests against already-running server
Add support for testing servers that require browser-based login (like better-auth) instead of auto-redirect. When --interactive is specified: - Starts a callback server on port 3333 - Prints the authorization URL for the user to open in browser - Waits for the OAuth callback with the authorization code - Continues the auth flow once the code is received This enables testing third-party auth servers that use real login pages.
- Remove callback URL as constructor parameter - Provider now handles redirect_uris internally via clientMetadata getter - CALLBACK_URL is now a private constant in oauth-client.ts
…idation - Add FAILURE when PRM discovery is missing or lacks authorization_servers - Add FAILURE when AS metadata discovery is missing - Add FAILURE when token request is missing - Expand AS metadata validation to check: - issuer (required per RFC 8414) - authorization_endpoint (required for auth code flow) - token_endpoint (required) - code_challenge_methods_supported includes S256 (required for MCP PKCE)
|
I think the fake AS is a great solution here and focusing on the RS is the right design choice (better than #64 !). If we do a AS specific conformance check, I think it should be separate tooling. Maybe something someone at Okta / Entra / Auth0 / Twillio / Arcade / WorkOS etc want to take on. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Adds conformance testing for MCP server OAuth authentication implementations.
Design Philosophy
The MCP authorization spec separates the Authorization Server (AS) from the Resource Server (RS/MCP server). This reflects the reality that authorization is often better handled by dedicated tools (Auth0, Keycloak, better-auth, etc.) rather than reimplemented in every SDK.
This conformance suite tests MCP server (RS) implementations, not AS implementations. SDKs are not expected to provide a full AS - they just need to:
The conformance suite provides a fake AS for testing, so SDK authors can verify their RS implementation without setting up real auth infrastructure. Alternatively, servers can integrate with their own AS if they prefer.
What's New
CLI Commands
New Files
src/fake-auth-server.ts- Standalone fake OAuth AS CLIsrc/scenarios/server-auth/- Server auth scenario directorybasic-dcr-flow.ts- Tests complete OAuth flow (401 → PRM → AS metadata → CIMD/DCR → Token → Auth'd request)helpers/oauth-client.ts- Observation middleware andConformanceOAuthProviderspec-references.ts- RFC/spec references (2025-11-25)Modified Files
src/index.ts- Extended server command with--suite auth,--interactivesrc/runner/server.ts- AddedrunServerAuthConformanceTest()andstartFakeAuthServer()src/scenarios/client/auth/helpers/createAuthServer.ts- Added/introspectendpoint (RFC 7662), CIMD detectionsrc/types.ts- AddedClientScenarioOptionswithinteractiveflagpackage.json- Addedfake-auth-serverbin entryInteractive Mode
For servers that integrate with their own AS requiring browser-based login, use
--interactive:This starts a callback server on port 3333 and displays the authorization URL for you to open in a browser.
CIMD vs DCR
The fake AS defaults to
client_id_metadata_document_supported: true, making CIMD (URL-based client IDs) the preferred method over DCR.Architecture
Conformance Checks
auth-401-response- Server returns 401 for unauthenticated requestsauth-www-authenticate-header- 401 includes WWW-Authenticate header with Bearer schemeauth-resource-metadata-param- WWW-Authenticate includes resource_metadata parameterauth-prm-discovery- PRM endpoint responds at.well-known/oauth-protected-resourceauth-prm-authorization-servers- PRM contains authorization_servers arrayauth-as-metadata-discovery- AS metadata discovery worksauth-as-metadata-fields- AS metadata includes required fields (issuer, authorization_endpoint, token_endpoint, PKCE S256)auth-dcr-registration- Dynamic Client Registration succeeds (when DCR used)auth-dcr-response- DCR response contains client credentialsauth-token-request- Token acquisition succeedsauth-token-response- Token response contains access_tokenauth-authenticated-request- Authenticated MCP call succeedsauth-flow-completion- Complete OAuth flow succeededTesting Example
Related PRs
auth-test-server.tsto typescript-sdk conformance directory