Some Blaxel integrations support OAuth-based authentication. You can automate such a flow to allow multiple users (tenants) to go through an OAuth flow and each have their integration. This approach is particularly useful when you need to automate the creation of dedicated MCP servers for each tenant with customized access permissions. This guide takes the example of creating such a flow for a Gmail integration.

Prerequisites

We recommend creating a separate OAuth flow specifically for the Gmail integration. Don’t simply add the Gmail scope to an existing OAuth flow, as this would require all users to grant email permissions even when they don’t need Gmail functionality.

Overview of the OAuth flow

The integration follows this redirect pattern:
UI β†’ Your Backend β†’ Google β†’ Your Backend β†’ UI

Step-by-step guide

Step 1: User initiates connection

  • In your app’s UI, user clicks a button to β€œconnect with Google” (or equivalent) during integration setup
  • UI redirects to your backend OAuth endpoint

Step 2: Backend initiates Google OAuth

Your backend should redirect to Google’s OAuth URL with these parameters: Required Scopes:
  • https://www.googleapis.com/auth/gmail.send
  • openid
  • profile
  • email
OAuth URL:
https://accounts.google.com/o/oauth2/auth?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope=email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fgmail.send+openid+profile&response_type=code&access_type=offline

Step 3: Google authorization

  • Google prompts user to login and approve requested scopes
  • Google redirects back to your redirect_uri with a temporary authorization code

Step 4: Exchange Code for Tokens

Your backend exchanges the authorization code for access and refresh tokens: Example: Token Exchange (Python)
import requests
import json

def exchange_code_for_tokens(auth_code, client_id, client_secret, redirect_uri):
    """
    Exchange authorization code for access and refresh tokens
    """
    token_url = "https://oauth2.googleapis.com/token"
    
    data = {
        'code': auth_code,
        'client_id': client_id,
        'client_secret': client_secret,
        'redirect_uri': redirect_uri,
        'grant_type': 'authorization_code'
    }
    
    try:
        response = requests.post(token_url, data=data)
        response.raise_for_status()
        
        token_data = response.json()
        
        return {
            'access_token': token_data['access_token'],
            'refresh_token': token_data['refresh_token'],
            'expires_in': token_data['expires_in']
        }
    
    except requests.exceptions.RequestException as e:
        print(f"Token exchange failed: {e}")
        if hasattr(e.response, 'json'):
            print(f"Error details: {e.response.json()}")
        raise
Example: cURL request
curl -X POST https://oauth2.googleapis.com/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "code=AUTHORIZATION_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "redirect_uri=YOUR_REDIRECT_URI" \
  -d "grant_type=authorization_code"

Step 5: Create integration

Once you have the refresh token, create the integration on Blaxel (for an MCP server in this case) with these parameters:
// Create the integration connection on blaxel (store the secrets values)
curl -X POST https://api.blaxel.ai/v0/integrations/connections \
  -H "Content-Type: application/json" \
  -H "X-Blaxel-Workspace: YOUR_WORKSPACE_ID"
  -H "Authorization: Bearer BL_API_KEY" \
  -d '{
    "metadata": {
      "name": "gmail-google-oauth",
      "displayName": "Gmail Google OAuth Connection"
    },
    "spec": {
      "integration": "gmail",
      "secret": {
        "CLIENT_ID": "your-google-client-id.apps.googleusercontent.com",
        "CLIENT_SECRET": "your-google-client-secret",
        "REFRESH_TOKEN": "user-refresh-token-from-oauth"
      }
    }
  }'
Parameters Required:
  • CLIENT_ID: Your Google OAuth application client ID
  • CLIENT_SECRET: Your Google OAuth application client secret
  • REFRESH_TOKEN: The refresh token obtained from the OAuth flow
You can then create the actual MCP server that uses this integration connection:
// Create the MCP binded to the integration connection
curl -X POST https://api.blaxel.ai/v0/functions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer BL_API_KEY" \
  -H "X-Blaxel-Workspace: YOUR_WORKSPACE_ID"
  -d '{
    "metadata": {
      "name": "gmail-mcp-server",
      "displayName": "Gmail MCP Server"
    },
    "spec": {
      "type": "mcp",
      "integrationConnections": ["gmail-google-oauth"],
      "runtime": {
        "type": "mcp"
      }
    }
  }'

Step 6: Complete Integration

  • Save MCP configuration in your system
  • Redirect user back to frontend with success confirmation
  • Integration is now ready for use

Troubleshooting

  • Invalid scope error: Ensure Gmail API is enabled in Google Cloud Console
  • Redirect URI mismatch: Verify redirect URI matches exactly in Google OAuth app settings
  • Token refresh issues: Check that access_type=offline is included in initial OAuth request