Skip to Content
User Guide🎁 Special FeaturesCustom MCP ServerOAuth2 Authentication & DCR Guide

OAuth2 Authentication & DCR Guide

This guide explains how to apply OAuth 2.0 authentication to Custom Remote MCP servers. With Dynamic Client Registration (DCR) support, users can complete authentication automatically by simply entering a URL.

Overview

QuestionAnswer
Does Custom MCP support OAuth2?✅ Fully supported.
Can each user authenticate individually?✅ Yes, tokens are managed per user.
Is DCR required?❌ No, it’s optional. Without it, users manually enter Client ID/Secret.
What are the benefits of DCR?Automatic client registration greatly improves the user experience.

OAuth2 Authentication Methods

When you enter the MCP server URL, AIP automatically detects OAuth metadata and operates in one of three modes:

OAuthWithDCR (Automatic Client Registration)

  • Condition: MCP server supports DCR specification
  • User Action: Enter URL only
  • AIP Process: Automatically registers client
  • Result: OAuth popup appears automatically

OAuth (Manual Client ID/Secret Entry)

  • Condition: MCP server does not support DCR
  • User Action: Manually enter Client ID / Secret
  • AIP Process: Processes OAuth with the provided credentials
  • Result: OAuth popup appears

NoAuth (No Authentication)

  • Condition: OAuth metadata discovery does not return usable metadata
  • User Action: None
  • AIP Process: No OAuth flow is started for this setup
  • Result: No OAuth popup

As soon as you enter the MCP server URL, AIP automatically performs OAuth Discovery to determine which authentication method to use.

What is DCR

Dynamic Client Registration (DCR) is a standard protocol defined in RFC 7591  that allows an OAuth2 client (AIP) to automatically register with an Authorization Server and obtain a Client ID and Secret.

Without DCR (Traditional Flow)

  1. User manually creates an OAuth App on the service.
  2. Obtains Client ID / Secret.
  3. Manually enters them in AIP.
  4. OAuth popup proceeds.

With DCR

  1. User simply enters the MCP Server URL in AIP.
  2. AIP automatically registers a client with the server.
  3. Client ID / Secret obtained automatically.
  4. OAuth popup proceeds (no user input required).

How DCR Support is Detected

AIP checks whether the Authorization Server Metadata contains a registration_endpoint field:

// Example response from /.well-known/oauth-authorization-server { "issuer": "https://mcp.example.com", "authorization_endpoint": "https://mcp.example.com/oauth/authorize", "token_endpoint": "https://mcp.example.com/oauth/token", "registration_endpoint": "https://mcp.example.com/oauth/register" // DCR supported if present }

AIP’s Automatic OAuth Detection Flow

When an MCP server URL is entered, the AIP backend automatically performs the following detection steps:

  1. Send POST request to MCP server
    • 401 response + WWW-Authenticate header → Extract Protected Resource Metadata URL
    • No 401 → Check /.well-known/oauth-protected-resource
  2. Extract authorization_servers from Protected Resource Metadata
  3. Fetch Authorization Server Metadata (ASM) — Priority Order
    • RFC 8414: /.well-known/oauth-authorization-server/{path}
    • OIDC (path insertion): /.well-known/openid-configuration/{path}
    • OIDC (path appending): /{path}/.well-known/openid-configuration
  4. Determine authentication method
    • ASM fetch fails → NoAuth (metadata fallback)
    • ASM has registration_endpointOAuthWithDCR
    • ASM has no registration_endpointOAuth (manual input)

If OAuth metadata cannot be resolved during Discovery, metadata detection falls back to NoAuth and no OAuth popup is shown. DCR runtime failures are handled separately: AIP returns a DCR unsupported error and the UI falls back to manual Client ID / Secret input.

Setup Guide

Connecting a DCR-Supported Server (e.g., Linear)

Enter URL

Go to Integrations → All Integrations → click Custom MCP Integration Setup and enter the MCP Server URL.

Automatic Authentication

AIP automatically performs DCR and an OAuth popup appears. Log in with your service account to complete the integration.

Token Management

