Skip to main content
This guide shows you how to authenticate an MCP client to the Bright Data MCP server with OAuth 2.1, so a user signs in through a browser instead of pasting a Bright Data API key into a config file. The Bright Data MCP server at https://mcp.brightdata.com is an OAuth 2.1 protected resource. It advertises its authorization server through RFC 9728 discovery metadata, and any MCP client that implements the Model Context Protocol authorization spec can connect without hardcoded credentials. The authorization server is https://brightdata.com. Four requirements are enforced on every request. Get these wrong and the flow fails before a token is ever issued:
  1. PKCE with S256 is mandatory. The plain method is rejected.
  2. The resource parameter is mandatory on both the authorization request and the token request, per RFC 8707.
  3. Clients are public. The token endpoint accepts token_endpoint_auth_method: none, so there is no client secret.
  4. The only scope is mcp.

Which authentication methods does the Bright Data MCP server support?

The Bright Data MCP server accepts two authentication methods. Both reach the same tools and draw on the same account credits. The API key method is documented in the remote MCP server quickstart. Use OAuth 2.1 when the person running the client is not the person who owns the Bright Data account, or when you do not want a long-lived key sitting in a config file.

Prerequisites

Before you start, make sure you have:
  • A Bright Data account. New accounts include 5,000 free requests per month.
  • An MCP client that implements the Model Context Protocol authorization spec, or your own OAuth 2.1 client code.
  • A redirect URI you control. Loopback addresses such as http://localhost:8765/callback are accepted for native and desktop clients.

How to run the OAuth 2.1 authorization code flow

The flow spans two hosts. mcp.brightdata.com holds the tools, brightdata.com issues the tokens, and the user’s browser enters only during authorization.
1

Trigger the 401 challenge

Call the MCP endpoint without a token. The Bright Data MCP server returns 401 Unauthorized with a WWW-Authenticate header that points at its protected resource metadata.
The response header is the entry point to the whole flow:
Parse resource_metadata from this header rather than hardcoding the URL. That is what makes the client portable across MCP servers.
2

Fetch the protected resource metadata

Request the URL from the resource_metadata parameter to learn which authorization server issues tokens for this resource.
Two values matter downstream. The resource value is what you send as the resource parameter in steps 4 and 5. The single entry in authorization_servers is the issuer you query in step 3.
3

Fetch the authorization server metadata

Request the RFC 8414 metadata document from the issuer to get the endpoint URLs and the server’s capabilities.
Read the endpoint URLs from this document. Do not hardcode them, because a discovery-driven client keeps working if an endpoint path changes.
4

Register a client

Register once with the RFC 7591 dynamic client registration endpoint to get a client_id. Registration is open, so no existing credential is needed.
The server responds with 201 Created:
No client_secret is returned, because clients are public. Store the client_id and reuse it. Every redirect_uri you plan to use has to be listed at registration time, since an unregistered redirect URI is rejected with 400 Bad Request.
5

Send the user to the authorization endpoint

Generate a PKCE verifier and challenge, then open the authorization URL in the user’s browser.
Keep the verifier in memory for step 6 and keep the state value so you can compare it against the value that comes back. If the user is not signed in, the authorization endpoint redirects to https://brightdata.com/cp/start?mcp=1&need_login=1&next=... and returns to the flow after sign-in.After the user approves, the browser is redirected to your redirect_uri with the authorization code:
Reject the response if state does not match the value you sent.
6

Exchange the code for an access token

Post the code, the PKCE verifier and the resource value to the token endpoint. All five parameters are required.
Send the returned access token as a bearer header on every MCP request. The protected resource metadata lists header as the only supported bearer method, so a token in a query string is not accepted.

OAuth 2.1 endpoint reference

