> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Gmail

**Authentication:** OAuth 2.0
**Categories:** Communication
## What you can do

Connect this agent connector to let your agent:

- **Read emails** — fetch messages, threads, and attachments from any label or inbox
- **Send and reply** — compose new emails and reply to existing threads on behalf of your users
- **Search messages** — query Gmail with full search syntax to find emails by sender, subject, or content
- **Manage labels** — apply, remove, and list labels to organize messages
- **Access contacts** — look up contacts and people from the user's address book

## Authentication

This connector uses **OAuth 2.0**. Scalekit acts as the OAuth client: it redirects your user to Gmail, obtains an access token, and automatically refreshes it before it expires. Your agent code never handles tokens directly — you only pass a `connectionName` and a user `identifier`.

You supply your Gmail **Connected App** credentials (Client ID + Secret) once per environment in the Scalekit dashboard.

Before calling this connector from your code, create the Gmail connection in **AgentKit** > **Connections** and copy the exact **Connection name** from that connection into your code. The value in code must match the dashboard exactly.

## Set up the connector

Register your Scalekit environment with the Gmail connector so Scalekit handles the authentication flow and token lifecycle for you. The connection name you create will be used to identify and invoke the connection programmatically. Then complete the configuration in your application as follows:

> caution
>
> Google applications using scopes that permit access to certain user data must complete a verification process.

