Prerequisites
- A
url-type MCP instance that already exists. OAuth connect resolves the remote URL from the instance’s parent spec and returns 400 if there is none — create the instance first with Connect a remote MCP server. - The provider’s MCP endpoint must publish protected-resource metadata (RFC 9728) so the authorization server can be discovered.
- Redis reachable from the API. The in-flight flow state lives there between the two requests.
- A browser. The authorization step requires a human at a consent screen.
Steps
Start the flow
authorize_url in a browser
yourself.Behind that single call AgentArea discovers the authorization server from the MCP
URL, registers as a client via Dynamic Client Registration where the provider
supports it, generates a PKCE S256 pair, and stores the flow state in Redis keyed
by state.return_to is where the browser lands afterwards. It is validated against an
allowed base, so an arbitrary URL is rejected.Complete consent in the browser
Open the URL, approve the scopes. The provider redirects to
GET /v1/mcp-oauth/callback with code and state.The callback is public — it must be, because the provider redirects a browser to
it — and it is protected by the state token rather than your API key. It
exchanges the code for tokens, writes an auth config of type oauth2 holding the
access token, refresh token, scope, and expiry, links it to the instance via
auth_config_id, and then redirects the browser to
{return_to}/mcp-servers/{instance_id}?oauth=success.Tool discovery is kicked off in the background at that point, so the tool list
may be a moment behind the redirect.Handle a provider without dynamic registration
Some authorization servers do not implement RFC 7591. The flow then needs a
pre-registered OAuth app, supplied to the API as environment variables:Register the app with the provider using the callback URL of your deployment.
Without these,
/authorize returns 502 naming the issuer that refused
registration.Verify
Confirm the instance now carries an auth config and that a call through the governed proxy succeeds with an injected token.Authorization header is stripped before the request goes upstream, so this
only succeeds if the OAuth credential was stored correctly.
Troubleshooting
400 "Instance has no remote URL configured"
400 "Instance has no remote URL configured"
The instance is
docker or command , not url . OAuth connect only
applies to remote servers; a managed workload takes its credential from the
environment instead.502 "OAuth discovery failed"
502 "OAuth discovery failed"
The MCP endpoint does not publish protected-resource metadata, or the
authorization server metadata document is unreachable. Confirm the provider
documents OAuth for MCP; if it uses a plain API key, use
Pass secrets to an MCP server .
502 naming the issuer and Dynamic Client Registration
502 naming the issuer and Dynamic Client Registration
The authorization server has no registration endpoint, or registration
failed. Register an OAuth app manually and set
MCP_OAUTH_CLIENT_ID and
MCP_OAUTH_CLIENT_SECRET .The callback reports an invalid or expired state
The callback reports an invalid or expired state
Flow state is held in Redis with a bounded lifetime and is consumed on first
use. A stale browser tab, a second attempt at the same
authorize_url , or
a Redis restart between the two steps all produce this. Start again from
/authorize .return_to is ignored or rejected
return_to is ignored or rejected
It is validated against an allowed frontend base to stop the callback
becoming an open redirect. Use your deployment’s configured frontend origin.
Calls start failing with 401 days later
Calls start failing with 401 days later
The stored refresh token is used to mint new access tokens, and some
providers rotate refresh tokens on each use. If a refresh fails the
connection needs re-authorizing — re-run
/authorize for the same instance.Two auth configs for one instance
Two auth configs for one instance
Each successful flow creates a new auth config named
mcp-oauth-{first 8 chars of instance id} and repoints auth_config_id .
Older configs are left behind; the instance uses only the one it points at.Related
Connect a remote MCP server
Point AgentArea at an MCP server somebody else operates, test the endpoint
before saving it
Pass secrets to an MCP server
Declare which inputs are credentials with env_schema, supply their values on
the instance
MCP
What the Model Context Protocol gives an agent, and how AgentArea hosts MCP
servers