Google Workspace MCP — Gmail edition
Provides full Gmail access across multiple Google accounts, enabling search, read, triage, thread and attachment retrieval, label/filter/draft management, message and thread organization (archive, spam, trash, read state), and sending, replying, forwarding, or sending reviewed drafts.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Google Workspace MCP — Gmail editionshow me unread emails from all my accounts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Google Workspace MCP — Gmail edition
An MCP server that gives Claude Code full Gmail access across several Google accounts at once: the same things the claude.ai Gmail connector can do, plus one mailbox view over all of your accounts.
It runs locally on macOS, as a deployed copy that Claude Code starts for every session. It is a personal project and is not published to npm or the MCP registry.
What it can do
Five tools, when started with GWS_SERVICES=gmail:
Tool | Operations |
| Read: |
Organize a message: | |
Organize a whole thread: | |
Many at once: | |
Labels: | |
Drafts (never sent from here): | |
Filters: | |
|
|
| Add, re-authorize, check and remove accounts |
| The local folder attachments are read from and saved to |
| Several calls in one, or one change across many messages |
"Archive" always means Gmail's archive: out of the inbox, still in All Mail.
Several mailboxes as one
manage_email { "operation": "triage", "email": "all" } # every account, each under its own heading
manage_email { "operation": "search", "email": "all", "query": "from:bank newer_than:7d" }
manage_email { "operation": "labels" } # no email: GWS_DEFAULT_ACCOUNT
manage_accounts { "operation": "authenticate", "email": "you@example.com" } # re-authorize one account"all" works on list operations only. Anything that changes mail names its account, and
send_email always names its sender: it never falls back to the default.
Related MCP server: Gmail MCP
Setup (macOS)
Google Cloud OAuth client: create a project, enable only the Gmail API, configure the consent screen (use Internal if all accounts are in one Google Workspace, so tokens never expire for being in testing), and create an OAuth client of type Desktop app.
Store the client in the Keychain (each command prompts for the value):
security add-generic-password -s google-workspace-mcp-oauth -a client_id -w security add-generic-password -s google-workspace-mcp-oauth -a client_secret -wDeploy and register:
scripts/local/deploy.sh claude mcp add google-workspace --scope user \ -e GWS_SERVICES=gmail \ -e GWS_DEFAULT_ACCOUNT=you@example.com \ -e GWS_SAFETY_POLICY=no-delete,audit \ -- ~/.local/lib/google-workspace-mcp/current/scripts/local/start-mcp.shAdd each account in a new Claude Code session:
manage_accounts {operation: "authenticate", email: "you@example.com"}. Only the Gmail scopes are requested (gmail.modify,gmail.settings.basic).
After a code change: commit, run scripts/local/deploy.sh, start a new session. Details in
scripts/local/README.md.
Configuration
Variable | Effect |
| Services to load, e.g. |
| Account a call acts as when |
| Opt-in policies, comma-separated: |
Safety
Mail cannot be deleted permanently. The scopes held don't allow it;
trashis the furthest it goes (Gmail empties Trash after 30 days).Filters never forward mail (
no-auto-forward, always on): a forwarding filter would send every future match with nobody asking for any of them.One way out. Only
send_emailsends; drafts inmanage_emailnever do.no-deleteblocks permanent deletes in other services; Gmail drafts are exempt, as in the Gmail connector.auditlogs every write with content redacted (who, what, to whom — not the text).Per-account access: an account authorized read-only is refused writes before the request leaves.
Optional gates:
draft-only-emailstops all sending; addingrequires_user_interaction: truetosrc/factory/manifest/gmail-send.yamlmakes Claude Code ask before every send, in every permission mode.Email content is data, not instructions. Say so in your
CLAUDE.md: a message asking Claude to forward, reply or change settings should never be acted on unasked.
Where your data lives
What | Where |
OAuth client id and secret | macOS Keychain, service |
Per-account refresh tokens |
|
Account list |
|
Attachments workspace |
|
Logs |
|
Running copy |
|
Requests go only to Google's APIs. Nothing is sent anywhere else.
Development
npm ci
make check # type-check, lint, tests, build, smoke testsOn macOS, run tests with a non-symlinked temp dir (TMPDIR="$(cd "$TMPDIR" && pwd -P)/" make check):
a few workspace tests otherwise trip over /var → /private/var.
The code still contains the upstream Calendar, Drive, Docs, Sheets, Tasks, Meet and Contacts
services. GWS_SERVICES leaves them out; they are not exercised in this project.
Origin and license
This project started as a fork of aaronsb/google-workspace-mcp v4.8.0 by Aaron Bockelie and contributors, and is now maintained independently. It is not affiliated with or endorsed by the original author.
Main changes from upstream:
Sending split into its own
send_emailtool, withsendDraft; drafts, archive, read state, spam and labels at message and thread level inmanage_email.GWS_SERVICES,GWS_DEFAULT_ACCOUNTandemail: "all"across accounts.Gmail-only consent scopes and account pre-selection on re-authorization.
no-auto-forward, audit redaction, drafts exempt fromno-delete.archivemeans Gmail's archive (the upstream "save to a local markdown file" is removed);getThreadreturns bodies; attachments are sent instead of saved as a draft.A macOS launcher and deploy script (
scripts/local/).
Licensed under the Apache License 2.0. The upstream copyright and attribution
notices are kept in NOTICE and LICENSE-MIT. The design records in
docs/ and the RELEASE-NOTES-*.md files are upstream history, kept as written.
Available Tools
14 toolsbulk_operationsA
Do many things in one call, two ways. mode:'queue' (default) runs different operations in sequence, chaining results with $N.field — works for every tool. mode:'batch' does ONE operation across many resources in a single Google request — far fewer round trips, but only where Google publishes a batch method.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | queue (default): N operations, N API calls, in order, with $N.field references between them. batch: ONE operation across many resources in a single API call — no $N references, because there is no 'between'. | |
| tool | No | batch only — the tool to call, e.g. 'manage_contacts'. | |
| No | batch only — the account to act as. | ||
| items | No | batch only — one entry per resource. A bare id string is enough when that is all that differs, e.g. ['people/c1', 'people/c2']; use objects when items carry more, e.g. [{name: 'Ada Lovelace', contactEmail: 'ada@example.com'}]. Anything shared by the WHOLE batch — labels to add, a field mask — goes at the top level of this call, not in here. | |
| detail | No | summary: one-line status per operation (default) | full: include complete output from each operation | |
| operation | No | batch only — the operation to apply to every item, e.g. 'delete'. Ask for one that cannot batch and the error names the ones that can. | |
| operations | No | Operations to execute sequentially |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the behavioral load, and it does disclose non-obvious traits: batch issues a single upstream Google request, queue chains results via $N.field and has no equivalent 'between' step in batch, and batch availability is conditional on Google publishing a batch method. It omits failure/partial-failure semantics and ordering guarantees for batch, so it is helpful but not complete.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero filler, and the most decision-relevant fact for an agent (the two modes and their tradeoff) is front-loaded. The contrast is stated compactly rather than as a bulleted manual.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter orchestration tool with no annotations and no output schema, the mechanics are adequately covered, but two consequential gaps remain: no differentiation from the queue_operations sibling, and no explanation of return shape even though detail:summary/full governs output verbosity (the description never mentions it). Adequate, not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (mode, tool, email, items, detail, operation, operations) is already documented in the schema, including the very same mode semantics the description restates. The description adds no syntax, format, or constraint detail beyond what structured fields provide, which is the textbook baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific capability (execute many operations in one call) and names the two distinct execution strategies, with the engine difference spelled out ('runs different operations in sequence' vs 'ONE operation across many resources in a single Google request'). It never mentions the sibling queue_operations, which covers apparently overlapping ground, so the agent gets no help distinguishing these two; that omission keeps it out of 5 territory.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives real selection criteria between the two modes: queue 'works for every tool', batch is 'only where Google publishes a batch method' but yields 'far fewer round trips'. It stops short of saying when to reach for bulk_operations at all versus calling individual tools (or queue_operations) directly, so there is no explicit when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_accountsA
Manage Google Workspace account lifecycle: list, authenticate, check status, refresh credentials, update scopes, or remove accounts.
| Name | Required | Description | Default |
|---|---|---|---|
| No | Required for remove, status, refresh, scopes. For authenticate: optional — pre-selects that Google account, which is how an existing account is re-authorized. | ||
| access | No | How much this account may do. 'readwrite' (default) is full access. 'read' asks Google for read-only permissions instead, so the account can look things up but cannot send, edit or delete. Some services have no read-only option — you will be told which before the browser opens, and nothing is authorized until you confirm. | |
| category | No | For authenticate (default: personal) | |
| services | No | For scopes — comma-separated service names (e.g. gmail,drive,calendar,sheets) | |
| operation | Yes | list: show all accounts | authenticate: add new account (opens browser) | remove: delete account and credentials | status: check token validity and scopes | refresh: renew credentials | scopes: re-auth with different services | capabilities: show available services, safety policies, and workspace status | |
| description | No | For authenticate — optional label | |
| confirmWriteAccess | No | Set true to go ahead when 'read' was asked for but some services can only be granted full access. Only needed after a first call has told you which ones. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden, yet it discloses little beyond the operation list: it doesn't mention that authenticate opens a browser, that remove is destructive/irreversible, or how read vs readwrite access is negotiated. Most behavioral detail lives in the schema parameter descriptions, not the description text.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence that name-drops the verb, resource, and all supported operations with zero filler. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, multi-operation dispatcher with no annotations and no output schema, the description is on the thin side: it omits mutation/irreversibility guidance and sibling routing. The very detailed schema compensates substantially, keeping this adequate rather than deficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the parameter descriptions are unusually rich (email role per operation, access nuances, confirmWriteAccess flow), so the baseline is 3. The description adds no parameter meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb (manage) and resource (Google Workspace account lifecycle) and enumerates the concrete operations (list, authenticate, status, refresh, scopes, remove). An agent can tell it manages accounts rather than mail/calendar/drive, but it never explicitly distinguishes itself from the many manage_* siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Enumerating the six operations implies when each is used, and the schema's operation enum expands on this, but the description itself gives no explicit conditions, prerequisites, or alternative tools to prefer. Usage is inferable rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_calendarB
List events, view agenda, check availability, or manage calendar events.
| Name | Required | Description | Default |
|---|---|---|---|
| end | No | End time (ISO 8601) — or, when allDay is true, a DATE (YYYY-MM-DD) that is the INCLUSIVE last day; the exclusive end date the Calendar API requires is computed for you. Optional for all-day events: a missing end (or one equal to start) makes a one-day event. | |
| days | No | Number of days ahead to show (default: today only) | |
| meet | No | Add a Google Meet video conference link. On `update`, true adds a link and false REMOVES an existing one; omit it to leave the link as it is. | |
| text | No | Natural language event description | |
| week | No | Show this week's events | |
| Yes | Account email address. On list operations, "all" runs it once for every configured account. | ||
| query | No | Free-text search terms to filter events | |
| start | No | Start time (ISO 8601) — or a DATE (YYYY-MM-DD) when allDay is true | |
| allDay | No | Whether the event is all-day. When true, start and end are DATES (YYYY-MM-DD — an ISO datetime's date part is used) and end, if given, is the INCLUSIVE last day; the exclusive end date the Calendar API requires is computed for you. Omit it (or pass false) for a timed event with start/end as dateTime — pass false with new datetimes to convert an all-day event back to a timed one. On `update`, converting TO all-day needs only one of start/end; the other is derived from the event on record. Converting FROM all-day needs both, because the missing one would need a time of day only you can choose. | |
| eventId | No | Event ID | |
| summary | No | Event title | |
| timeMax | No | End of range (ISO 8601) | |
| timeMin | No | Start of range (ISO 8601). On `list`, defaults to today. | |
| location | No | Event location | |
| tomorrow | No | Show tomorrow's events instead of today | |
| attendees | No | Comma-separated email addresses. On `update`, whatever you pass REPLACES the existing list — addresses you leave out are removed, and an empty string clears everyone. OMIT the parameter to leave the attendee list untouched while changing other fields. On `freebusy`, the addresses whose availability to check. | |
| operation | Yes | list: upcoming events — defaults to primary calendar, use calendarId to target a specific calendar (use 'calendars' operation to discover IDs) | agenda: today's schedule at a glance (all calendars). Returns calendarId per event for follow-up get calls. | get: full event details by ID. For shared calendar events, calendarId is required (use agenda or list to discover it). | create: create a new calendar event | quickAdd: create event from natural language (e.g. 'Lunch with Alice tomorrow at noon') | update: update an existing event (patch semantics — only changed fields needed) | delete: delete an event | calendars: list all calendars the user has access to | freebusy: check availability (free/busy) for a time range. Automatically includes own calendar; add attendees to check others. | |
| calendarId | No | Calendar ID. Use the `calendars` operation to list available IDs; required for events on shared calendars. Defaults to 'primary' on the event operations (`list`, `get`, `create`, `quickAdd`, `update`, `delete`). On `agenda`, a calendar name or ID to filter to — OMIT it to span all calendars, and do not pass 'primary', which is an API alias rather than an id agenda matches on. On `freebusy`, a comma-separated list of calendar IDs to check IN ADDITION to your own. | |
| maxResults | No | Max events (default: 10, max: 50) | |
| description | No | Event description or notes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the entire behavioral burden, and it discloses almost nothing: no mention of destructive delete/update semantics, no permission or auth requirements, no return format, no rate limits. The only genuinely useful behavioral notes (patch semantics, attendee replacement, all-day conversion) exist in the schema descriptions, not here.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The single sentence is front-loaded and waste-free, but for a tool with nine operations and twenty parameters it is under-specified rather than genuinely concise. Brevity here is achieved by omission, not by efficient structuring.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema is exceptionally self-documenting (100% coverage, operation enum enumerating semantics), which compensates for much of the description's silence, and there is no output schema to explain. Still, a nine-operation tool with no annotations and no destructive-operation warnings leaves the agent relying entirely on schema text for routing and safety.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with detailed per-parameter and per-operation documentation in the schema, so the baseline is 3. The description adds no parameter-level meaning whatsoever beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names concrete verbs (list events, view agenda, check availability) plus a catch-all ('manage calendar events') against the calendar resource, so an agent can tell this is the multiplexed calendar tool. It is clear but does not differentiate from siblings like manage_meet, manage_contacts, or manage_tasks, and it never signals that this one tool actually spans nine distinct operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The four phrases imply usage modes (viewing vs. managing), which roughly maps to the read/write split in the operation enum. However, the description itself gives no when-to-use guidance, no alternatives, and no routing between operations or siblings — the rich per-operation guidance lives entirely in the schema's operation enum, not in the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_contactsB
Search, read, create, update and delete Google Contacts: your saved contacts, the addresses you have corresponded with but never saved, and your organization's directory.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Full name, e.g. `Ada Lovelace`. Split into given and family name on the way in; a single word becomes the given name. | |
| Yes | Account email address. On list operations, "all" runs it once for every configured account. | ||
| notes | No | Free-text note stored on the contact | |
| phone | No | Phone number, in whatever form you have it — Google normalizes it. On `update` this REPLACES every number the contact has — pass an empty string to clear them. | |
| query | No | Text to match against names, email addresses, nicknames and phone numbers. Matching is by PREFIX: `ann` finds Anna, `nna` finds nobody. | |
| company | No | Organization name | |
| jobTitle | No | Job title within the organization | |
| contactId | No | Person id as `list` or `search` printed it (e.g. `people/c1234567890`). A bare id without the `people/` prefix is accepted. | |
| operation | Yes | list: list your saved contacts | search: search your saved contacts by name, email, nickname or phone | get: get one person in full — addresses, birthday, notes, relations | create: create a new contact | update: change an existing contact (only the fields you pass; pass an empty string to clear one) | delete: delete a contact | listOther: list 'other contacts' — addresses you have corresponded with but never saved | searchOther: search 'other contacts' by name or email | listDirectory: list people in your organization's directory (Workspace accounts only) | searchDirectory: search your organization's directory by name or email (Workspace accounts only) | |
| pageToken | No | Continue from where a previous page stopped — pass the token that response printed | |
| sortOrder | No | Order for `list` — by first name, by last name, or most recently changed first | |
| maxResults | No | Max people to return (default 25). Capped per operation: 30 for `search` and `searchOther`, 100 for everything else. | |
| contactEmail | No | The contact's email address. (`email` is the account making the call, not the person being saved.) On `update` this REPLACES every address the contact has — pass an empty string to clear them. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it is a single sentence that discloses almost nothing beyond the surface: no mention that delete is irreversible, that update overwrites fields, that directory access requires a Workspace account, or any pagination/rate-limit behavior. The rich destructive semantics (e.g. phone/contactEmail REPLACING all values) live only in the schema, not the description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with no filler, and the verb set and resource come first. It is efficient, though for a 10-operation, 13-parameter tool the brevity borders on under-specification rather than true conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity tool — 10 operations, 13 parameters, no annotations, no output schema — the description is not complete enough. It omits the destructive nature of delete, the overwrite semantics of update, account scoping for the email parameter, and the Workspace-only gating of directory operations, leaving the agent to reconstruct behavior from the schema alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 13 parameters with unusual thoroughness — including prefix-matching semantics for query, the people/ id format, and the replace-vs-clear behavior of phone and contactEmail. The description adds no parameter meaning of its own, which is the correct baseline when the schema does all the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (Google Contacts) and enumerates the verb set (search, read, create, update, delete), which cleanly separates it from siblings like manage_calendar or manage_email. It also partitions the resource into three domains — saved contacts, 'other' contacts, and the org directory — that map onto the operation enum. It stops short of naming the individual operations, but the resource is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied through the three-domain breakdown (saved vs corresponded-but-unsaved vs directory), which is the actual routing decision between list/search, listOther/searchOther, and listDirectory/searchDirectory. However, the description never states when to prefer this tool over siblings (e.g. contacts lookups while composing email via manage_email), and gives no prerequisites such as the Workspace-only restriction on directory operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_docsB
Read, write, insert, and find-replace text in Google Docs documents.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Text to write (plain text) — appended to the end by write, inserted at `index` by insertText | |
| Yes | Account email address. On list operations, "all" runs it once for every configured account. | ||
| index | No | Character index to insert at (1 = start of the tab's body) | |
| tabId | No | Tab to act on — a tabId from a previous get's tabIndex. Scopes the read on get; targets the edit on write/insertText/replaceText, which act on the FIRST tab when it is omitted (replaceText spans every tab). Character indices are per-tab. | |
| title | No | Document title (default: 'Untitled document') | |
| findText | No | Text to find | |
| matchCase | No | Case-sensitive match (default: true) | |
| operation | Yes | get: get document content and metadata | create: create a new document | write: append text to the end of a document | insertText: insert text at a specific position in a document | replaceText: find and replace text in a document | |
| documentId | No | Document ID | |
| replaceWith | No | Replacement text |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. The verbs 'write', 'insert', and 'replace' imply mutation, but the description does not disclose destructive potential, permission requirements, tab-scoping behavior, or what gets overwritten. The schema descriptions add some behavioral detail, but the description itself adds none.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler or redundancy. It is appropriately sized for a high-level tool summary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter, multi-operation tool with no output schema, the one-sentence description is thin and omits the 'create' operation entirely. The rich schema prevents total ambiguity, but the description does not fully convey the tool's scope or behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 10 parameters and the operation enum. The description adds only a high-level restatement of operations and does not clarify index semantics, tabId scoping, matchCase defaults, or other parameter-level behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs (read, write, insert, find-replace) and names the resource (Google Docs documents), which distinguishes it from siblings like manage_sheets and manage_drive. However, it omits the 'create' operation that the schema lists, so the full scope is not stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit when-to-use guidance, no when-not-to-use, and no named alternatives. The description does not tell an agent when to choose this tool over manage_drive for document files or when a different operation is preferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_driveC
Search, upload, download, share, comment on, or manage files in Google Drive.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | File name in Drive. On `upload`, defaults to the local file's name. On `copy`, the name for the copy — without it Drive names it 'Copy of <original>'. On `update`, the new name (a rename). On `createFolder`, the folder name. | |
| role | No | Permission level. On `share`, the level to grant — defaults to `reader`. On `setRole`, the new level, and it is REQUIRED there: with no default to fall back on, an omitted role would silently demote the collaborator, and setRole sends no notification. | |
| type | No | Permission type (default: 'user'). Use 'group' for Google Groups, 'domain' to share with an entire G Suite domain, 'anyone' for public links. | |
| Yes | Account email address. On list operations, "all" runs it once for every configured account. | ||
| query | No | Drive search query (e.g. "name contains 'budget'" or "mimeType='application/pdf'") | |
| domain | No | Domain name (required when type is 'domain'). | |
| fileId | No | File ID | |
| content | No | Comment text. On `replyToComment`, the reply text. | |
| filePath | No | Local file path to upload | |
| folderId | No | Folder ID (pass the id returned by createFolder or search) | |
| maxDepth | No | How many folder levels to descend (default 10). The tree is labelled partial when this limit stops the walk. | |
| mimeType | No | Target format (e.g. application/pdf, text/csv, text/plain, application/vnd.openxmlformats-officedocument.wordprocessingml.document) | |
| resolved | No | true to resolve, false to reopen | |
| commentId | No | Comment ID | |
| operation | Yes | search: find files by query | get: get file metadata | upload: upload a local file to Drive | viewImage: view an image file inline without saving to workspace (png, jpg, gif, webp). Use for quick preview — use download to save. | download: download file content to local path | copy: create a copy of a file (set name to rename the copy; parentFolderId to place it in a folder) | update: rename a file (set name) and/or move it between folders (addParents / removeParents — to move, set both) | delete: permanently delete a file (cannot be undone) | trash: move a file or folder to trash (recoverable for 30 days — use instead of delete when you only need to remove it) | export: export a Google Workspace document (Docs, Sheets, Slides) to a file format | createFolder: create a new folder (optionally nested under a parent folder) | listFolder: list the files and subfolders directly inside a folder | tree: print a recursive folder tree and count the files (subfolders excluded from the count) | listPermissions: list sharing permissions on a file | share: share a file with a user, group, domain, or anyone | unshare: remove sharing permission from a file | setRole: change an existing collaborator's role (no notification email is sent) | listComments: list comments on a file | getComment: get a specific comment by ID | addComment: add a comment to a file (optionally anchored to quoted text) | resolveComment: resolve or reopen a comment | replyToComment: reply to an existing comment | |
| addParents | No | Comma-separated folder ID(s) to add as parents (move into a folder) | |
| maxResults | No | Max results (default: 10, max: 50) | |
| outputPath | No | Local path to save the file | |
| quotedText | No | Text to anchor the comment to (optional — if provided, comment is anchored to first occurrence) | |
| shareEmail | No | Email address of the collaborator. On `share`, required when type is 'user' or 'group'; omit for 'domain' (use the `domain` param) or 'anyone'. On `setRole`, the existing collaborator whose role to change. | |
| permissionId | No | Permission ID to remove (from listPermissions) | |
| removeParents | No | Comma-separated folder ID(s) to remove as parents (move out of a folder) | |
| includeDeleted | No | Include deleted comments (default: false) | |
| parentFolderId | No | Destination folder ID. On `upload`, places the file in this folder. On `copy`, defaults to the source file's folder. On `createFolder`, nests the new folder under this parent. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the full behavioral burden and delivers essentially none — no mention of auth requirements, quota limits, notification behavior, or which operations are destructive/irreversible. Only an implicit hint that write actions (upload, share) exist.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with no redundancy or wasted clauses. It is efficient, though its brevity for a 22-operation tool borders on under-specification rather than pure conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 24-parameter mega-tool dispatching 22 operations with no annotations and no output schema, one generic sentence is far too thin. It never tells the agent that this is an operation-dispatch tool or that the operation enum is where the real contract lies.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (including the richly documented operation enum) is already explained in the schema. The description adds no parameter meaning beyond that, making baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the resource (Google Drive files) and lists concrete verbs (search, upload, download, share, comment), so the domain is clear. It fails to distinguish this dispatcher from adjacent siblings like manage_docs, manage_sheets, or manage_workspace, and the trailing 'or manage files' is filler.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no when-to-use, when-not-to-use, or alternative-selection guidance at the description level. The operation-level routing lives entirely in the schema enum, so the description itself provides no decision support.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_emailA
Search, read, triage, label, archive, trash, report spam, and manage drafts, labels and filters in a Google Workspace account. Supports Gmail search syntax. This tool sends nothing: sending, replying and forwarding are send_email.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | CC email(s), comma-separated | |
| to | No | Recipient email(s), comma-separated | |
| bcc | No | BCC email(s), comma-separated | |
| body | No | Email body text | |
| from | No | Sender email or RFC 2822 mailbox for a verified Gmail Send As alias | |
| html | No | Treat body as HTML content (default: plain text) | |
| name | No | Label name, e.g. 'REC/Receipt'. Nested labels use a slash; create the parent first if Gmail shows nesting. | |
| Yes | Account email address. On list operations, "all" runs it once for every configured account. | ||
| query | No | Gmail search query (e.g. "from:alice subject:meeting has:attachment") | |
| format | No | For getThread: full (default) includes each message's body; metadata is From, To, Subject and Date only | |
| draftId | No | Draft id as returned by listDrafts (an r… id, not the message id) | |
| idsOnly | No | On `search`: return only message ids, up to 500 per page, without fetching each message's headers. For counting a large result or collecting ids to pass to bulk_operations batch mode (e.g. modify). | |
| labelId | No | Label ID (from `labels`), e.g. Label_123 — not the label name | |
| matchTo | No | Filter criterion: recipient, e.g. a list or alias address | |
| subject | No | Email subject line | |
| filename | No | Attachment filename, exactly as it appears in the `read` response (e.g. 'invoice_template.md') | |
| filterId | No | Filter id, as listed by `filters`. On previewFilter, the filter a change would replace; leave it out to preview a new filter. | |
| replyAll | No | For a reply draft: include everyone on the thread, as reply-all does (default: reply to the sender) | |
| threadId | No | Thread ID to retrieve | |
| matchFrom | No | Filter criterion: sender, e.g. billing@vendor.com or @vendor.com | |
| matchSize | No | Filter criterion: size in bytes; requires matchSizeComparison | |
| messageId | No | Email message ID | |
| operation | Yes | search: find emails by query. Says when more results exist than the page shows; continue with pageToken, or pass idsOnly to collect up to 500 ids per page for bulk_operations. | read: get full email by ID. Pass bodyFormat: 'html' when the plain-text part is a stub (marketing email, invitations, booking confirmations) and the dates/codes you need only exist in the HTML — returned HTML is sanitized and wrapped in a Spotlighting block (ADR-305). | archive: archive a message, as Gmail's Archive button does: it leaves the inbox but stays in All Mail with its other labels. `unarchive` puts it back. | unarchive: move an archived message back to the inbox | markRead: mark a message as read | markUnread: mark a message as unread | triage: unread inbox summary (sender, subject, date) | trash: move a message to trash | markSpam: report a message as spam: moves it out of the inbox into Spam | unmarkSpam: not spam: moves a message from Spam back to the inbox | modifyThread: add or remove labels on every message in a thread at once (e.g. a label on the whole conversation; removeLabelIds UNREAD marks it all read) | archiveThread: archive a whole conversation: every message in the thread leaves the inbox | unarchiveThread: move a whole conversation back to the inbox | markThreadSpam: report a whole conversation as spam: every message moves out of the inbox into Spam | unmarkThreadSpam: not spam: moves a whole conversation from Spam back to the inbox | trashThread: move a whole conversation (every message in the thread) to trash | untrashThread: restore a whole conversation from trash | untrash: restore a message from trash | listDrafts: list saved drafts (unsent messages) with each draft's DRAFT id (the r… id), recipient, subject and date. Use that draft id with deleteDraft — a message id from search in:drafts will not work for deletion. | createDraft: save a new draft without sending it. Give to, subject and body for a new message; give replyToMessageId instead for a reply draft in that message's thread (recipients, subject and quoting are filled in, as for a reply). Returns the draft id (r…). | getDraft: read a draft by its draft id (the r… id from listDrafts or createDraft): recipients, subject, body and attachments | updateDraft: change a draft without sending it. Only the fields you give change; recipients, subject, body and attachments you leave out are kept, and a reply draft stays in its thread. `body` replaces the whole text; `attachments` replaces all attachments. | deleteDraft: permanently delete a draft (unsent message) by its draft id (the r… id returned by listDrafts). Irreversible — the draft is discarded, not moved to trash. | getAttachment: download an email attachment to workspace directory (use read first to see attachment list) | viewAttachment: view an image attachment inline without saving to workspace (png, jpg, gif, webp). Use for quick preview — use getAttachment to save. | modify: add or remove labels on a message (e.g. archive, mark read/unread) | previewModifyMatching: evaluate a label change over everything a query matches, without making it: the exact count (up to 10,000), a sample, and what the change does to each message. Holds the matched set and returns the previewToken modifyMatching needs. No ids are returned beyond the sample. | modifyMatching: apply a previewed label change (archive, mark read, label, trash) to exactly the messages previewModifyMatching counted, and report how many changed. Requires its previewToken from an earlier call, within 30 minutes; each preview applies once. | labels: list all labels in the mailbox | createLabel: create a label. A slash in the name makes it nested (e.g. 'REC/Receipt' under 'REC'). Fails if the name already exists. Use `labels` first to check, then pass the returned label ID to `modify`. | updateLabel: rename a label or change where it shows. Only the fields you give change. Renaming 'REC' does not rename nested 'REC/…' labels. | deleteLabel: delete a label. The messages themselves stay where they are; they just lose this label. Irreversible. | filters: list the account's filters: id, criteria and what each does. Gmail allows 1,000. | getFilter: one filter's criteria and actions in words, plus the parameters that recreate or edit it | previewFilter: evaluate a filter without creating it: how many messages it matches today and a sample, what each action does, and any duplicate or overlapping filter. Returns the previewToken createFilter needs; with filterId, previews replacing that filter and returns the token updateFilter needs. Criteria are the match* params; actions are addLabelIds and removeLabelIds (filters cannot forward mail in this build). A good criterion is the query of a search that already found the mail. | createFilter: create a filter. Requires the previewToken from previewFilter called with the same parameters, in an earlier call, within 30 minutes. Acts on mail arriving from then on. | updateFilter: change a filter's criteria or actions. Gmail has no in-place update, so this creates the replacement and then deletes the original; the filter gets a new id. Requires the previewToken from previewFilter called with filterId and the same parameters. | deleteFilter: delete a filter. Returns what it was and the parameters to recreate it. | threads: list email threads by query | getThread: read a whole conversation: every message in the thread with its sender, date and body. Pass format metadata for headers only, to skim a long thread. | |
| pageToken | No | Continue a list from where the previous page stopped: pass the pageToken its response gave. Absent from a response means that response was the last page. | |
| bodyFormat | No | How to render the message body. 'plain' (default) returns text/plain or a crude HTML-strip fallback. 'html' returns the text/html part sanitized — useful when the plain-text part is empty/stub. | |
| matchQuery | No | Filter criterion: any Gmail search query the message must match, same syntax as search | |
| maxResults | No | Max results per page (default 10, max 50). On `search` with idsOnly, default and max 500. | |
| addLabelIds | No | Comma-separated label IDs to add (e.g. STARRED, IMPORTANT, Label_123). On modify, to this message; on the filter operations, to each matching message as it arrives; on the *ModifyMatching operations, to every message the preview counted. | |
| attachments | No | Workspace filenames to attach, comma-separated (files must exist in workspace via manage_workspace) | |
| matchSubject | No | Filter criterion: words in the subject | |
| previewToken | No | The token the preview returned for this exact change: previewFilter for createFilter and updateFilter, previewModifyMatching for modifyMatching. Required: the write runs only after its preview has been seen. | |
| removeLabelIds | No | Comma-separated label IDs to remove (e.g. UNREAD to mark read, INBOX to archive). On modify, from this message; on the filter operations, from each matching message as it arrives; on the *ModifyMatching operations, from every message the preview counted. | |
| replyToMessageId | No | For createDraft: make it a reply draft to this message id, in its thread | |
| matchExcludeChats | No | Filter criterion: leave chat messages out | |
| matchNegatedQuery | No | Filter criterion: a Gmail search query the message must NOT match | |
| matchHasAttachment | No | Filter criterion: only messages with an attachment | |
| labelListVisibility | No | Whether the label appears in the label list: labelShow (default), labelShowIfUnread, or labelHide | |
| matchSizeComparison | No | Filter criterion: whether matches are larger or smaller than matchSize | |
| messageListVisibility | No | Whether the label appears on messages in the message list: show (default) or hide |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It usefully says 'This tool sends nothing' and lists mutation-heavy operations like trash, spam, drafts, labels and filters, but it omits permissions, irreversibility and preview-token gating that the operation-level schema describes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the operation set, then Gmail search syntax support, then the send_email boundary. It is appropriately sized for a 39-parameter multi-operation tool without wasting words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The top-level description is appropriately high-level for a schema that exhaustively documents each operation, and it names the key sibling boundary. It does not globally flag destructive operations or preview-token requirements, but the operation descriptions cover those details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description only adds that Gmail search syntax is supported, but the query parameter already documents that syntax with an example.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific set of verbs and resources: search, read, triage, label, archive, trash, report spam, manage drafts, labels and filters. It also names the sibling send_email as the tool for sending, so an agent can distinguish Gmail management from sending without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly routes sending, replying and forwarding to send_email, which is the main sibling boundary for this tool. It does not give top-level when-to-use guidance for choosing among its many operations, though the operation enum description supplies that detail in the schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_meetB
Browse past Google Meet conferences, participants, transcripts, recordings, and AI-generated smart notes. Requires Workspace Business Standard+ for transcripts/recordings.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Account email address. On list operations, "all" runs it once for every configured account. | ||
| space | No | Meeting code (the abc-mnop-xyz part of a Meet link) or a full spaces/... resource name | |
| filter | No | EBNF filter. On `listConferences`, e.g. 'space.meeting_code = "abc-mnop-xyz"' or 'start_time>="2026-01-01T00:00:00Z"'. On `listParticipants`, e.g. 'latest_end_time IS NULL' for active participants. | |
| operation | Yes | listConferences: list recent meeting conferences (default: descending by start time) | getConference: get details of a specific conference | listParticipants: list who attended a conference | listTranscripts: list transcripts for a conference (requires Workspace Business Standard+) | getTranscript: get transcript metadata including Google Docs destination | listTranscriptEntries: get structured transcript text — who said what, with timestamps | listRecordings: list recordings for a conference (saved as MP4 in Drive) | getRecording: get recording metadata including Drive file ID and playback link | getFullTranscript: get the full who-said-what transcript for a conference (chains transcripts + entries + participant names automatically). Use pageToken to continue reading. | listSmartNotes: list Gemini-generated smart notes for a conference | getSmartNote: get smart note metadata including Google Docs destination | createSpace: create a standalone Google Meet link (not attached to a calendar event) | activeConferences: list conferences happening RIGHT NOW across your meetings | getSpace: look up a meeting space by its meeting code or resource name | updateSpace: change who can join a meeting space, or turn host controls on or off | endActiveConference: end the call happening in a space right now, disconnecting everyone in it | |
| pageToken | No | Page token from a previous getFullTranscript call to continue reading | |
| accessType | No | Who can join without knocking. OPEN: anyone with the link. TRUSTED (default): people in your organization, plus invited guests. RESTRICTED: invited guests only. | |
| maxResults | No | Max results per page, as default/ceiling. Differs by operation: `listConferences` 25/100, `listParticipants` 100/250, `listTranscriptEntries` 100/100. (Google's own default for transcript entries is 10; this tool raises it.) | |
| moderation | No | Turn on host controls — the host admits guests and manages who can present or chat. | |
| conferenceId | No | Conference record ID (from `listConferences`) | |
| recordingName | No | Recording resource name (from listRecordings) | |
| smartNoteName | No | Smart note resource name (from listSmartNotes) | |
| transcriptName | No | Transcript resource name (from `listTranscripts`, e.g. conferenceRecords/.../transcripts/...) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and mostly fails: it says 'browse past' conferences, yet the tool can create spaces and end an active call (disconnecting everyone) — a significant side effect that is never flagged. The licensing requirement is the one real disclosure; permissions, reversibility of updateSpace, and read-vs-write nature of each operation are absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with scope and then the prerequisite — no filler. It is arguably undersized for a 17-operation tool, but every sentence present earns its place and nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter tool with 17 operations, no annotations, and no output schema, the description covers only the read/inspection half of the surface. It omits the createSpace/updateSpace/endActiveConference mutations and their consequences, leaving an agent unable to anticipate the tool's write behaviors from the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, including detailed per-operation explanations, filter examples, and per-operation page-size limits, so the schema does the heavy lifting. The description adds no parameter-level meaning beyond the licensing note, making the baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource domain (Google Meet conferences, participants, transcripts, recordings, smart notes) with the verb 'browse', so an agent knows broadly what it covers. However, it frames the tool as purely read-oriented while the schema includes mutation operations such as createSpace, updateSpace, and endActiveConference, so the stated purpose is narrower than the tool's actual scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives one concrete prerequisite — transcripts/recordings require Workspace Business Standard+ — which is genuinely useful usage context. But there is no guidance on when to pick manage_meet over siblings like manage_calendar or manage_workspace, nor any exclusion conditions, so usage is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_scratchpadA
Compose, edit, and deliver text content. Use for any multi-line content: emails, documents, descriptions. Compose in the scratchpad, edit by line or JSON path, attach files, then send to any target. Mail goes out only as a Gmail draft from here; to actually send it, pass the final text to send_email. For short one-liners, use the service tool directly instead.
| Name | Required | Description | Default |
|---|---|---|---|
| keep | No | For send: keep scratchpad after successful send (default: true) | |
| path | No | For json_* ops: JSON path (e.g., $.config.name, $.items[0].value) | |
| No | For attach (drive source): account that can read the Drive file | ||
| label | No | For create: optional human-readable label | |
| refId | No | For detach: attachment reference ID (att-1, att-2, etc.) | |
| value | No | For json_set, json_insert: value to set or insert (any JSON type) | |
| fileId | No | For attach (drive source): Drive file ID. The file is downloaded into the workspace at attach time. | |
| format | No | For create: content format (default: text). Controls validation and addressing mode. | |
| source | No | For attach: file source (workspace or drive). For import: resource type (doc, email, sheet, drive_file). | |
| target | No | For send: delivery target. Mail can only be saved as a draft here (email_draft); sending is send_email. | |
| content | No | Text content. For create (pre-fill), insert_lines, append_lines, replace_lines. | |
| endLine | No | End of line range (inclusive). For replace_lines, remove_lines, copy_lines, view. | |
| filename | No | For attach (workspace source): filename in workspace | |
| afterLine | No | Insert after this line number (0 = prepend). For insert_lines, copy_lines, attach. | |
| operation | Yes | create: new buffer | view: show content | discard: free buffer | list: show all | insert_lines/append_lines/replace_lines/remove_lines: line editing | copy_lines: copy from another scratchpad | json_get/json_set/json_delete/json_insert: path-addressed JSON editing | attach/detach: file references | import: load from Google Workspace resource | send: deliver to target | |
| startLine | No | Start of line range (1-based). For replace_lines, remove_lines, copy_lines, view. | |
| scratchpadId | No | Scratchpad ID (sp-XXXX). Required for all operations except create and list. | |
| sourceParams | No | For import: source-specific parameters (e.g., { documentId, mode } for doc, { messageId } for email) | |
| targetParams | No | For send: target-specific parameters (e.g., { email, to, subject } for email_draft, { filename } for workspace) | |
| fromScratchpadId | No | For copy_lines: source scratchpad ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does disclose a critical constraint: mail can only be produced as a Gmail draft here and must be routed through send_email to actually leave. It also narrates the workflow sequence (compose -> edit -> attach -> send). It leaves some side effects uncovered (what discard/keep do to buffer lifetime beyond the enum text), so it is strong but not exhaustive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the one-line purpose, then adds the workflow and routing in tight sentences. Slightly sentence-heavy (seven clauses), but each contributes either scope, workflow, or the sibling routing rule, so there is little waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 20-parameter, 17-operation tool with no output schema, the description orients the agent well: purpose, workflow, and the email-draft/send_email split. The import and json_* addressing modes are left entirely to the schema, which it covers, so nothing critical is missing, though the description itself is not exhaustive over the operation surface.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and every parameter, including the 17-value operation enum, is documented in the schema itself. The description adds no syntax or format detail beyond what the schema already provides, so the baseline 3 is correct.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb set (compose, edit, deliver) over a named resource (scratchpad text content) and enumerates the covered content types (emails, documents, descriptions). It also distinguishes itself from siblings by naming send_email and 'the service tool directly' as the routes for other cases, so an agent can place it without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use ('any multi-line content'), when-not ('for short one-liners, use the service tool directly instead'), and the alternative for the actual send step ('pass the final text to send_email'). Both the selection rule and the exclusion are stated, not implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_sheetsC
Read, write, and manage Google Sheets spreadsheets.
| Name | Required | Description | Default |
|---|---|---|---|
| Yes | Account email address. On list operations, "all" runs it once for every configured account. | ||
| index | No | Position among tabs (0-based). Appended at the end if omitted. | |
| range | No | A1 notation range (e.g. 'Sheet1!A1:D10', or just 'Sheet1' for a whole tab). On `append`, the target tab — defaults to 'Sheet1'; use 'MyTab' or 'MyTab!A:Z' to append to a specific one. | |
| title | No | On `create`, the spreadsheet title (defaults to 'Untitled spreadsheet'); on `renameSpreadsheet`, its new title. On `addSheet`, the name of the new TAB; on `renameSheet`, that tab's new title; on `duplicateSheet`, the name for the copy (defaults to 'Copy of <source>'). | |
| values | No | Comma-separated values for a single row (e.g. 'Alice,100,true') | |
| sheetId | No | Sheet ID of the tab, from `manage_sheets get`. On `duplicateSheet` and `copySheetTo`, the SOURCE tab to copy. | |
| rowCount | No | Initial row count (default 1000) | |
| operation | Yes | get: get spreadsheet metadata and sheet names | create: create a new spreadsheet (optionally with a title) | read: read cell values from a range; rendered rows are prefixed with their sheet row number (e.g. 'R3: …') since blank rows are otherwise invisible | append: append rows to a spreadsheet (rows land after the last row of existing data in the target range) | getValues: get values from a specific range (raw API); rendered rows are prefixed with their sheet row number (e.g. 'R3: …') | updateValues: write values to a specific range | clearValues: clear cell values from a range (structure preserved) | addSheet: add a new tab (sheet) to the spreadsheet | renameSheet: rename a tab (sheet) within a spreadsheet | deleteSheet: delete a tab (sheet) from the spreadsheet — irreversible | duplicateSheet: duplicate a tab within the same spreadsheet | renameSpreadsheet: rename the spreadsheet (the document title, not a tab) | copySheetTo: copy a tab from this spreadsheet into another spreadsheet | |
| jsonValues | No | JSON 2D array of rows (e.g. '[["a","b"],["c","d"]]'). Use for bulk and multi-row writes. | |
| columnCount | No | Initial column count (default 26) | |
| spreadsheetId | No | Spreadsheet ID. On `copySheetTo`, the SOURCE spreadsheet. | |
| valueInputOption | No | How input is interpreted: USER_ENTERED (default, parses formulas/types) or RAW | |
| destinationSpreadsheetId | No | Destination spreadsheet ID |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, and it delivers almost nothing: no mention of destructive operations (deleteSheet, clearValues), no auth or permission expectations, no note on the email-scoped 'all' fan-out, no rate-limit or batch guidance. The single sentence repeats the tool's name rather than adding behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One front-loaded sentence with no filler, which is genuinely concise and never buries the point. It is thin for a 13-parameter tool, but that is a completeness issue rather than a structure or verbosity problem.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is complex (13 operations, 13 parameters, no annotations, no output schema) yet the description is a single generic line. The schema compensates heavily by documenting each operation and even the rendered return format, so it is not inadequate — just barely sufficient for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the per-parameter and per-operation descriptions are unusually detailed (range semantics, jsonValues bulk writes, row-number prefixes). The description adds nothing on top of that, so the baseline 3 is appropriate — the schema does all the work.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb set (read, write, manage) against a specific resource (Google Sheets spreadsheets), which distinguishes it from the Docs/Drive/Calendar siblings. However, it is generic — it doesn't hint at the 13-operation dispatch model that is the tool's actual core, so an agent learns the domain but not the shape.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No when-to-use guidance, no exclusions, and no mention of the natural alternative (manage_drive for file-level operations, manage_docs for text documents). The agent must infer all routing from the operation enum in the schema rather than from the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_tasksC
Manage task lists and tasks in Google Tasks.
| Name | Required | Description | Default |
|---|---|---|---|
| due | No | Due date (RFC 3339, e.g. 2026-07-20T00:00:00.000Z — Google stores the date, not the time) | |
| Yes | Account email address. On list operations, "all" runs it once for every configured account. | ||
| notes | No | Task notes / details | |
| title | No | On `createTaskList`, the task list name. On `create` and `update`, the task title. | |
| status | No | Task status | |
| taskId | No | Task ID | |
| operation | Yes | listTaskLists: list all task lists | getTaskList: get a task list by ID | createTaskList: create a new task list | deleteTaskList: delete a task list and all its tasks | list: list tasks in a task list | get: get a specific task | create: create a new task | update: update a task (patch semantics — only the fields you pass are changed) | complete: mark a task as completed | delete: delete a task | |
| maxResults | No | Max tasks to return (default: 20, max: 100) | |
| taskListId | No | Task list ID (use `listTaskLists` to find) | |
| showCompleted | No | Include completed tasks (default: true) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden, yet it discloses nothing about destructive operations, permissions, account selection, patch semantics, or return behavior. It is not misleading, but it adds almost no behavioral context beyond the domain label.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no filler. It is efficiently concise, though its brevity encodes under-specification rather than deliberate compression.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a ten-parameter, multi-operation tool with destructive operations and no annotations or output schema, the description is far too thin. The schema compensates on parameter meanings, but an agent still lacks high-level guidance on operation selection, side effects, and account scoping.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all ten parameters are already documented richly in the schema, including operation meanings, email=all behavior, and patch semantics for update. The description itself adds no parameter semantics, which is acceptable given the schema baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the specific resource and domain: task lists and tasks in Google Tasks. The verb 'manage' is broad, but the resource is clear enough to distinguish this from siblings like manage_calendar or manage_email. It does not differentiate among the tool's many operations, but the schema does that.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no when-to-use or when-not-to-use guidance, no alternatives, and no prerequisites. An agent must infer entirely from the operation enum that this is the Google Tasks CRUD tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_workspaceB
Manage files and directories in the workspace sandbox. Supports nested paths (e.g. "reports/q1/summary.csv"). The workspace is the exchange point for file operations (attachments, downloads, exports).
| Name | Required | Description | Default |
|---|---|---|---|
| path | No | Directory path (for list: scope to subdirectory, for mkdir: directory to create) | |
| source | No | Source path (for move) | |
| content | No | File content to write (for write) | |
| filename | No | File path, may include directories (for read, write, delete, compress, decompress). E.g. "reports/q1/summary.csv" | |
| operation | Yes | list: show files (recursive) | read: get file content | write: save content to file | delete: remove file or directory | move: move or rename a file/directory | mkdir: create a directory | compress: gzip a file | decompress: gunzip a file | |
| destination | No | Destination path (for move, compress, decompress). Defaults to filename.gz for compress, strips .gz for decompress. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry behavioral disclosure. It only mentions nested-path support and the file-exchange context. It does not disclose that operations like delete, move, or write are mutating or potentially destructive, nor any overwrite semantics, irreversibility, or permission requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with no filler: purpose, path capability, and integration context are each stated once and front-loaded. The example path 'reports/q1/summary.csv' is concrete and earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The workspace-scope and nested-path context combine well with a high-coverage schema that spells out operations and defaults. However, with no annotations and no output schema, the description leaves destructive-operation caveats, expected return shapes, and path-boundary limits implicit, making it adequate but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters and explains each operation enum value and destination default. The description adds the nested-path convention and workspace role, but this is contextual rather than necessary parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Manage files and directories in the workspace sandbox,' naming a concrete resource and scope that separates it from siblings like manage_drive or manage_docs. The nested-path example further clarifies the file-operation role. 'Manage' is somewhat broad, but the schema's operation enum removes ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It says the workspace is 'the exchange point for file operations (attachments, downloads, exports),' which implies use when exchanging files with the workspace. However, it does not explicitly state when to prefer this over alternatives such as manage_drive, nor does it mention exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
queue_operationsA
RENAMED to bulk_operations, which does the same thing. This name still works and will be removed in a future release. Do many things in one call, two ways. mode:'queue' (default) runs different operations in sequence, chaining results with $N.field — works for every tool. mode:'batch' does ONE operation across many resources in a single Google request — far fewer round trips, but only where Google publishes a batch method.
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | queue (default): N operations, N API calls, in order, with $N.field references between them. batch: ONE operation across many resources in a single API call — no $N references, because there is no 'between'. | |
| tool | No | batch only — the tool to call, e.g. 'manage_contacts'. | |
| No | batch only — the account to act as. | ||
| items | No | batch only — one entry per resource. A bare id string is enough when that is all that differs, e.g. ['people/c1', 'people/c2']; use objects when items carry more, e.g. [{name: 'Ada Lovelace', contactEmail: 'ada@example.com'}]. Anything shared by the WHOLE batch — labels to add, a field mask — goes at the top level of this call, not in here. | |
| detail | No | summary: one-line status per operation (default) | full: include complete output from each operation | |
| operation | No | batch only — the operation to apply to every item, e.g. 'delete'. Ask for one that cannot batch and the error names the ones that can. | |
| operations | No | Operations to execute sequentially |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose real behavioral traits: batch mode's hard constraint ('only where Google publishes a batch method'), queue mode's universal applicability ('works for every tool'), and failure behavior ('the error names the ones that can'). It is silent on auth requirements and partial-failure semantics beyond what onError already documents in the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the deprecation/rename fact, which is the most decision-relevant information, then the purpose and mode distinctions. Three tight sentences with little waste; a minor overlap with schema text on mode semantics keeps it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter, no-annotation, no-output-schema tool, the description covers the routing decision, both execution modes, chaining semantics, and batch eligibility. Missing only auth/permission expectations and explicit return-shape guidance, though the detail enum in the schema covers output verbosity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds framing the schema does not: the queue-vs-batch tradeoff (round trips vs chaining), the meaning of $N.field references, and that batch mode permits no $N references 'because there is no between'. That is genuine added meaning on top of already-complete parameter docs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific capability ('Do many things in one call, two ways') and immediately identifies itself as a deprecated alias for bulk_operations, which lets an agent distinguish it from all other siblings. The purpose is slightly muddled by leading with the rename notice, but the underlying function (sequenced vs batched multi-operation execution) is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Names the alternative (bulk_operations) and the condition that selects it (this name still works but will be removed), then gives explicit when-to-use guidance for each mode: 'queue' for different operations in sequence with $N chaining, 'batch' for ONE operation across many resources where Google publishes a batch method. When-not conditions are stated for batch mode.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_emailA
Send mail from a Gmail account: a new message, a reply, a reply-all, or a forward. It sends immediately, so call it only for a message the user asked for, with the complete final text. email is the account the message is sent FROM. To prepare mail for the user to review first, use manage_email createDraft, then sendDraft here once they approve it.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | CC email(s), comma-separated. On `replyAll` these are ADDITIONAL — they do not replace the recipients already on the thread. | |
| to | No | Recipient email(s), comma-separated | |
| bcc | No | BCC email(s), comma-separated | |
| body | No | Email body text. On `forward`, an optional note prepended ABOVE the forwarded message. | |
| from | No | Sender email or RFC 2822 mailbox for a verified Gmail Send As alias | |
| html | No | Treat body as HTML content (default: plain text) | |
| Yes | Account email address this acts as. Required: there is no default account here. | ||
| draftId | No | Draft id (the r… id from listDrafts or createDraft), not a message id | |
| subject | No | Email subject line | |
| messageId | No | Email message ID | |
| operation | Yes | send: compose and send a new email (attachments up to 25 MB via the upload endpoint) | reply: reply to a message (thread-aware) | replyAll: reply-all to a message (thread-aware, includes all recipients) | forward: forward a message to new recipients (includes original attachments by default) | sendDraft: send a saved draft exactly as it is, by its draft id (the r… id from manage_email listDrafts or createDraft). Use this after the user has reviewed a draft, so what goes out is what they read. | |
| attachments | No | Workspace filenames to attach, comma-separated (files must exist in workspace via manage_workspace). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does disclose the critical trait — it 'sends immediately,' so it is irreversible — plus that `email` has no default account here. It does not cover broader auth expectations (e.g. that `from` requires a verified Send As alias) or any rate limits, which keeps it short of a 5.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three tight sentences that are strictly front-loaded: the destructive/immediacy constraint and the createDraft alternative both come before any parameter talk. Zero filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 12-parameter, no-annotation, no-output-schema tool, the description covers the two things an agent most needs and the schema cannot express: that sending is immediate/irreversible and that the correct pre-review path is createDraft + sendDraft. Per-parameter detail (cc, bcc, body, html, attachments) is already documented in the schema, so no return-value or parameter explanation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; however the description adds meaning the schema alone does not by resolving the easily-confused `email` vs `from` pair — '`email` is the account the message is sent FROM' (the acting account) versus `from` as an alias. Thread-aware semantics for reply/replyAll are also sketched, though no syntax examples are given.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence names the specific verb and resource and enumerates the four message kinds handled (new, reply, reply-all, forward), matching the operation enum. It also distinguishes itself from the sibling manage_email by naming createDraft as the non-sending alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when/when-not: 'call it only for a message the user asked for, with the complete final text,' plus a concrete alternative workflow ('use manage_email createDraft, then sendDraft here once they approve it'). Nothing about routing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
14 tool updates
v4.8.0- First observed
bulk_operations - First observed
manage_accounts - First observed
manage_calendar - First observed
manage_contacts - First observed
manage_docs - First observed
manage_drive - First observed
manage_email - First observed
manage_meet - First observed
manage_scratchpad - First observed
manage_sheets - First observed
manage_tasks - First observed
manage_workspace - First observed
queue_operations - First observed
send_email
TDQS
Scored across 14 tools
Most tools are clearly scoped to distinct Google services, but queue_operations is a deprecated duplicate of bulk_operations with identical functionality, creating confusion. Additionally, manage_scratchpad overlaps with manage_email's draft creation, leaving agents unsure which tool to use for composing drafts.
The set predominantly follows a consistent 'manage_<resource>' pattern (manage_email, manage_calendar, etc.). Minor deviations exist: send_email uses a different verb, and bulk_operations/queue_operations are noun phrases rather than verb_noun, but overall the naming is predictable.
With 14 tools, the count is well-suited for a broad Google Workspace suite, covering core services without being overwhelming. Each tool represents a distinct service or utility, and the count falls within the ideal 3–15 range.
The surface covers Gmail extensively (search, triage, labels, drafts, etc.) plus Calendar, Drive, Docs, Sheets, Contacts, Tasks, and Meet. Gaps include Google Slides, Forms, and Chat, but for a Gmail-centric edition, the core workflows are well-supported.
Maintenance
Related MCP Connectors
Permissioned access to Gmail, Drive and Calendar via the user's own Google account
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Search and triage all your mailboxes; draft replies and campaigns; send only as you allow.
Manage Gmail messages, threads, labels, drafts, and settings from your workflows. Send and organiz…
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Gmail through the Gmail API to read, send, and manage emails. Supports multiple Gmail accounts with real-time monitoring and advanced features for email search and attachment handling.17Apache 2.0
- AlicenseCqualityDmaintenanceEnables comprehensive Gmail management through the Gmail API, including sending/receiving emails, organizing labels and threads, managing drafts, and configuring account settings with secure OAuth2 authentication.641,792 npm1MIT
- AlicenseBqualityDmaintenanceEnables comprehensive Gmail management including sending, reading, and organizing emails, managing labels, drafts, threads, and configuring account settings through the Gmail API with secure OAuth2 authentication.641,792 npmMIT
- FlicenseNot gradedqualityDmaintenanceEnables read and compose access to three Gmail accounts simultaneously, with tools for searching, viewing threads and messages, and drafting or sending replies.-