1. ### Set up auth redirects

    - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. Find **Gmail** and click **Create**.

      > By default, a connection using Scalekit's credentials will be created. If you are testing, go directly to the Usage section. Before going to production, update your connection by following the steps below.

    - Click **Use your own credentials** and copy the redirect URI. It looks like `https:///sso/v1/oauth//callback`.

      > Image: Copy redirect URI from Scalekit dashboard

    - Navigate to [Google Cloud Console](https://console.cloud.google.com/projectselector2/home/dashboard?supportedpurview=project) → **APIs & Services** → **Credentials**. Click **+ Create Credentials**, then **OAuth client ID**. Choose **Web application** as the application type.

      > Image: Select Web application in Google Cloud Console

    - Under **Authorized redirect URIs**, click **+ Add URI**, paste the redirect URI, and click **Create**.

      > Image: Add authorized redirect URI in Google Cloud Console

2. ### Enable Gmail API

    - In [Google Cloud Console](https://console.cloud.google.com/projectselector2/home/dashboard?supportedpurview=project), go to **APIs & Services** → **Library**. Search for "Gmail API" and click **Enable**.

      > Image: Enable Gmail API in Google Cloud Console

3. ### Get client credentials

    Google provides your Client ID and Client Secret after you create the OAuth client ID in step 1.

4. ### Add credentials in Scalekit

    - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** and open the connection you created.

    - Enter your credentials:
      - Client ID (from above)
      - Client Secret (from above)
      - Permissions (scopes beginning with `gmail` — see [Google API Scopes reference](https://developers.google.com/identity/protocols/oauth2/scopes))

      > Image: Add credentials for Gmail in Scalekit dashboard
    - Click **Save**.

## Code examples

Connect a user's Gmail account and make API calls on their behalf — Scalekit handles OAuth and token management automatically.

## Discover tool names

Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you're not sure which name to use, list the tools available for this Gmail connection first.

  ### Node.js

```typescript

const connectionName = 'your-gmail-connection'; // copy the exact Connection name from AgentKit > Connections
const identifier = 'user_123'; // your unique user identifier

const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENV_URL,
  process.env.SCALEKIT_CLIENT_ID,
  process.env.SCALEKIT_CLIENT_SECRET
);

const { tools } = await scalekit.tools.listScopedTools(identifier, {
  filter: { connectionNames: [connectionName] },
  pageSize: 100,
});

for (const scopedTool of tools) {
  console.log('Available tool:', scopedTool.tool?.definition?.name);
}
```

  ### Python

```python

from dotenv import load_dotenv
from google.protobuf.json_format import MessageToDict
from scalekit.v1.tools.tools_pb2 import ScopedToolFilter

load_dotenv()

connection_name = "your-gmail-connection"  # copy the exact Connection name from AgentKit > Connections
identifier = "user_123"  # your unique user identifier

scalekit_client = scalekit.client.ScalekitClient(
    client_id=os.getenv("SCALEKIT_CLIENT_ID"),
    client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
    env_url=os.getenv("SCALEKIT_ENV_URL"),
)
actions = scalekit_client.actions

scoped_response, _ = actions.tools.list_scoped_tools(
    identifier=identifier,
    filter=ScopedToolFilter(connection_names=[connection_name]),
    page_size=100,
)

for scoped_tool in scoped_response.tools:
    definition = MessageToDict(scoped_tool.tool).get("definition", {})
    print("Available tool:", definition.get("name"))
```

## Use Gmail response fields as returned

Response fields from Gmail tools use camelCase, such as `threadId`, `messageId`, and `internalDate`. Tool input parameters use the snake_case names shown in the Tool list, such as `thread_id` and `message_id`. Extract values with camelCase, then pass them with snake_case. The snippets below assume you already have an active connected account ID for the user.

  ### Node.js

```typescript
const fetchResponse = await actions.executeTool({
  toolName: 'gmail_fetch_mails',
  connectedAccountId,
  toolInput: {
    query: 'is:unread',
    max_results: 5,
  },
});

const messages = Array.isArray(fetchResponse.data?.messages)
  ? fetchResponse.data.messages
  : [];
const threadId = typeof messages[0]?.threadId === 'string' ? messages[0].threadId : '';

const threadResponse = await actions.executeTool({
  toolName: 'gmail_get_thread_by_id',
  connectedAccountId,
  toolInput: {
    thread_id: threadId,
  },
});

console.log(threadResponse.data);
```

  ### Python

```python
fetch_response = actions.execute_tool(
    tool_name="gmail_fetch_mails",
    connected_account_id=connected_account.id,
    tool_input={
        "query": "is:unread",
        "max_results": 5,
    },
)

data = fetch_response.data or {}
messages = data.get("messages", [])
thread_id = messages[0].get("threadId", "") if messages else ""

thread_response = actions.execute_tool(
    tool_name="gmail_get_thread_by_id",
    connected_account_id=connected_account.id,
    tool_input={
        "thread_id": thread_id,
    },
)

print(thread_response.data)
```

## Proxy API Calls

  ### Node.js

```typescript

const connectionName = 'gmail'; // get your connection name from connection configurations
const identifier = 'user_123';  // your unique user identifier

// Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENV_URL,
  process.env.SCALEKIT_CLIENT_ID,
  process.env.SCALEKIT_CLIENT_SECRET
);
const actions = scalekit.actions;

// Authenticate the user
const { link } = await actions.getAuthorizationLink({
  connectionName,
  identifier,
});
console.log('🔗 Authorize Gmail:', link); // present this link to your user for authorization, or click it yourself for testing
process.stdout.write('Press Enter after authorizing...');
await new Promise(r => process.stdin.once('data', r));

// Make a request via Scalekit proxy
const result = await actions.request({
  connectionName,
  identifier,
  path: '/gmail/v1/users/me/profile',
  method: 'GET',
});
console.log(result);
```

  ### Python

```python

from dotenv import load_dotenv
load_dotenv()

connection_name = "gmail"    # get your connection name from connection configurations
identifier = "user_123"      # your unique user identifier

# Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
scalekit_client = scalekit.client.ScalekitClient(
    client_id=os.getenv("SCALEKIT_CLIENT_ID"),
    client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
    env_url=os.getenv("SCALEKIT_ENV_URL"),
)
actions = scalekit_client.actions

# Authenticate the user
link_response = actions.get_authorization_link(
    connection_name=connection_name,
    identifier=identifier
)
# present this link to your user for authorization, or click it yourself for testing
print("🔗 Authorize Gmail:", link_response.link)
input("Press Enter after authorizing...")

# Make a request via Scalekit proxy
result = actions.request(
    connection_name=connection_name,
    identifier=identifier,
    path="/gmail/v1/users/me/profile",
    method="GET"
)
print(result)
```

## Tool list

Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you're not sure which name to use, list the tools available for the current user first.

## Tool list

### `gmail_fetch_mails`

Fetch emails from a connected Gmail account using search filters. Requires a valid Gmail OAuth2 connection.

Parameters:

- `format` (`string`, optional): Format of the returned message.
- `include_spam_trash` (`boolean`, optional): Whether to fetch emails from spam and trash folders
- `label_ids` (`array`, optional): Gmail label IDs to filter messages
- `max_results` (`integer`, optional): Maximum number of emails to fetch
- `page_token` (`string`, optional): Page token for pagination
- `query` (`string`, optional): Search query string using Gmail's search syntax (e.g., 'is:unread from:user@example.com')
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `tool_version` (`string`, optional): Optional tool version to use for execution

### `gmail_get_attachment_by_id`

Retrieve a specific attachment from a Gmail message using the message ID and attachment ID.

Parameters:

- `attachment_id` (`string`, required): Unique Gmail attachment ID
- `message_id` (`string`, required): Unique Gmail message ID that contains the attachment
- `file_name` (`string`, optional): Preferred filename to use when saving/returning the attachment
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `tool_version` (`string`, optional): Optional tool version to use for execution

### `gmail_get_contacts`

Fetch a list of contacts from the connected Gmail account. Supports pagination and field filtering.

Parameters:

- `max_results` (`integer`, optional): Maximum number of contacts to fetch
- `page_token` (`string`, optional): Token to retrieve the next page of results
- `person_fields` (`array`, optional): Fields to include for each person
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `tool_version` (`string`, optional): Optional tool version to use for execution

### `gmail_get_message_by_id`

Retrieve a specific Gmail message using its message ID. Optionally control the format of the returned data.

Parameters:

- `message_id` (`string`, required): Unique Gmail message ID
- `format` (`string`, optional): Format of the returned message.
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `tool_version` (`string`, optional): Optional tool version to use for execution

### `gmail_get_thread_by_id`

Retrieve a specific Gmail thread by thread ID. Optionally control message format and metadata headers. Requires a valid Gmail OAuth2 connection with read access.

Parameters:

- `thread_id` (`string`, required): Unique Gmail thread ID
- `format` (`string`, optional): Format of messages in the returned thread.
- `metadata_headers` (`array`, optional): Specific email headers to include when format is metadata
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `tool_version` (`string`, optional): Optional tool version to use for execution

### `gmail_list_drafts`

List draft emails from a connected Gmail account. Requires a valid Gmail OAuth2 connection.

Parameters:

- `max_results` (`integer`, optional): Maximum number of drafts to fetch
- `page_token` (`string`, optional): Page token for pagination
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `tool_version` (`string`, optional): Optional tool version to use for execution

### `gmail_list_threads`

List threads in a connected Gmail account using optional search and label filters. Requires a valid Gmail OAuth2 connection with read access.

Parameters:

- `include_spam_trash` (`boolean`, optional): Whether to include threads from Spam and Trash
- `label_ids` (`array`, optional): Gmail label IDs to filter threads (threads must match all labels)
- `max_results` (`integer`, optional): Maximum number of threads to return
- `page_token` (`string`, optional): Page token for pagination
- `query` (`string`, optional): Search query string using Gmail search syntax (for example, 'is:unread from:user@example.com')
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `tool_version` (`string`, optional): Optional tool version to use for execution

### `gmail_search_people`

Search people or contacts in the connected Google account using a query. Requires a valid Google OAuth2 connection with People API scopes.

Parameters:

- `query` (`string`, required): Text query to search people (e.g., name, email address).
- `other_contacts` (`boolean`, optional): Whether to include people not in the user's contacts (from 'Other Contacts').
- `page_size` (`integer`, optional): Maximum number of people to return.
- `person_fields` (`array`, optional): Fields to retrieve for each person.
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `tool_version` (`string`, optional): Optional tool version to use for execution


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
