Gmail
Twin of the Gmail API v1 and hosted Gmail MCP.
Twin of the Gmail API v1 and hosted Gmail MCP.
| Covers | gmail.googleapis.com, gmailmcp.googleapis.com |
| Auth | Google OAuth access tokens |
| Webhooks | No |
| MCP tools | 23 |
| Operations | 91 |
Coverage
Messages, threads, drafts, labels and attachments, incremental change sync
through users.history, the settings surface including filters, forwarding and
send-as, and the media upload host on the same origin. The hosted MCP server
answers on /mcp/v1 and shares the same mailbox state as the REST API.
Credentials
This twin issues no tokens of its own. It verifies the ones
Google Identity mints, so any well-formed ya29.…
token from there authenticates by default and your existing credentials need no
change. The auth.mode switch that restricts it to credentials the world knows
lives on Google Identity rather than here. See
Credentials.
The same Google access token authenticates the REST and hosted MCP surfaces.
Gmail’s scopes are enforced and they are narrow. A readonly token cannot insert, a permanent delete needs the full mail scope, and the metadata scope serves metadata but refuses message content and search. Settings scopes are not interchangeable with each other.
Vendor specific details
- A query that matches nothing returns
{"resultSizeEstimate": 0}with nomessageskey at all. Code that doesfor m in body["messages"]raises here, exactly as it does in production. - An unknown value in
labelIdsis a400 Invalid label, not an empty result.labelIdsis a repeated parameter, so a comma-joined pair counts as one bad name. users.watchstores the registration and answers normally, but nothing is ever delivered. Real Gmail publishes changes to Cloud Pub/Sub rather than posting to a URL, so there is no callback to wait for.- A
startHistoryIdthat is too old is a plain404with nofullSyncRequiredhint. You have to treat the 404 itself as the signal to resync. - An attachment token resolves against its own message, so the message id in
the path is ignored entirely. A token that does not decode is a
400, and a token whose message was deleted is a403even thoughmessages.geton the same id is a404.
Its own notes
Once a sandbox is running, this twin serves its own operating notes at
{control_url}/veris/manual: the credentials it accepts, the API versions it
serves, and the fault statuses you can arm against it. They are generated from
the same source as its behaviour, so they cannot drift.