Installation
- Go to Apps in your workspace
- Search for Google Mail and install it
- Open the app instance configuration and fill in the required fields
Configuration
| Field | Description |
|---|
| Gmail API Base URL | Base URL of the Gmail API (default https://gmail.googleapis.com) |
| API Token (fallback) | Optional static OAuth access token used as a shared fallback for all users of this tenant. Stored as a workspace secret. Most deployments leave this empty and rely on per-user OAuth instead. |
| OAuth2 Client ID | Google OAuth Application Client ID. Create an OAuth client of type Web application in the Google Cloud Console |
| OAuth2 Client Secret | Google OAuth Client Secret, stored as a workspace secret |
| OAuth Callback URL | Auto-populated on install — paste this value into the Authorized redirect URIs list of your Google OAuth client |
| OAuth Authorize URL | Default https://accounts.google.com/o/oauth2/v2/auth |
| OAuth Token URL | Default https://oauth2.googleapis.com/token |
| OAuth Revoke URL | Default https://oauth2.googleapis.com/revoke |
| OAuth Scopes | Space-separated Google API scopes. Default https://mail.google.com/ (full mailbox access). Other common values: gmail.readonly, gmail.send, gmail.modify, gmail.labels, gmail.settings.basic |
| Refresh Token TTL (seconds) | Default 15552000 (180 days, Google’s max) |
| Max Tool Payload (KB) | Threshold above which MCP responses are auto-compacted into a summary + recovery hints to avoid overflowing the LLM context. Default 50. Raise it (for example 200) when targeting LLMs with 1M-token windows |
| MCP Endpoint | Auto-populated on install — URL of the MCP endpoint for this instance |
| MCP API Key | Auto-populated on install — signed key used in the mcp-api-key header. Do not modify |
MCP Endpoint, MCP API Key and OAuth Callback URL are generated automatically by the onInstall flow. The OAuth credentials below (OAuth2 Client ID, OAuth2 Client Secret) must be filled in manually after creating the OAuth client in the Google Cloud Console.
Authorize end-users
Once the app instance is configured, each end-user authorizes their own Google account through a browser-based consent screen:Trigger the connect flow
From an MCP client (Agent Creator capability or any tool client), call any data tool. If no OAuth session exists for the current user × tenant, the MCP server returns a connector_auth_required payload with a connect_url. Alternatively, call the connect tool explicitly to receive the same payload.
Open the connect URL
Open the returned URL in a browser tab where the user is already authenticated to Prisme.ai. The platform redirects to the Google OAuth consent screen.
Grant access
The user reviews the requested scopes (default https://mail.google.com/) and clicks Allow. Google redirects back to the platform’s oauthCallback webhook.
Confirmation
The user sees a Connection complete page and can close the tab. The platform has stored an access token plus refresh token as user-scoped secrets — both are tenant-prefixed so they do not leak across app instances.
Each user’s OAuth tokens are scoped per (user × tenant). A user who has authorized in tenant A does not gain access in tenant B — they must run the connect flow again per app instance. Refresh tokens are rotated by Google on each refresh and live up to 180 days when idle.
Available Instructions
Every instruction resolves credentials from the workspace configuration. The userId argument defaults to me (the authenticated end-user) — pass an explicit email address only when calling on behalf of a delegated account. Most list operations accept maxResults (default 100) and pageToken for pagination, plus a Gmail-style q query string for filtering.Messages
| Instruction | Arguments |
|---|
listMessages | userId, maxResults, pageToken, q, labelIds, includeSpamTrash |
getMessage | userId, id*, format (minimal/metadata/full/raw), metadataHeaders |
sendMessage | userId, raw*, threadId, labelIds, payload |
insertMessage | userId, raw*, threadId, labelIds, payload, internalDateSource, deleted |
importMessage | userId, raw*, threadId, labelIds, payload, internalDateSource, neverMarkSpam, processForCalendar, deleted |
deleteMessage | userId, id* |
trashMessage | userId, id* |
untrashMessage | userId, id* |
modifyMessage | userId, id*, addLabelIds, removeLabelIds |
batchModifyMessages | userId, ids*, addLabelIds, removeLabelIds |
batchDeleteMessages | userId, ids* |
Threads
| Instruction | Arguments |
|---|
listThreads | userId, maxResults, pageToken, q, labelIds, includeSpamTrash |
getThread | userId, id*, format, metadataHeaders |
deleteThread | userId, id* |
trashThread | userId, id* |
untrashThread | userId, id* |
modifyThread | userId, id*, addLabelIds, removeLabelIds |
Attachments
| Instruction | Arguments |
|---|
getAttachment | userId, messageId, id |
Drafts
| Instruction | Arguments |
|---|
listDrafts | userId, maxResults, pageToken, q, includeSpamTrash |
getDraft | userId, id*, format |
createDraft | userId, message* |
updateDraft | userId, id, message |
deleteDraft | userId, id* |
sendDraft | userId, id*, message |
Labels
| Instruction | Arguments |
|---|
listLabels | userId |
getLabel | userId, id* |
createLabel | userId, name*, labelListVisibility, messageListVisibility, color, type |
updateLabel | userId, id*, name, labelListVisibility, messageListVisibility, color, type |
patchLabel | userId, id*, name, labelListVisibility, messageListVisibility, color, type |
deleteLabel | userId, id* |
History
| Instruction | Arguments |
|---|
listHistory | userId, startHistoryId*, maxResults, pageToken, labelId, historyTypes |
Profile & Push Notifications
| Instruction | Arguments |
|---|
getProfile | userId |
watchInbox | userId, topicName*, labelIds, labelFilterAction, labelFilterBehavior |
stopWatch | userId |
Settings
| Instruction | Arguments |
|---|
getAutoForwarding | userId |
updateAutoForwarding | userId, enabled, emailAddress, disposition |
getImap | userId |
updateImap | userId, enabled, autoExpunge, expungeBehavior, maxFolderSize |
getLanguage | userId |
updateLanguage | userId, displayLanguage* |
getPop | userId |
updatePop | userId, accessWindow, disposition |
getVacation | userId |
updateVacation | userId, enableAutoReply, responseSubject, responseBodyPlainText, responseBodyHtml, restrictToContacts, restrictToDomain, startTime, endTime |
Filters
| Instruction | Arguments |
|---|
listFilters | userId |
getFilter | userId, id* |
createFilter | userId, criteria, filterAction |
deleteFilter | userId, id* |
Forwarding Addresses
| Instruction | Arguments |
|---|
listForwardingAddresses | userId |
getForwardingAddress | userId, forwardingEmail* |
createForwardingAddress | userId, forwardingEmail* |
deleteForwardingAddress | userId, forwardingEmail* |
Send-As Aliases
| Instruction | Arguments |
|---|
listSendAs | userId |
getSendAs | userId, sendAsEmail* |
createSendAs | userId, sendAsEmail*, displayName, replyToAddress, signature, isPrimary, treatAsAlias, smtpMsa |
updateSendAs | userId, sendAsEmail*, displayName, replyToAddress, signature, isPrimary, treatAsAlias, smtpMsa |
patchSendAs | userId, sendAsEmail*, displayName, replyToAddress, signature, isPrimary, treatAsAlias, smtpMsa |
deleteSendAs | userId, sendAsEmail* |
verifySendAs | userId, sendAsEmail* |
S/MIME
| Instruction | Arguments |
|---|
listSmimeInfo | userId, sendAsEmail* |
getSmimeInfo | userId, sendAsEmail, id |
insertSmimeInfo | userId, sendAsEmail, pkcs12, encryptedKeyPassword |
deleteSmimeInfo | userId, sendAsEmail, id |
setDefaultSmimeInfo | userId, sendAsEmail, id |
Delegates
| Instruction | Arguments |
|---|
listDelegates | userId |
getDelegate | userId, delegateEmail* |
createDelegate | userId, delegateEmail*, verificationStatus |
deleteDelegate | userId, delegateEmail* |
Arguments flagged with * are required. The userId argument defaults to me — leave it empty unless you explicitly need to address a delegated mailbox.
DSUL Examples
List the latest unread messages in the inbox
- GoogleMail.listMessages:
q: in:inbox is:unread
maxResults: 10
output: inbox
Send a plain-text email
The Gmail API requires the message as a base64url-encoded RFC 2822 string. Build the MIME body in Custom Code first, then pass it as raw.- Custom Code.run:
function: base64url
parameters:
value: |
From: me
To: alice@example.com
Subject: Status update
Hello Alice,
Here is the weekly summary.
output: rawEmail
- GoogleMail.sendMessage:
raw: '{{rawEmail}}'
output: sent
Apply a label to a thread
- GoogleMail.modifyThread:
id: '{{thread_id}}'
addLabelIds:
- IMPORTANT
removeLabelIds:
- UNREAD
output: modified
Enable an out-of-office responder
- GoogleMail.updateVacation:
enableAutoReply: true
responseSubject: I am out of office
responseBodyHtml: |
<p>I am away until April 15. For urgent matters, please contact alice@example.com.</p>
restrictToContacts: false
startTime: '1739923200000'
endTime: '1741132800000'
output: vacation
Create a filter that archives newsletters
- GoogleMail.createFilter:
criteria:
from: newsletter@example.com
filterAction:
addLabelIds:
- Label_1
removeLabelIds:
- INBOX
output: filter
In App mode, the filter.action body field is exposed as filterAction to avoid colliding with the entity-level action selector used by the MCP tool. The connector maps it back to action before sending the request to Gmail.
The Google Mail app ships with a built-in MCP server. Each app instance gets its own signed mcp-api-key that encodes the workspace ID and a credentials lookup URL — the Google OAuth token is never passed through headers and is resolved server-side from the user’s per-tenant secret.The MCP surface is entity-grouped: each MCP tool corresponds to a Gmail entity (e.g. messages, threads, labels) and takes an action argument that maps to one of the underlying operations. This keeps the LLM-facing tool list under 20 entries while still exposing all 68 Gmail operations.Plug into an Agent Creator capability
Agents consume MCP servers directly through Agent Creator capabilities. This is the preferred way to expose Google Mail to an agent.Create or open a workspace
From the Prisme.ai console, create a new workspace (or open the one that will host the connector).
Install the Google Mail app
Open the workspace Imports panel, search for Google Mail and install it.
Configure the credentials
Open the freshly installed app instance settings and fill in the required fields (see the Usage as App tab for the field-by-field reference). At minimum you need OAuth2 Client ID and OAuth2 Client Secret from your Google Cloud OAuth client.
Copy the MCP endpoint and API key
Still on the app instance configuration page, copy the values of MCP Endpoint and MCP API Key — both are generated automatically on install.
Open Agent Creator
Switch to Agent Creator and open the agent you want to extend.
Add a capability
Add a new capability to the agent:
-
If a dedicated Google Mail capability exists — select it and paste the MCP API Key into the
mcp-api-key field. The server URL is already wired.
-
Otherwise — select the generic
custom_mcp capability, paste the MCP Endpoint into the Server URL field, then open the Headers field and add an mcp-api-key entry whose value is the MCP API Key copied earlier:
{
"mcp-api-key": "your-mcp-api-key"
}
Save
The agent now has access to every Google Mail tool exposed by the MCP server.
Brief the agent in its system prompt
Wiring the capability is not enough — the agent also needs to know the MCP exists and when to reach for it. Add a short paragraph to the agent’s system prompt. Copy-pasteable starter:You have access to the Google Mail MCP server. Use it whenever the user asks something that maps to Gmail data — searching the inbox, reading or sending emails, managing labels, threads, drafts, filters or settings. Prefer `format: metadata` for batch message lookups; only request `format: full` for a single message at a time. Confirm with the user before any destructive action (deleteMessage, deleteThread, batchDelete, deleteLabel).
Refine the trigger keywords (resource names, business domains, typical user phrasings) so the agent reliably picks up the right intent in your context. Use this flow to plug the Google Mail MCP into an AI Knowledge agent that does not yet support the native MCP picker.Install the Google Mail app
Install and configure the app in the same workspace as your agent (see the Usage as App tab). Once configured, mcpEndpoint and mcpApiKey are auto-populated.
Copy the MCP credentials
Open the app instance config and copy the values of MCP Endpoint and MCP API Key.
Open your AI Knowledge project
Navigate to Advanced > Tools.
Add an MCP tool
Click Add and select the MCP tab.
Fill in the endpoint
Paste the MCP Endpoint URL copied from the app instance.
Add the auth header
In the Headers field, add the signed API key:{
"mcp-api-key": "your-mcp-api-key"
}
Save
The agent can now list and call Google Mail tools through the MCP endpoint.
The signed mcp-api-key encodes the workspace ID and the getConfig webhook URL. The MCP server validates the signature using the central app secret, fetches the OAuth client configuration from the installed app, and resolves the end-user’s access token from per-user secrets. Credentials are cached per tenant for 10 minutes.
Every tool accepts an outputFormat parameter that controls the MCP response shape:
verbose (default) — human-readable text for LLM consumption
structured — machine-readable JSON in structuredContent
both — both text and structured content
Responses larger than 50 KB (configurable via Max Tool Payload (KB)) are auto-compacted into a summary plus recovery hints. The agent sees the most relevant fields (id, threadId, labelIds, snippet, key headers) and is told how to re-request narrower data — for instance, calling messages.get with format: metadata instead of format: full, or paging with smaller maxResults. This guardrail prevents the connector from blowing past the LLM context window when an agent batches many messages.get calls in parallel.
Each entity tool takes an action argument (a string enum) plus the parameters relevant to that action. The connector dispatches to the matching Gmail REST operation server-side.Messages, Threads, Attachments
| Tool | Actions | Description |
|---|
messages | list, get, send, insert, import, delete, trash, untrash, modify, batchModify, batchDelete | Search the mailbox, read, send and label messages |
threads | list, get, delete, trash, untrash, modify | Browse and modify conversation threads |
attachments | get | Download a message attachment by messageId + id (the attachmentId exposed by messages.get) |
Drafts & History
| Tool | Actions | Description |
|---|
drafts | list, get, create, update, delete, send | Manage and send drafts |
history | list | Stream Gmail history records since a given startHistoryId |
Labels
| Tool | Actions | Description |
|---|
labels | list, get, create, update, patch, delete | CRUD on user labels |
Profile & Push Notifications
| Tool | Actions | Description |
|---|
profile | get, watch, stop | Mailbox profile (email, totals, historyId) and Pub/Sub watch lifecycle |
Settings & Filters
| Tool | Actions | Description |
|---|
settings | getAutoForwarding, updateAutoForwarding, getImap, updateImap, getLanguage, updateLanguage, getPop, updatePop, getVacation, updateVacation | Account-level Gmail settings |
filters | list, get, create, delete | Inbox auto-classification rules |
Identities
| Tool | Actions | Description |
|---|
sendAs | list, get, create, update, patch, delete, verify | Send-as aliases (other email addresses the user can send from) |
smimeInfo | list, get, insert, delete, setDefault | S/MIME certificates attached to a send-as alias (requires Google Workspace Enterprise) |
forwardingAddresses | list, get, create, delete | Whitelisted addresses for automatic forwarding |
delegates | list, get, create, delete | Account-wide delegation (Google Workspace, domain-wide auth) |
OAuth Session
| Tool | Actions | Description |
|---|
connect | (no args) | Initiate the per-user OAuth flow. Returns a connector_auth_required payload with a connect_url. Data tools auto-prompt this when no session is active, so call it directly only when the user explicitly asks to sign in |
disconnect | (no args) | Revoke the current user’s OAuth tokens (RFC 7009) and clear the local secrets |
messages — list
Search the mailbox using Gmail’s standard query syntax (the same one the web UI uses).{
"name": "messages",
"arguments": {
"action": "list",
"q": "from:alice@example.com after:2026/01/01 has:attachment",
"maxResults": 10
}
}
| Parameter | Required | Description |
|---|
action | Yes | Must be list |
q | No | Gmail-style query (e.g. is:unread, from:, to:, subject:, after:YYYY/MM/DD, has:attachment, label:) |
maxResults | No | Default 100. Lower it (e.g. 10) for safer paging |
pageToken | No | Cursor from a previous list response |
labelIds | No | Restrict to messages carrying all of these label IDs |
includeSpamTrash | No | Default false |
messages — get
Fetch a single message. Pick the lightest format that satisfies your need to avoid LLM context overflow.{
"name": "messages",
"arguments": {
"action": "get",
"id": "199c8915c4753fbd",
"format": "metadata",
"metadataHeaders": ["From", "To", "Subject", "Date"]
}
}
| Parameter | Required | Description |
|---|
action | Yes | Must be get |
id | Yes | The message ID returned by messages.list |
format | No | minimal (id + threadId + labelIds), metadata (default — id + headers + snippet), full (entire MIME tree — large), raw (base64url-encoded RFC 2822 — very large) |
metadataHeaders | No | When format: metadata, list of header names to include (default returns all) |
messages — send
Send a message. The Gmail API requires the message as a base64url-encoded RFC 2822 string. Build the MIME body upstream and pass it as raw.{
"name": "messages",
"arguments": {
"action": "send",
"raw": "RnJvbTogbWVAZXhhbXBsZS5jb20KVG86IGFsaWNlQGV4YW1wbGUuY29tCi4uLg=="
}
}
| Parameter | Required | Description |
|---|
action | Yes | Must be send |
raw | Yes | RFC 2822 message body, base64url-encoded |
threadId | No | Send as a reply in an existing thread |
labelIds | No | Apply these labels to the sent message |
threads — get
Fetch an entire conversation thread. With format: full, multi-message threads can easily exceed 100 KB raw — the connector automatically returns a compact summary above 50 KB.{
"name": "threads",
"arguments": {
"action": "get",
"id": "1999b92e2d656257",
"format": "metadata"
}
}
| Parameter | Required | Description |
|---|
action | Yes | Must be get |
id | Yes | The thread ID returned by threads.list |
format | No | Same enum as messages.get. Default metadata |
metadataHeaders | No | When format: metadata, list of header names to include |
labels — create
{
"name": "labels",
"arguments": {
"action": "create",
"name": "Project/Acme",
"labelListVisibility": "labelShow",
"messageListVisibility": "show",
"color": {
"backgroundColor": "#16a766",
"textColor": "#ffffff"
}
}
}
labelListVisibility ∈ labelShow / labelShowIfUnread / labelHide. messageListVisibility ∈ show / hide. Slash-separated names create a nested label.drafts — create
{
"name": "drafts",
"arguments": {
"action": "create",
"message": {
"raw": "RnJvbTogbWVAZXhhbXBsZS5jb20KVG86IGFsaWNlQGV4YW1wbGUuY29tLi4u"
}
}
}
The message argument is a Gmail message resource — at minimum a raw base64url-encoded RFC 2822 body. A draft is not sent until you call drafts.send with its id.filters — create
{
"name": "filters",
"arguments": {
"action": "create",
"criteria": {
"from": "newsletter@example.com"
},
"filterAction": {
"addLabelIds": ["Label_1"],
"removeLabelIds": ["INBOX"]
}
}
}
filterAction is the Gmail API’s action body object. It is renamed in the MCP tool to avoid colliding with the entity-level action selector — the connector maps it back to action server-side.settings — updateVacation
{
"name": "settings",
"arguments": {
"action": "updateVacation",
"enableAutoReply": true,
"responseSubject": "I am out of office",
"responseBodyHtml": "<p>I am away until April 15.</p>",
"restrictToContacts": false,
"startTime": "1739923200000",
"endTime": "1741132800000"
}
}
startTime / endTime are millisecond timestamps as strings (Gmail’s API quirk). Omit them for an indefinite vacation responder.