The authorization server metadata is also served from https://mcp.brightdata.com/.well-known/oauth-authorization-server, and the protected resource metadata is also served from the path-insertion variant https://mcp.brightdata.com/.well-known/oauth-protected-resource/mcp. Clients that probe either location resolve correctly.
The two copies of the authorization server metadata are not identical. The copy served from https://brightdata.com includes "resource_parameter_supported": true. The copy served from https://mcp.brightdata.com omits that field, even though the server rejects any authorization or token request that arrives without a resource parameter. Read the copy at the issuer root, https://brightdata.com/.well-known/oauth-authorization-server, which is the location RFC 8414 specifies and the only one that advertises the requirement.

What does the authorization server enforce?

The Bright Data authorization server rejects requests that do not meet these five rules. The error strings below are returned verbatim, which makes them useful assertions in a test suite. Two failures are returned as 400 Bad Request without a redirect, which is the behavior the OAuth 2.0 Security Best Current Practice prescribes so that an attacker cannot use the authorization server as an open redirector:
  • An unknown client_id.
  • A redirect_uri that was not registered for that client_id.

How to handle 401 responses and refresh tokens

Treat any 401 from https://mcp.brightdata.com as the signal to refresh, then retry the request once. Do not schedule refreshes against a hardcoded lifetime, because the WWW-Authenticate challenge is the authoritative signal. Request a new access token with the refresh_token grant. The resource parameter is required here too:
If the refresh token is itself invalid or already used, the server returns invalid_grant with the description Invalid, expired, or already used refresh token. Send the user back through the authorization flow in step 5 when that happens.

How to test your OAuth 2.1 integration

Verify discovery and enforcement with curl before you write any client code. None of these checks need a token or a browser. Confirm the server challenges an unauthenticated request:
Expected output:
Confirm that PKCE and the resource parameter are enforced. Both requests return a redirect carrying an OAuth error, so no token is issued:
Once the flow works end to end, add these four assertions to your client’s test suite so a regression fails the build:
  1. A request with no token returns 401 and a WWW-Authenticate header containing resource_metadata.
  2. A request with a valid bearer token returns a tools/list result with a non-empty tools array.
  3. A request with a deliberately corrupted bearer token returns 401, not 200.
  4. The state value returned to your redirect URI matches the value your client sent.

Troubleshooting OAuth 2.1 errors

FAQ

Do I have to migrate from API keys to OAuth 2.1?

No. The ?token=YOUR_API_TOKEN query parameter on https://mcp.brightdata.com/mcp and https://mcp.brightdata.com/sse continues to work. OAuth 2.1 is an additional method, not a replacement.

Which scope should I request?

Request mcp. It is the only scope the Bright Data MCP server publishes in scopes_supported, on both the protected resource metadata and the authorization server metadata.

Is a client secret required?

No. The authorization server publishes token_endpoint_auth_methods_supported: ["none"], so Bright Data MCP clients are public clients. PKCE, not a secret, is what binds the authorization code to the client that requested it.

Can I skip dynamic client registration and use a preconfigured client ID?

Dynamic client registration at https://brightdata.com/users/auth/mcp/register is the supported path, and it is open, so any client can register itself without a credential. Register once and store the returned client_id rather than registering on every launch.

Why does my Python client get a 403 instead of an OAuth error?

Set an explicit User-Agent header. Requests to https://brightdata.com that carry the Python standard library default User-Agent (Python-urllib/*) are rejected with 403 Forbidden before they reach the authorization server, so no OAuth error body comes back to explain the failure. The rejection matches on the User-Agent string alone. An identical client sending an identical request over the same TLS connection succeeds as soon as the header changes, so no other property of the client is involved. Verified against https://brightdata.com/.well-known/oauth-authorization-server and the registration endpoint: Only the Python standard library default is affected. Clients built on requests, httpx, aiohttp, Node, Go, Java or okhttp send their own User-Agent and need no change.

Which MCP transports support OAuth 2.1?

Both. The Streamable HTTP endpoint https://mcp.brightdata.com/mcp and the SSE endpoint https://mcp.brightdata.com/sse return the same 401 challenge and accept the same bearer token.

Remote MCP server advanced configuration

Select tool groups, switch zones and tune the remote Bright Data MCP server.