OAuth Setup Guide
This guide provides step-by-step instructions for setting up OAuth authentication with MCP servers.
Table of Contentsβ
- Introduction
- OAuth Concepts
- Prerequisites
- Step-by-Step Setup
- Provider Examples
- Token Management
- Security Best Practices
- Troubleshooting
Introductionβ
OAuth 2.0 is an industry-standard protocol for authorization. Radium uses OAuth to securely authenticate with remote MCP servers that require authentication.
Why OAuth?β
- Security: Tokens are stored securely and automatically refreshed
- Standard: Works with any OAuth 2.0 compliant provider
- Automatic: Token refresh happens automatically
- Flexible: Supports various OAuth providers (GitHub, Google, custom)
OAuth Conceptsβ
Key Termsβ
- Client ID: Public identifier for your application
- Client Secret: Secret key for your application (keep secure!)
- Access Token: Token used to authenticate API requests
- Refresh Token: Token used to obtain new access tokens
- Token URL: Endpoint for obtaining and refreshing tokens
- Authorization URL: Endpoint for user authorization (if required)
OAuth Flowβ
- Registration: Register your application with the OAuth provider
- Configuration: Add OAuth credentials to MCP server config
- Initial Token: Obtain initial access token (may require manual step)
- Automatic Refresh: Radium automatically refreshes tokens when expired
Prerequisitesβ
Before setting up OAuth, you need:
- OAuth Provider Account: Account with the OAuth provider (GitHub, Google, etc.)
- OAuth Application: Registered OAuth application with the provider
- Credentials: Client ID and Client Secret from the provider
- Token Endpoint: URL for token acquisition and refresh
Step-by-Step Setupβ
Step 1: Register OAuth Applicationβ
Register your application with the OAuth provider:
- Log in to the provider's developer portal
- Create a new OAuth application
- Configure redirect URI (if required by provider)
- Note the Client ID and Client Secret
Step 2: Configure MCP Serverβ
Add OAuth configuration to your MCP server config:
[[servers]]
name = "oauth-server"
transport = "http"
url = "https://api.example.com/mcp"
auth = {
auth_type = "oauth",
params = {
token_url = "https://api.example.com/oauth/token",
client_id = "your-client-id",
client_secret = "your-client-secret"
}
}
Step 3: Obtain Initial Tokenβ
For the first connection, you may need to obtain an initial token manually:
-
Option A: Provider-specific flow
- Some providers provide a web interface for token generation
- Follow provider's documentation for initial token acquisition
-
Option B: OAuth Authorization Flow
- Use OAuth authorization URL to get authorization code
- Exchange authorization code for access token
- Save token to
~/.radium/mcp_tokens/{server-name}.json
-
Option C: Personal Access Token
- Some providers (like GitHub) allow personal access tokens
- Create token in provider settings
- Use as initial access token
Step 4: Verify Configurationβ
Test your OAuth setup:
# Test connection
rad mcp test --server oauth-server
# Check token status
rad mcp auth status
Step 5: Automatic Refreshβ
Once configured, Radium automatically:
- Detects when tokens are expired
- Refreshes tokens using the refresh token
- Updates stored tokens
- Retries failed requests after refresh
Provider Examplesβ
GitHub OAuthβ
Step 1: Create GitHub OAuth Appβ
- Go to GitHub Settings β Developer settings β OAuth Apps
- Click "New OAuth App"
- Fill in:
- Application name: "Radium MCP"
- Homepage URL:
https://radium.dev - Authorization callback URL:
http://localhost:8080/callback(or your callback URL)
- Click "Register application"
- Note the Client ID
- Generate a Client Secret
Step 2: Configure Radiumβ
[[servers]]
name = "github-mcp"
transport = "http"
url = "https://api.github.com/mcp"
auth = {
auth_type = "oauth",
params = {
token_url = "https://github.com/login/oauth/access_token",
client_id = "your-github-client-id",
client_secret = "your-github-client-secret"
}
}
Step 3: Initial Token (GitHub Personal Access Token)β
For GitHub, you can use a Personal Access Token:
- Go to GitHub Settings β Developer settings β Personal access tokens
- Generate new token (classic)
- Select required scopes
- Copy the token
- Create token file manually:
mkdir -p ~/.radium/mcp_tokens
cat > ~/.radium/mcp_tokens/github-mcp.json <<EOF
{
"access_token": "ghp_your_token_here",
"token_type": "Bearer",
"expires_at": null
}
EOF
chmod 600 ~/.radium/mcp_tokens/github-mcp.json
Google OAuthβ
Step 1: Create Google OAuth Credentialsβ
- Go to Google Cloud Console
- Create a new project or select existing
- Enable the API you need
- Go to "Credentials" β "Create Credentials" β "OAuth client ID"
- Configure OAuth consent screen
- Create OAuth client ID (Web application)
- Note the Client ID and Client Secret
Step 2: Configure Radiumβ
[[servers]]
name = "google-mcp"
transport = "http"
url = "https://api.google.com/mcp"
auth = {
auth_type = "oauth",
params = {
token_url = "https://oauth2.googleapis.com/token",
client_id = "your-google-client-id",
client_secret = "your-google-client-secret"
}
}
Step 3: Initial Tokenβ
Google OAuth typically requires an authorization flow:
- Use Google's OAuth playground or a tool to get initial token
- Save token with refresh token to
~/.radium/mcp_tokens/google-mcp.json
Custom OAuth Providerβ
Step 1: Get Provider Informationβ
Obtain from your OAuth provider:
- Token endpoint URL
- Client ID
- Client Secret
- Required scopes (if any)
Step 2: Configure Radiumβ
[[servers]]
name = "custom-api"
transport = "http"
url = "https://api.custom.com/mcp"
auth = {
auth_type = "oauth",
params = {
token_url = "https://api.custom.com/oauth/token",
client_id = "your-client-id",
client_secret = "your-client-secret",
scope = "read write" # Optional: provider-specific scopes
}
}
Step 3: Initial Tokenβ
Follow your provider's documentation for initial token acquisition.
Token Managementβ
Token Storageβ
Tokens are stored in: ~/.radium/mcp_tokens/{server-name}.json
Token File Formatβ
{
"access_token": "eyJhbGc...",
"token_type": "Bearer",
"refresh_token": "def502...",
"expires_at": 1234567890,
"scope": "read write"
}
Checking Token Statusβ
# Check token status for all servers
rad mcp auth status
# Check specific server
rad mcp auth status --server github-mcp
Manual Token Refreshβ
Tokens refresh automatically, but you can trigger a refresh:
# Refresh token for a server
rad mcp auth refresh --server github-mcp
Token Expirationβ
Tokens are automatically refreshed when:
- Token is expired (based on
expires_at) - Server returns 401 Unauthorized
- Before connection if token is already expired
Token Permissionsβ
Token files have restricted permissions (0600) on Unix:
- Owner: read/write
- Group: no access
- Others: no access
Security Best Practicesβ
1. Secure Credential Storageβ
- Never commit credentials to version control
- Store credentials in environment variables or secure vault
- Use
.gitignoreto exclude config files with secrets
2. Token Securityβ
- Tokens stored with restricted permissions (0600)
- Tokens automatically refreshed to minimize exposure
- Old tokens invalidated when refreshed
3. Credential Rotationβ
- Rotate client secrets periodically
- Revoke old tokens when rotating
- Update configuration with new credentials
4. Scope Limitationβ
- Request only necessary OAuth scopes
- Use least privilege principle
- Review and minimize granted permissions
5. HTTPS Onlyβ
- Always use HTTPS for token endpoints
- Verify SSL certificates
- Don't use HTTP for production
6. Environment Variablesβ
For sensitive credentials, consider using environment variables:
[[servers]]
name = "api-server"
transport = "http"
url = "https://api.example.com/mcp"
auth = {
auth_type = "oauth",
params = {
token_url = "https://api.example.com/oauth/token",
client_id = "${OAUTH_CLIENT_ID}",
client_secret = "${OAUTH_CLIENT_SECRET}"
}
}
Note: Environment variable substitution may need to be implemented or done manually.
Troubleshootingβ
Token Not Foundβ
Problem: "No token found for server"
Solutions:
- Check token file exists:
~/.radium/mcp_tokens/{server-name}.json - Verify server name matches configuration
- Initial token may need manual acquisition
- Check token file permissions
Token Expiredβ
Problem: "OAuth token expired"
Solutions:
- Tokens should auto-refresh - check refresh token is present
- Verify
token_urlis correct - Check client credentials are valid
- Ensure refresh token hasn't been revoked
Refresh Token Missingβ
Problem: "No refresh token available"
Solutions:
- Some providers don't return refresh tokens
- May need to re-authenticate manually
- Check provider documentation for refresh token requirements
- Verify OAuth flow includes refresh token grant
Invalid Credentialsβ
Problem: "Authentication error: invalid client"
Solutions:
- Verify
client_idis correct - Verify
client_secretis correct - Check credentials haven't been revoked
- Ensure OAuth app is properly configured with provider
Token Refresh Failsβ
Problem: Token refresh returns error
Solutions:
- Verify
token_urlis correct - Check refresh token is valid
- Verify client credentials are correct
- Check provider's token refresh requirements
- Review provider logs for detailed error
401 Unauthorized After Refreshβ
Problem: Still getting 401 after token refresh
Solutions:
- Verify new token is being used
- Check token has required scopes
- Verify server accepts the token format
- Check token hasn't been revoked on provider side
Common OAuth Providersβ
GitHubβ
- Token URL:
https://github.com/login/oauth/access_token - Authorization URL:
https://github.com/login/oauth/authorize - Documentation: https://docs.github.com/en/apps/oauth-apps
Googleβ
- Token URL:
https://oauth2.googleapis.com/token - Authorization URL:
https://accounts.google.com/o/oauth2/v2/auth - Documentation: https://developers.google.com/identity/protocols/oauth2
Microsoft/Azure ADβ
- Token URL:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token - Authorization URL:
https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize - Documentation: https://docs.microsoft.com/en-us/azure/active-directory/develop/
Custom Providerβ
For custom OAuth providers, you'll need:
- Token endpoint URL
- Authorization endpoint URL (if required)
- Client ID and Secret
- Required scopes
- Provider-specific configuration
Advanced Topicsβ
Custom Token Endpointβ
Some providers use different token endpoint formats:
auth = {
auth_type = "oauth",
params = {
token_url = "https://api.example.com/v2/oauth/token",
client_id = "client-id",
client_secret = "client-secret",
grant_type = "refresh_token" # Some providers require explicit grant type
}
}
Token Refresh Behaviorβ
Tokens are automatically refreshed when:
- Token is expired (based on
expires_at) - Server returns 401 Unauthorized
- Before connection if token is already expired
Refresh uses the refresh token to obtain a new access token without user interaction.
Multiple OAuth Serversβ
You can configure multiple OAuth-authenticated servers:
[[servers]]
name = "github-api"
transport = "http"
url = "https://api.github.com/mcp"
auth = { auth_type = "oauth", params = { ... } }
[[servers]]
name = "google-api"
transport = "http"
url = "https://api.google.com/mcp"
auth = { auth_type = "oauth", params = { ... } }
Each server maintains its own token independently.
Related Documentationβ
- User Guide - Getting started with MCP
- Configuration Guide - General configuration reference
- OAuth Server Example - OAuth configuration examples
- Troubleshooting - Common OAuth issues
- Authentication - Authentication overview
Referencesβ
- OAuth 2.0 Specification
- OAuth 2.0 Best Practices
- Provider Documentation - Links to provider-specific docs