Each user authenticates independently. Tokens are managed separately per user.

Connecting a Non-DCR Server (e.g., Salesforce)

Add MCP in AIP

  1. Go to Integrations → All Integrations → Custom MCP Integration Setup and enter the MCP Server URL.
  2. Click Install — a Client ID / Secret input dialog appears. The dialog also displays the OAuth Callback URL (with a copy button) and the list of required Scopes.

Create an OAuth App

Create an OAuth App in the MCP server’s admin console:

  1. Enable OAuth Settings.
  2. Enter the Callback URL. Copy the OAuth Callback URL from AIP’s Client ID / Secret input dialog and register it.
  3. Select the required Scopes.
  4. Note the Client ID and Client Secret.

OAuth Login

  1. Return to AIP’s Client ID / Secret input dialog and enter the Client ID / Secret from the previous step.
  2. Log in with your service account via the OAuth popup. Once login is complete, AIP receives authentication tokens from the service and the integration is finalized. For details on the internal processing, see OAuth2 Internal Processing Flow.

For Salesforce Custom Domain environments, AIP automatically requests re-login to prevent cross-org OAuth errors. If the issue persists, try using a separate browser profile.

Connecting Internal Network Servers (Edge Tunnel Required)

If the MCP server runs on an internal network or localhost:

  1. Start Edge Tunnel using the AIP Desktop CLI.
  2. Check the “Use Edge Tunnel” option when configuring the Custom MCP.
  3. The subsequent OAuth Discovery and authentication flow proceeds as usual.

For details, see the Edge Tunnel documentation.

Challenges When DCR is Not Supported

Issues that may arise when integrating MCP servers without DCR support:

  • Manual client setup required — Someone configuring the integration must create or register an OAuth app and provide Client ID / Secret.
  • Scope misconfiguration — AIP provides scope guidance, but users must manually add scopes to their OAuth App. Missing scopes cause tool call failures.
  • Client Secret security — Secrets are directly entered into AIP, increasing operational burden.
  • Operational complexity — Re-entry is required when Client ID/Secret expires or is rotated.
  • High adoption barrier — Creating an OAuth App is a difficult task for non-technical users.

DCR Implementation Guide (For MCP Server Developers)

To enable DCR support on your MCP server, you need both the two metadata endpoints and the registration_endpoint implementation that the metadata points to.

1. Protected Resource Metadata

GET /.well-known/oauth-protected-resource Response: { "resource": "https://mcp.example.com", "authorization_servers": ["https://auth.example.com"] }

2. Authorization Server Metadata

The registration_endpoint must be included for AIP to recognize DCR support.

GET /.well-known/oauth-authorization-server Response: { "issuer": "https://auth.example.com", "authorization_endpoint": "https://auth.example.com/authorize", "token_endpoint": "https://auth.example.com/token", "registration_endpoint": "https://auth.example.com/register", "scopes_supported": ["read", "write"], "response_types_supported": ["code"], "grant_types_supported": ["authorization_code", "refresh_token"], "code_challenge_methods_supported": ["S256"], "token_endpoint_auth_methods_supported": ["client_secret_basic"] }

Without registration_endpoint, AIP automatically falls back to the OAuth (manual input) method. Including S256 in code_challenge_methods_supported enables AIP to automatically apply PKCE for enhanced security. This is recommended.

3. Client Registration Endpoint

The registration_endpoint is a POST endpoint that AIP calls directly during automatic client registration. It must accept client metadata in RFC 7591 format and return registration results including client_id and client_secret.

POST /oauth/register Content-Type: application/json Request: { "client_name": "Custom MCP Client of AI Platform", "redirect_uris": ["https://{aip-domain}/integration/oauth/callback"], "grant_types": ["authorization_code", "refresh_token"], "scope": "read write", "token_endpoint_auth_method": "client_secret_basic" } Response (201 Created): { "client_id": "aip_123456789", "client_secret": "replace-with-secure-secret", "client_id_issued_at": 1712236800, "client_secret_expires_at": 0, "redirect_uris": ["https://{aip-domain}/integration/oauth/callback"], "grant_types": ["authorization_code", "refresh_token"], "token_endpoint_auth_method": "client_secret_basic" }

