ScreenshotNeo

BlogAI agents

How to Configure OAuth for Claude Code MCP Servers

Configure remote MCP OAuth in Claude Code, fix authentication errors, test with MCP Inspector, and secure scopes, callbacks, and tokens.

By the ScreenshotNeo team1 October 20267 min read

To configure OAuth for a remote MCP server in Claude Code, register the server as an HTTP or Streamable HTTP MCP server, then authenticate it from Claude Code’s /mcp panel. Claude Code normally discovers the authorization server metadata automatically from the server’s authentication response. Use oauth.authServerMetadataUrl when discovery is nonstandard, and oauth.scopes to request a least-privilege scope set.

This guide covers project and user configuration, browser sign-in, fixed callback ports, client credentials, token refresh, MCP Inspector testing, hosted connector limitations, troubleshooting, and security practices.

1. Add the remote MCP server

Remote servers must declare an HTTP transport explicitly. A URL without a type is interpreted as a stdio configuration, so omitting type can make a valid remote server fail to connect.

Using the Claude Code CLI

claude mcp add --transport http my-server https://mcp.example.com/mcp
claude mcp list
claude mcp get my-server

The add command writes the configuration and prints an Added ... message. Use a project .mcp.json when a team should share the server definition. Use user scope for a personal server that should be available across projects.

Using JSON configuration

claude mcp add-json my-server '{"type":"http","url":"https://mcp.example.com/mcp"}'

streamable-http is accepted as an alias in JSON configuration:

claude mcp add-json my-server '{"type":"streamable-http","url":"https://mcp.example.com/mcp"}'

After adding the server, run claude mcp list. Typical states include Connected, Needs authentication, and Failed to connect. The interactive /mcp panel shows the same state and provides the authentication action.

2. Complete the OAuth flow in Claude Code

  1. Start Claude Code in the project containing the MCP configuration.
  2. Run /mcp.
  3. Select the remote server marked Needs authentication.
  4. Choose the sign-in or authenticate action.
  5. Complete the authorization in your browser and approve the requested scopes.
  6. Return to Claude Code and confirm that the server state changes to Connected.

Claude Code recognizes an authentication requirement from a 401 or 403 response. A server that returns a suitable WWW-Authenticate header can participate in automatic authorization-server discovery. After authorization, Claude Code stores the OAuth credentials and attaches access tokens to later MCP requests. See the Claude Code MCP documentation for the current command and configuration behavior.

3. Configure OAuth metadata and scopes

Automatic discovery is the normal path. Add an explicit metadata URL when a reverse proxy, custom authorization server, or nonstandard discovery endpoint prevents Claude Code from finding the metadata.

{
  "mcpServers": {
    "my-server": {
      "type": "http",
      "url": "https://mcp.example.com/mcp",
      "oauth": {
        "authServerMetadataUrl": "https://auth.example.com/.well-known/openid-configuration",
        "scopes": "resource.read resource.write"
      }
    }
  }
}

oauth.scopes is one space-separated string. When supplied, it takes precedence over scopes discovered from the server. Pin only the scopes required by the tools. This avoids silently granting a broader permission set if the server later advertises additional scopes.

4. Use a fixed callback port

Most providers can use Claude Code’s normal local callback behavior. A provider that requires a pre-registered localhost redirect needs a fixed callback port. Register the exact callback URL with the provider, then configure the OAuth client information in the MCP entry.

{
  "mcpServers": {
    "my-server": {
      "type": "http",
      "url": "https://mcp.example.com/mcp",
      "oauth": {
        "clientId": "YOUR_CLIENT_ID",
        "callbackPort": 8765
      }
    }
  }
}

The CLI also supports supplying a client secret through its secret option when using claude mcp add-json. Keep the secret out of committed project files. Prefer an operating-system secret store or an environment mechanism supported by your deployment.

5. Client ID and secret choices

Situation Recommended setup
Normal remote server Let Claude Code discover metadata and start the browser flow from /mcp.
Nonstandard discovery Set oauth.authServerMetadataUrl.
Provider requires a registered localhost redirect Set a fixed callbackPort and register the matching callback.
Provider gives you a preconfigured OAuth client Set the client ID and provide the client secret through the CLI secret option; do not commit it.

6. Token refresh and re-authentication

Claude Code refreshes a stored access token when a later MCP request returns 401, then retries the request once. If the authorization server rejects the refresh token, the automatic retry cannot succeed. Open /mcp and choose Re-authenticate to run the browser flow again.

Do not delete and recreate the server first. Inspect its state with claude mcp list and claude mcp get my-server; this distinguishes an expired grant from a malformed URL or an unreachable server.

7. Test OAuth independently with MCP Inspector

MCP Inspector isolates server OAuth behavior from Claude Code’s local credential store. Start it with:

