Skip to content

fix: community server OAuth localhost redirect, state validation, and token injection#471

Merged
saucow merged 1 commit intodocker:mainfrom
saucow:fix/community-oauth-localhost-redirect
Apr 7, 2026
Merged

fix: community server OAuth localhost redirect, state validation, and token injection#471
saucow merged 1 commit intodocker:mainfrom
saucow:fix/community-oauth-localhost-redirect

Conversation

@saucow
Copy link
Copy Markdown
Contributor

@saucow saucow commented Apr 6, 2026

Summary

Fixes three issues preventing community server OAuth from working end-to-end in Desktop mode with the McpGatewayOAuth flag enabled.

1. DCR registration rejected by community servers

authorizeCommunityMode was passing DefaultRedirectURI (mcp.docker.com/oauth/callback) to DiscoverAndRegister. Community servers only accept localhost redirects. Fixed by creating the callback server first and using its localhost URL for DCR registration.

2. State validation failed after OAuth callback

When redirecting directly to localhost (community mode), the full state mcp-gateway:PORT:UUID comes through. The state manager only knows the bare UUID. In CE mode, the mcp.docker.com proxy strips the prefix, but direct localhost callbacks don't. Fixed by stripping the prefix before validation.

3. Remote server connected without token

remote.go used NewOAuthCredentialHelper() (ModeAutoModeDesktop) which reads from the Secrets Engine. Community server tokens are in docker pass, not the Secrets Engine. Fixed by using DetermineMode with IsCommunity() to route to the correct credential store.

Testing

Tested end-to-end with Vercel MCP server (community registry):

  • docker mcp oauth authorize com-vercel-vercel-mcp — DCR succeeds with localhost redirect, callback received, token stored in docker pass
  • Gateway startup — token read from docker pass, server connects with Bearer token, 18 tools listed
  • Token refresh loop running — reads from docker pass, will refresh via oauth2 library

🤖 Generated with Claude Code

…tion, and per-server token injection

Three fixes for community server OAuth in Desktop mode (McpGatewayOAuth flag):

1. authorizeCommunityMode passed DefaultRedirectURI (mcp.docker.com/oauth/callback) to
   DiscoverAndRegister. Community servers reject non-localhost redirects. Create the
   callback server first and use its localhost URL for DCR registration.

2. Direct localhost callbacks return the full state (mcp-gateway:PORT:UUID). The state
   manager only knows the bare UUID. Strip the mcp-gateway:PORT: prefix before validating.

3. remote.go used NewOAuthCredentialHelper() (ModeAuto -> ModeDesktop) to read tokens.
   Community server tokens are in docker pass, not Secrets Engine. Use DetermineMode
   with IsCommunity() to route to the correct credential store.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@saucow saucow requested a review from a team as a code owner April 6, 2026 23:07
@saucow saucow requested a review from cutecatfann April 6, 2026 23:46
Copy link
Copy Markdown
Contributor

@cutecatfann cutecatfann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for fixing these issues!

@saucow saucow merged commit 4246962 into docker:main Apr 7, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants