Back to blog
Tutorialoauthauth

OAuth 2.0 MCP servers — the pre-registered client path

Set up OAuth with a known client_id and client_secret. Covers Cast's OAuth mode with full PKCE and state support.

June 3, 2026·6 min read

Overview

OAuth 2.0 is the standard for delegated API access. You have a known client_id and client_secret, and your authorization server issues access tokens. Cast handles the entire token lifecycle — obtaining, caching, and refreshing — so your MCP clients never touch credentials.

This tutorial covers Cast's Custom OAuth provider mode: a pre-registered client with known credentials. For Dynamic Client Registration, see the next tutorial.

1. Start the test server in oauth mode

terminal
cd cast-mcp/test-server
npx ts-node src/index.ts --mode oauth --port 3456

The startup banner prints the pre-registered client credentials:

  🔑 Pre-registered OAuth client:
       client_id     : test-client-id
       client_secret : cs_<generated>
       grant_types   : authorization_code, client_credentials, refresh_token
  🌐 Token endpoint  : http://localhost:3456/auth/token
  🌐 Auth endpoint   : http://localhost:3456/auth/authorize

Copy the client_secret — you'll paste it into Cast.

2. Create a workspace and upload the spec

New workspace → Upload → http://localhost:3456/openapi.json → wait for tool generation.

Workspace navigationactual UI
overview
upload
configure
connect
analytics
logs

3. Configure auth — OAuth 2.0 → Custom OAuth

Switch to Configure. In the Auth section, click the OAuth 2.0 card. Below the auth type grid, a provider selector appears. Choose Custom OAuth since you have a pre-registered client_id and secret.

Fill in the URLs and credentials exactly as shown. The scopes match what the test server expects.

Workspace navigationactual UI
overview
upload
configure
connect
analytics
logs
Configure → Auth → OAuth 2.0actual UI

API Base URL

http://localhost:3456
🔑

Bearer Token

Authorization: Bearer <token>

#

API Key Header

X-Api-Key: <key>

Custom Headers

Any header name + value

🌐

OAuth 2.0

PKCE · DCR support

OAuth / DCR Provider

Recommended

Cast DCR

We handle Dynamic Client Registration automatically. Zero config.

🏢

Your own DCR

Use your OAuth server's DCR endpoint.

Custom OAuth

Provide client_id and client_secret directly.

Authorization URL

http://localhost:3456/auth/authorize

Token URL

http://localhost:3456/auth/token

Client ID

test-client-id

Client Secret

•••••••••

OAuth Scopes

read:items×write:items×read:users×

PKCE

Proof Key for Code Exchange

State parameter

CSRF protection

Save auth configuration
💡

Not sure which grant type your server uses? Check its metadata at /.well-known/oauth-authorization-server. The test server exposes this endpoint.

How Cast handles the OAuth flow

When an MCP client first connects, Cast initiates an OAuth authorization_code + PKCE flow. The client sees a browser redirect to your authorization endpoint. After the user approves, Cast receives the callback, exchanges the code for tokens, and stores them encrypted. All subsequent tool calls attach the access token silently; Cast refreshes it before expiry.

4. Enable tools

Configure → Toolsactual UI
GET

listItems

/api/items

POST

createItem

/api/items

GET

listUsers

/api/users

GET

getItem

/api/items/{id}

DELETE

deleteItem

/api/items/{id}

Save changes

5. Connect and test

Workspace navigationactual UI
overview
upload
configure
connect
analytics
logs
Connect → Your MCP URLactual UI
Claude Desktop
Cursor
Windsurf
Cline
claude_desktop_config.json Copy
{
  "mcpServers": {
    "test-oauth": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote@latest",
        "https://mcp.getcast.io/test-oauth-cmpqg61ej002c"
      ]
    }
  }
}
Server active · 0 errors

On first connection, Claude Desktop opens a browser window for the OAuth authorization flow. After you authorize, Cast stores the tokens and subsequent calls happen silently.