npx @modelcontextprotocol/inspector
  1. Select SSE or Streamable HTTP, matching the server transport.
  2. Enter the MCP server URL.
  3. Open Auth Settings.
  4. Select Quick OAuth Flow.
  5. Approve the authorization request and continue through the progress steps.
  6. Copy the resulting access_token for an isolated connector test.

If Inspector cannot discover metadata or complete the callback, fix the server’s OAuth response before changing Claude Code configuration. Inspector is also useful for checking whether a proxy is stripping WWW-Authenticate.

8. Hosted connector boundary

Claude Code can use MCP connectors configured in Claude.ai when you are signed in with the relevant subscription authentication. Some Anthropic-hosted services, including Microsoft 365, Gmail, and Google Calendar, do not support local Claude Code OAuth because their upstream identity providers accept only the Claude.ai redirect URL. Authorize those connectors at claude.ai/customize/connectors, then let Claude Code use the managed connector.

9. Google Cloud and Workspace MCP servers

For a Google Cloud or Google Workspace remote MCP service, create an OAuth 2.0 client of type Web application. Add https://claude.ai/api/mcp/auth_callback as an authorized redirect URI, store the client secret securely, and enter the client ID and secret in the custom connector’s Advanced settings. This is the Claude.ai callback path and is separate from a local Claude Code callback-port configuration.

10. Troubleshooting OAuth errors

Symptom Likely cause Fix
Failed to connect Wrong URL, server is down, TLS failure, or transport mismatch. Confirm an HTTPS URL, use explicit type: http or streamable-http, then test the same URL in MCP Inspector.
Needs authentication remains after sign-in Authorization callback did not complete or the server rejected the token. Reopen /mcp, authenticate again, and inspect the server response in Inspector.
Discovery fails The proxy removed WWW-Authenticate or metadata is at a nonstandard URL. Restore the header or set oauth.authServerMetadataUrl explicitly.
Provider rejects redirect URI The registered callback does not exactly match the callback Claude Code uses. Register the exact localhost callback and configure a fixed callbackPort when required.
Scope consent is too broad The server advertises more scopes than the tools need. Set oauth.scopes to a space-separated least-privilege list.
Requests return 401 after working earlier Access token expired. Allow Claude Code to refresh once; if refresh is rejected, choose Re-authenticate in /mcp.
OAuth works in Claude.ai but not locally The identity provider allows only the Claude.ai redirect URL. Configure the connector in Claude.ai and use the managed connector from Claude Code.
Secret appears in a repository diff Client credentials were placed in project JSON. Revoke and rotate the secret, remove it from history where necessary, and provide it through a secret mechanism.

11. Security checklist

  • Use HTTPS for the MCP endpoint and authorization server.
  • Trust an MCP server before connecting it. External content handled by a server can carry prompt-injection instructions.
  • Request only the scopes required by the tools.
  • Do not commit client secrets, access tokens, or refresh tokens.
  • Do not paste tokens into issue trackers or shell history.
  • Use MCP Inspector to reproduce failures without changing production credentials.
  • After changing redirect URIs or scopes, re-authenticate and verify the consent screen.

12. Performance, reliability, and operational notes

OAuth adds a browser round trip only during initial authorization or re-authentication. Normal tool calls use the stored access token. Keep the MCP endpoint and authorization server close to the users and avoid proxies that rewrite authentication headers. Monitor the server’s HTTP status and authentication headers, and make re-authentication a documented recovery step rather than deleting configuration.

For team projects, commit only the non-secret server URL, transport, metadata URL, and approved scopes in .mcp.json. Keep each developer’s authorization state and any client secret outside the repository. When a server changes its advertised scopes or authorization server, update the configuration deliberately and repeat the Inspector test.

Or skip the browser setup

If your goal is to give an AI agent clean website screenshots, ScreenshotNeo provides an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. It also has a direct HTTP API. See the ScreenshotNeo API documentation for the complete option list.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Before capture, cookie and consent banners, newsletter popups, and chat widgets are removed. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed; response headers identify the page verdict and whether the request was billed. You can configure full-page capture, element selectors, device presets, dark mode, retina scale, waits, custom CSS and JavaScript, request blocking, cookies, headers, geolocation, PDFs, caching, signed links, asynchronous jobs, bulk capture, and more.

The free plan includes 1,000 screenshots each month with no card. Paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

FAQ

Does Claude Code support OAuth 2.0 for remote MCP servers?

Yes. Remote servers use HTTP or Streamable HTTP transport, and authentication is completed from the /mcp panel.

Can I force a specific OAuth scope?

Yes. Set oauth.scopes to a space-separated scope string. It overrides discovered scopes.

Should I put a client secret in .mcp.json?

No. Keep secrets out of committed configuration and provide them through the CLI secret option or a secure secret store.

What should I use when Claude Code and the provider disagree about OAuth?

Run the flow in MCP Inspector first. It shows whether the server metadata, redirect URI, scopes, and token exchange work independently of Claude Code.