> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blaxel.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OAuth flow for integrations

> Set up a user-facing OAuth flow so end-users can authorize integration connections to third-party services through your Blaxel application.

Some Blaxel integrations support [OAuth](https://oauth.net/2/)-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](/Integrations/Gmail).

## **Prerequisites**

* A Google OAuth application configured with the scope [`https://www.googleapis.com/auth/gmail.send`](https://www.googleapis.com/auth/gmail.send) (see below for guide)
* Client ID and Client Secret from your OAuth app
* A backend server to handle the OAuth flow

<Accordion title="How to create a Google OAuth app">
  ### 1. Create the APP

  * Go to [https://console.cloud.google.com/auth/clients](https://console.cloud.google.com/auth/clients)

  [](https://lh7-rt.googleusercontent.com/docsz/AD_4nXcFD1le5fn-eMiyTjOee-bHWxp1UjI1AGyCszco9b-mdjaIoN1mnDtOmKbEAW8LsocvYGiroJJwCi_SHFgzKLwYoHoG5UweSDlS3Smm-r0f0RMvr85KCx4Rp_6MdhwweRdRcBpeaQ?key=Pe48uQJwhyRkAD1JsBWU4Q)

  * Select *Web application*
  * Choose a name. It will be displayed when your user logins through Google
  * The redirect URIs will be the URL where your user will be redirected to after Google authorizes the request. It must be server-side as it will need to access secret credentials.

  Finish creating the application. You’ll be given you a *client\_id* and *client\_secret:* keep them securely.

  ### 2. Configure scope

  Scopes are used to request sufficient access on the user’s account. In this example, we want to connect his account to the MCP server to send emails.

  * Go to Data access

  [](https://lh7-rt.googleusercontent.com/docsz/AD_4nXcikg83r7fMeZkFl_4JM0evSGUH7oj_EsJtMMjYHwrtiHZrq_1smDrui7kpxbPy-Vqj9-Y6P0pazODg1vPxG5S_Rh5eeqADVjatdfXqukuKc9kx6rGYNbnmnAsnIZfQCOdCxlBmJw?key=Pe48uQJwhyRkAD1JsBWU4Q)

  * Click on “Add or remove scopes”
  * Add `gmail.send`

  [](https://lh7-rt.googleusercontent.com/docsz/AD_4nXeiuINtnWLiOcK94UIMLCoqc7N7L-gQRtvXdKcTmab1yvTpLTwWZ_jvw8fy1ygeONhm8lRsKnTjP_-M6xuzOh-wE0FAm7_qgtgMAAQnP00Y0IVXOvCGt2aT3Inf-tUxvwUclvbi?key=Pe48uQJwhyRkAD1JsBWU4Q)

  <Info>Some scopes (like this one) require an HTTPS callback URL. You won’t be able to test them easily locally without using *ngrok* or a similar tool which allows you to have an HTTPS URL bound to your localhost.</Info>

  <Info>By default, it will work with your own account without any review by Google. You can look for the Audience tab on left to add more users. To make it global, you will need to launch a review process from Google with the “Publish app” button.</Info>
</Accordion>

<Warning>**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.</Warning>

## **Overview of the OAuth flow**

The integration follows this redirect pattern:

```text theme={null}
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:**

```text theme={null}
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)**

```python theme={null}
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**

```bash theme={null}
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:

```bash theme={null}
// 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](../Functions/Overview) that uses this integration connection:

```bash theme={null}
// 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
