Gmail channel plugin for OpenClaw. Supports two backends:
- API (recommended) — connects directly via the Gmail API using OAuth2. No external CLI needed.
- gog — shells out to the gog CLI. The original backend, still fully supported.
Both backends coexist — you can run different accounts on different backends.
openclaw plugins install @mcinteerj/openclaw-gmailOr from a local clone:
openclaw plugins install --link /path/to/openclaw-gmailRequires openclaw >= 2026.1.0.
The API backend connects directly to Gmail — no gog CLI required.
If you have gog installed, the onboarding flow will detect your existing OAuth client credentials from ~/.config/gogcli/credentials.json and reuse them. You only need a one-time browser authorization to get a new refresh token.
If you don't have gog, you'll need to create a GCP OAuth client:
- Go to Google Cloud Console → Credentials
- Create a project (or use an existing one)
- Enable the Gmail API
- Create an OAuth 2.0 Client ID (type: Desktop app)
- Copy the Client ID and Client Secret
Then run openclaw configure, select Gmail, and follow the prompts. The flow will:
- Ask for your email address
- Prompt for client credentials (or reuse gog's)
- Open a browser for OAuth consent
- Store the refresh token in your OpenClaw config
- Set
backend: "api"on the account
Manual config (if you prefer to skip the wizard):
{
"channels": {
"openclaw-gmail": {
"accounts": {
"you@gmail.com": {
"email": "you@gmail.com",
"backend": "api",
"oauth": {
"clientId": "your-client-id.apps.googleusercontent.com",
"clientSecret": "your-client-secret",
"refreshToken": "your-refresh-token"
},
"allowFrom": ["*"],
"pollIntervalMs": 60000
}
}
}
}
}Install the gog CLI (v1.2.0+), authorize it (gog auth add you@gmail.com), then run openclaw configure. The account will use gog by default (no backend field needed).
Existing gog users upgrading the plugin will continue working with no changes — gog remains the default. To migrate an account to the API backend:
- Run
openclaw configure→ select Gmail - The wizard detects your gog credentials and offers migration
- Authorize in the browser (one-time, ~10 seconds)
- Done — your account now uses the API directly
Your gog installation is not affected and other accounts can continue using it.
- Polling-based sync: Fetches new unread emails from Inbox
- Rich text: Markdown responses are converted to HTML emails via
marked - Threading: Native Gmail thread support with quoted reply context
- Reply All: Replies include all thread participants
- Archiving: Automatically archives threads upon reply
- Email body sanitization: Cleans incoming HTML for LLM consumption
- Circuit breaker (gog backend): Handles API failures and rate limiting
- MIME construction (API backend): Builds RFC 2822 messages with proper threading headers
{
"channels": {
"openclaw-gmail": {
"accounts": {
"you@gmail.com": {
"email": "you@gmail.com",
"allowFrom": ["*"],
"pollIntervalMs": 60000,
"includeQuotedReplies": true, // default: true
"includeThreadContext": false, // default: false
"allowOutboundTo": ["@company.com"], // optional
"threadReplyPolicy": "allowlist" // default: "open"
}
},
"defaults": {
"includeQuotedReplies": true,
"includeThreadContext": false
}
}
}
}| Key | Type | Default | Description |
|---|---|---|---|
backend |
"api" | "gog" |
"gog" |
Which backend to use for this account |
oauth |
object | — | OAuth credentials (required for API backend) |
allowFrom |
string[] | [] |
Sender allowlist. ["*"] allows all. |
pollIntervalMs |
number | 60000 |
Polling interval in milliseconds |
includeQuotedReplies |
boolean | true |
Include thread history as quoted text in replies |
includeThreadContext |
boolean | false |
When an allowed sender replies in a thread containing messages from non-allowed senders, include those earlier messages as context. See Thread Context. |
allowOutboundTo |
string[] | (falls back to allowFrom) |
Restrict who the bot can send to. Supports domain wildcards (@company.com). |
threadReplyPolicy |
"open" | "allowlist" | "sender-only" |
"open" |
Controls reply restrictions |
open(default): No outbound restrictions. Backwards compatible.allowlist: All thread participants must be inallowOutboundTo.sender-only: Only checks if the original thread sender is allowed.
When includeThreadContext is enabled, the plugin enriches inbound messages with prior thread history that the agent wouldn't otherwise see.
The problem: If someone not on the allow list emails the agent, their message is quarantined (never seen). If an allowed sender then replies to that thread asking the agent to review it, the agent only sees the allowed sender's new message — the quoted content from the non-allowed sender is stripped during sanitization.
The solution: With includeThreadContext: true, when an allowed sender's message arrives in a thread that contains earlier messages from non-allowed senders, those earlier messages are included as labelled context above the new message:
---
**Thread context** (1 earlier message from senders not on your allow list):
**From:** Hamish Smith <hamish@example.com>
**Date:** Mon, 24 Feb 2026 10:30:00 +1300
Hey Keith, can you book transfers for our Fiji trip?
---
[Thread Context: ID=abc123, Subject="Book Your Fast Fiji Transfers"]
Keith, can you please review Hamish's request below and action it?
This is disabled by default to preserve the existing allow list behavior where non-allowed senders' content is never shown. Enable it per-account or in defaults when you want allowed senders to be able to surface thread context from outside the allow list.
npx vitest runCreate a GitHub release or run the "Publish to npm" workflow via Actions.