gmail
The user's Gmail mailbox — READ it, or prepare a DRAFT. Nothing here sends,
archives or deletes: that is gmail_act, the tool your client asks you to confirm.
op:
"search" (default): search with Gmail query syntax.
querye.g.from:foo@bar.com is:unread newer_than:7d. Returns {messages: [{id, threadId, from, subject, date, snippet, labelIds}], count}."get": a full message (headers, body, attachment metadata) by
message_id."attachment": the CONTENT of an attachment of
message_id, byfilename(from op="get";indexbreaks a tie between same-named ones). Small text (JSON/CSV/Markdown/ plain, ≤256 KB) comes back inline as{encoding: "text", content}; a PDF as its extracted text plusraw_url, a short-lived signed URL to the original (a scanned or protected PDF has no text:text_unavailablesays why); an .xlsx as CSV per sheet (sheet,max_rows— default 200, max 5000; iftruncated, ask one sheet or raisemax_rows;raw_urlalways gives the original file). An image (png/jpeg/gif/webp, ≤3 MB) and a scanned PDF whose pages are JPEG (≤5 pages, ≤3 MB) come back as IMAGE CONTENT you can look at — nothing stored. Anything else, or over those caps, as a short-lived signed URL{encoding: "url", url, expires_in}(image_unavailablesays why an image or scan was not served as image)."drafts": the drafts. Returns {drafts: [{id, message_id, to, subject, date, snippet}], count} — a draft
idis whatgmail_act(op="send", draft_id=…)sends."draft": WRITE A DRAFT — a new message (
to,subject,body) or a threaded reply (reply_to). It does NOT leave the mailbox. Returnskind: "draft", itsidandweb_link(the draft opened in Gmail web, to note where it waits): send it withgmail_act(op="send", draft_id=<id>)once the person agrees. ⚠️ A fresh draft can be MISSING from an already-open Gmail tab for a while (the API has it, the client view lags): tell the person to reload or searchin:drafts."accounts": the Gmail accounts this call can use — the user's own, then the mailboxes an admin shared with their team or organization. Returns {accounts: [{email, is_default, shared}]}; pass an
emailas_accountto act on that mailbox. An unknown email is refused, never replaced.
The sending account's Gmail signature is appended by default, after -- (none added when
the signature already opens with its own), like the Gmail web client does (the API never adds it on its own) — so do NOT write a sign-off block of
your own in body. signature in the answer says what happened: "appended",
"none_configured" (the account has no signature — nothing was added), or "disabled"
(sign=False).
Tool call template
This tool declares no required parameters. Add optional parameters from the input schema as needed.
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"arguments": {},
"name": "gmail"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | carbon-copy recipient(s), comma-separated. | |
| op | No | search (default) | get | attachment | drafts | draft | accounts. | search |
| to | No | recipient(s), comma-separated. REQUIRED for a new message (omit when replying). | |
| bcc | No | blind-copy recipient(s), comma-separated — a new message only. | |
| _org | No | Org (id) de CET APPEL. `oto_list_orgs()`. | |
| body | No | the message, rendered from markdown to HTML by default. | |
| html | No | explicit HTML body (bypasses markdown rendering). | |
| sign | No | append the account's Gmail signature (default True); False writes the body alone. | |
| index | No | op="attachment" — 0-based tiebreaker between same-named attachments. | |
| query | No | op="search" — Gmail search query. | |
| sheet | No | op="attachment" of an .xlsx — sheet name or 0-based index. | |
| _group | No | Équipe (id) de CET APPEL, sous son org parente. | |
| _run_id | No | OBLIGATOIRE à chaque appel dès `run_start` ou `data_claim_next` : sans lui, l'écriture sur une ligne réservée est refusée. Hérité seulement si le serveur tient un run actif — n'y compte pas. | |
| account | No | email of the Google account to use — same choice as `_account`. | |
| subject | No | subject line (new message only; a reply keeps the thread's subject). | |
| _account | No | Compte à OPÉRER quand plusieurs existent. `oto_identity(op='list')`. | |
| _project | No | Projet (id) de CET APPEL — jeton PRIMAIRE. `oto_project(op='list')`. | |
| filename | No | op="attachment" — name of the attachment (e.g. "Contrat.pdf"). | |
| markdown | No | render `body` from markdown when `html` is absent (default True). | |
| max_rows | No | op="attachment" of an .xlsx — rows per sheet (default 200, max 5000). | |
| reply_to | No | id of the message to reply to. When set, this is a threaded REPLY (subject/thread preserved) and `to`/`subject` are ignored. | |
| _instance | No | Instance de connecteur PRÉCISE (un credential exact). `oto_instance(op='list')`. | |
| from_name | No | optional display name for the From header. | |
| message_id | No | op="get"/"attachment" — the message id (from op="search"). | |
| attachments | No | files to attach, as `source` refs oto resolves server-side (the agent has no local disk). Each item — `kind` selects the origin: - Drive: `{"kind":"drive","file_id":"<id>"}` (id from drive_list/metadata) - Gmail: `{"kind":"gmail","message_id":"<id>","filename":"<name>"}` - URL: `{"kind":"url","url":"https://…"}` — e.g. a signed URL from `oto_upload_url` (upload a local PDF first) or drive_download. Named by the server's `Content-Disposition`, else the path; `"filename"` forces the name (its extension types the file). - Project file: `{"kind":"project_file","project_id":<id>,"file_id":<id>}` (ids from oto_project_files op=list) | |
| max_results | No | op="search"/"drafts" — max items to return (default 20). |