-
Notifications
You must be signed in to change notification settings - Fork 324
Description
What you'd like to see
Add support for explicit OAuth configuration (clientId, clientSecret, callbackPort, scopes) in remote MCP server definitions, so that servers that do not support Dynamic Client Registration (RFC 7591) can still complete the OAuth flow.
Proposed configuration
toolsets:
- type: mcp
remote:
url: https://mcp.slack.com/mcp
transport_type: streamable
oauth:
clientId: "3660753192626.8903469228982"
clientSecret: "" # optional, for confidential clients
callbackPort: 3118 # optional, fixed port for the OAuth callback server
scopes: # optional, override scopes to request
- search:read.public
- chat:writeThis mirrors what other MCP clients already support. For example, the Slack MCP plugin uses this format for Claude Code (.mcp.json):
{
"mcpServers": {
"slack": {
"type": "http",
"url": "https://mcp.slack.com/mcp",
"oauth": {
"clientId": "1601185624273.8899143856786",
"callbackPort": 3118
}
}
}
}And for Cursor:
{
"mcpServers": {
"slack": {
"url": "https://mcp.slack.com/mcp",
"auth": {
"CLIENT_ID": "3660753192626.8903469228982"
}
}
}
}Why you'd like to see it
Many real-world MCP servers require OAuth but do not support Dynamic Client Registration. The Slack MCP server is a prominent example — its official documentation explicitly states:
"We do not support SSE-based connections or Dynamic Client Registration at this time."
The current OAuth implementation in docker-agent always attempts dynamic registration first. When the server's metadata lacks a registration_endpoint, validateAndFillDefaults() fabricates one (appending /register to the auth server URL), which then fails. When it does exist and the server doesn't support it, the registration POST fails with an HTTP error. In both cases the error is fatal — the MCP toolset fails to start and the agent silently loses all tools from that server.
This same root cause is behind issue #416 (GitHub MCP Server OAuth 404) and affects any server that requires a pre-registered app identity (Slack, potentially others).
Detailed failure trace (Slack example)
- Agent connects to
https://mcp.slack.com/mcp→ server returns HTTP 401 withWWW-Authenticate: Bearer resource_metadata="https://mcp.slack.com/.well-known/oauth-protected-resource" oauthTransportinitiates managed OAuth flow- Fetches auth server metadata from
https://mcp.slack.com/.well-known/oauth-authorization-server— response has noregistration_endpoint validateAndFillDefaults()setsRegistrationEndpoint = "https://mcp.slack.com/register"(a fabricated default)RegisterClient()POSTs to that URL → Slack returns a 302 redirect to an HTML page (not an RFC 7591 endpoint)- Registration fails →
handleManagedOAuthFlowreturns error (theTODO(rumpl): fall back to requesting client ID from userpath) oauthTransport.RoundTripreturns"OAuth flow failed: ..."→doStart()fails →ensureToolSetsAreStartedlogs a warning and skips the toolset- The agent proceeds with zero MCP tools from the Slack server — all tool calls return "Tool not available"
Code references
pkg/tools/mcp/oauth.go—validateAndFillDefaults()fabricates registration endpoint;handleManagedOAuthFlow()has theTODOfallback commentpkg/tools/mcp/oauth_helpers.go—RegisterClient()performs the failing dynamic registrationpkg/config/latest/types.go—Remotestruct currently only hasURL,TransportType, andHeaders(no OAuth fields)
Workarounds?
No working workaround exists. Passing CLIENT_ID as an HTTP header (as the Cursor config does) sends it on every request but the OAuth code never reads it to use as the client_id in the authorization flow:
# Does NOT work — CLIENT_ID header is ignored by the OAuth logic
remote:
url: https://mcp.slack.com/mcp
transport_type: streamable
headers:
"CLIENT_ID": "3660753192626.8903469228982"Additional context
- Related issue: Unable to complete OAuth flow for GitHub MCP Server (404 error) #416 (same root cause — dynamic registration fails for GitHub MCP Server)
- Slack MCP server docs: https://docs.slack.dev/ai/slack-mcp-server
- Slack MCP plugin repo (Claude Code + Cursor configs): https://github.com/slackapi/slack-mcp-plugin
- The
validateAndFillDefaults()function should probably not fabricate aregistration_endpointwhen the server metadata does not include one — that is a separate but related bug