Skip to content

gmail MCP server

The gmail MCP server lets agents read and send email from the user’s Gmail account. It’s injected only when the user has granted a Gmail integration to the running profile (see Integrations & scope).

The server holds the refresh token server-side and mints fresh access tokens (cached for ~1h, auto-rotated on expiry) — agents never see the raw OAuth credentials.

Gmail search syntax. Returns message summaries with IDs.

{ "query": "from:alice subject:meeting is:unread", "max_results": 10 }

Max 50 results per call. The result includes message_id, thread_id, sender, subject, date, snippet.

Full message content by ID.

{ "message_id": "1942abc…" }

Returns subject, from, to, date, body. HTML bodies are stripped to plain text. Body is truncated at 4000 chars (with a “truncated” marker).

Full thread (all messages in chronological order).

{ "thread_id": "1942def…" }

User’s Gmail labels (folders).

{}

Send a new email or reply.

{
"to": "alice@example.com",
"subject": "Re: meeting",
"body": "Sounds good. Tuesday 2pm works.",
"cc": "bob@example.com",
"bcc": "",
"thread_id": "1942def…", // optional: makes this a reply in a thread
"in_reply_to": "msg-id-header" // optional: standard email headers
}

For non-ASCII subjects the server adds RFC 2047 encoding automatically.

Same shape as gmail_send_message, just saves to Drafts without sending.

Authorization: Bearer gmail_<token>. The bearer carries { userId }. The server looks up the user’s Gmail integration, decrypts the refresh token, exchanges for an access token (cached), and proxies to Gmail’s API.

When a user connects Gmail, the platform requests:

  • gmail.readonly — search + read
  • gmail.send — send
  • gmail.compose — draft creation
  • userinfo.email — profile lookup for the integration row

Connection flow: dashboard Settings → Integrations → “Connect Gmail” → Google’s consent screen → /api/gmail/callback.

Scoping the Gmail integration to specific profiles means agents on other profiles literally don’t see gmail_* tools when they call tools/list. There’s no “is this profile allowed” runtime check inside the MCP server — the orchestrator gates injection upstream.