Implementation Example (Node.js)

const crypto = require('crypto'); // Protected Resource Metadata app.get('/.well-known/oauth-protected-resource', (req, res) => { res.json({ resource: 'https://mcp.example.com', authorization_servers: ['https://auth.example.com'] }); }); // Authorization Server Metadata app.get('/.well-known/oauth-authorization-server', (req, res) => { res.json({ issuer: 'https://auth.example.com', authorization_endpoint: 'https://auth.example.com/authorize', token_endpoint: 'https://auth.example.com/token', registration_endpoint: 'https://auth.example.com/register', scopes_supported: ['read', 'write', 'admin'], response_types_supported: ['code'], code_challenge_methods_supported: ['S256'], grant_types_supported: ['authorization_code', 'refresh_token'], token_endpoint_auth_methods_supported: ['client_secret_basic'] }); }); // Client Registration Endpoint app.post('/oauth/register', (req, res) => { res.status(201).json({ client_id: `aip_${crypto.randomBytes(16).toString('hex')}`, client_secret: crypto.randomBytes(32).toString('hex'), client_id_issued_at: Math.floor(Date.now() / 1000), client_secret_expires_at: 0, redirect_uris: req.body.redirect_uris ?? [], grant_types: req.body.grant_types ?? ['authorization_code', 'refresh_token'], token_endpoint_auth_method: req.body.token_endpoint_auth_method ?? 'client_secret_basic' }); });

Implementation Example (Python)

from flask import Flask, jsonify, request import time import secrets app = Flask(__name__) @app.route('/.well-known/oauth-protected-resource') def oauth_resource_metadata(): return jsonify({ 'resource': 'https://mcp.example.com', 'authorization_servers': ['https://auth.example.com'] }) @app.route('/.well-known/oauth-authorization-server') def oauth_authorization_server(): return jsonify({ 'issuer': 'https://auth.example.com', 'authorization_endpoint': 'https://auth.example.com/authorize', 'token_endpoint': 'https://auth.example.com/token', 'registration_endpoint': 'https://auth.example.com/register', 'scopes_supported': ['read', 'write', 'admin'], 'response_types_supported': ['code'], 'code_challenge_methods_supported': ['S256'], 'grant_types_supported': ['authorization_code', 'refresh_token'], 'token_endpoint_auth_methods_supported': ['client_secret_basic'] }) @app.route('/oauth/register', methods=['POST']) def oauth_register(): payload = request.get_json(silent=True) or {} return jsonify({ 'client_id': f'aip_{secrets.token_hex(16)}', 'client_secret': secrets.token_hex(32), 'client_id_issued_at': int(time.time()), 'client_secret_expires_at': 0, 'redirect_uris': payload.get('redirect_uris', []), 'grant_types': payload.get('grant_types', ['authorization_code', 'refresh_token']), 'token_endpoint_auth_method': payload.get('token_endpoint_auth_method', 'client_secret_basic') }), 201

These examples are minimal implementations for documentation purposes. In production, you should persist registered clients, validate allowed redirect URIs, and implement client secret protection policies.

Troubleshooting

OAuth Popup Does Not Appear

  1. Verify OAuth metadata discovery works correctly.
    curl https://mcp.example.com/.well-known/oauth-protected-resource
    If PRM returns authorization_servers, verify the referenced Authorization Server Metadata is reachable as well.
  2. Confirm AIP can reach the MCP server URL over HTTP (check firewalls).
  3. For internal network servers, check the “Use Edge Tunnel” option.
  4. Verify the MCP Server URL is correct (e.g., https://host/sse).
  5. Confirm the MCP server supports standard OAuth2 Authorization Code Flow.

Authentication Failure

  • Verify Client ID / Secret are correct.
  • Add AIP’s OAuth callback URL to the OAuth app’s redirect URI whitelist.
  • Check server logs for OAuth endpoint error messages.

Per-User Authentication Not Working

  • Log in with a different user account.
  • Verify the MCP server issues different tokens per user.
Last updated on