Skip to main content
Glama
macos-mail-mcp

macos-mail-mcp

macos-mail-mcp

npm version License: MIT Node.js 22.12+ macOS

An MCP server for Apple Mail (macOS Mail.app) that connects Claude to your email via AppleScript. Provides 20 tools for reading, searching, managing, and composing emails.

Supported Accounts

Works with any email account configured in macOS Mail.app — iCloud, Gmail, Outlook/Exchange, Yahoo, Fastmail, custom IMAP/POP, etc. No code changes needed; just add the account in Mail.app and it becomes available through all 20 tools.

Related MCP server: imail-mcp

Requirements

  • macOS with Mail.app configured (with at least one email account)

  • Node.js 22.12+

  • An MCP client. Claude Code, Claude Desktop and Cowork are the ones set up below; any client that speaks MCP over stdio works.

Installation

Quick Install (npm)

The easiest way — no cloning or building required.

Claude Code and Claude Desktop use separate MCP configs. The claude mcp add command below configures Claude Code only — it writes to ~/.claude.json. Claude Desktop and Cowork read a different file (claude_desktop_config.json) and must be configured separately. Set up whichever you use, or both.

Claude Code (CLI):

claude mcp add --transport stdio --scope user macos-mail-mcp -- npx -y macos-mail-mcp@latest

--scope user makes the server available in every project — the default local scope only registers it for the directory you run the command in. -y lets npx install the package on first run without an interactive prompt. @latest makes the auto-update behaviour explicit — see Staying up to date.

Claude Desktop (and Cowork):

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "macos-mail-mcp": {
      "command": "/absolute/path/to/npx",
      "args": ["-y", "macos-mail-mcp@latest"],
      "env": { "PATH": "/absolute/path/to/node/bin:/usr/bin:/bin" }
    }
  }
}

Both paths above are placeholders. Use the absolute path to npx — GUI apps don't inherit your shell's PATH, so a bare "npx" usually fails to launch, and the correct path differs per install. Find yours with which npx:

  • Apple Silicon Homebrew: /opt/homebrew/bin/npx

  • Intel Homebrew: /usr/local/bin/npx

  • nvm: ~/.nvm/versions/node/<version>/bin/npx

The env.PATH entry lets npx locate node for the same reason. Then fully quit Claude (Cmd+Q — closing the window isn't enough) and reopen; the config is only read at startup. If the server doesn't appear, check ~/Library/Logs/Claude/mcp*.log for spawn errors.

Staying up to date

Installed copies update themselves. npx re-resolves the published version every time the server starts, so a new release is picked up without you touching the config.

@latest in the commands above makes that explicit rather than changing it. Why a bare package name already re-resolves, why @latest is still worth writing, and what it costs are in CLAUDE.md, which the package does not ship.

Two consequences worth knowing:

  • Updates land at server start, not while it is running. A long-running Claude Desktop keeps serving the version it launched with. Quit and reopen it to pick up a release.

  • The check is a registry round-trip. With the registry unreachable the server fails to start rather than falling back to the cached copy. That is the price of always-current; pinning a version to avoid it gives up the updates.

What each version changed is in the changelog.

Install from Source

For working on the server itself. This path does not auto-update — it runs whatever npm run build last produced in your working tree, which is exactly what you want while developing and not what you want otherwise.

git clone https://github.com/marius-cetanas/macos-mail-mcp.git
cd macos-mail-mcp
npm install
npm run build

Then register with Claude Code. Use a distinct name so the local build does not shadow a published copy you may also have registered:

claude mcp add --transport stdio --scope user macos-mail-mcp-dev -- node /path/to/macos-mail-mcp/build/index.js

Or add to Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json):

{
  "mcpServers": {
    "macos-mail-mcp-dev": {
      "command": "/absolute/path/to/node",
      "args": ["/path/to/macos-mail-mcp/build/index.js"]
    }
  }
}

Use the absolute path to node here too (find yours with which node) — same PATH reason as above. Then fully quit and reopen Claude.

macOS Permissions

On first use, macOS will prompt to grant automation permission for controlling Mail.app. Go to System Settings > Privacy & Security > Automation to manage this.

Tools

Accounts (2)

Tool

Description

list_accounts

List all mail accounts (name, type, enabled, full name, emails)

get_account_detail

Get full account details (server, port, SSL, mailbox count)

Account type is an open string: known IMAP/POP/iCloud/SMTP types use canonical names, and other raw Mail type text is preserved. Backend-reported unknown remains unknown; the account's name or email domain is not used to infer Exchange identity.

Breaking account-detail contract: serverName, port and usesSsl can now be null when unsupported, missing or unavailable. Clients must handle null instead of relying on empty-string, zero or false defaults. Genuine available values, including SSL false and port 0, are preserved.

Mailboxes (3)

Tool

Description

list_mailboxes

List mailboxes for an account or all accounts

get_mailbox_info

Get mailbox details (message count, unread count)

create_mailbox

Ensure a mailbox exists (top-level or nested), reporting whether it was created or already existed

For create_mailbox, parentMailboxName can be an existing parent name or full path. The tool resolves that parent, checks the full slash path within the requested account, and reuses an existing mailbox or creates an absent one. It returns the full path read back from Mail as mailboxName, with created: false, alreadyExisted: true for an existing target and created: true, alreadyExisted: false after creation. Lookup/permission failures return errors. Omit the parent to address the account directly.

Messages (8)

Tool

Description

list_messages

List messages with pagination (limit/offset) and optional date filtering (after/before)

get_message

Get full message content, headers, recipients, attachments. Mailbox name is optional — omit to search all mailboxes in the account.

search_messages

Bounded serial search with explicit slow-search opt-in and partial-result metadata; results identify account and full mailbox path

move_message

Move a message to a different mailbox

move_messages

Bulk move multiple messages to a different mailbox in a single operation

delete_message

Delete a message (moves to Trash)

flag_message

Set/clear flag with optional color index (0-6)

mark_read

Mark message as read or unread

In get_message results, an absent recipient display name is the empty string in name. The to/cc/bcc arrays preserve known names, addresses and recipient order.

Every message dateReceived from list/search/get uses UTC ISO 8601 at second precision: YYYY-MM-DDTHH:mm:ssZ. It identifies an absolute instant for parsing and UTC-aware after/before inputs; clients can render it in their preferred local timezone. Message-date scripts run in isolated UTC subprocesses to avoid historical daylight-saving and repeated-clock ambiguity.

Unknown message IDs report plain decimal IDs and the requested account/mailbox, for example Message 999999999 not found in account "Work", mailbox "INBOX". Account-wide get_message reports that all mailboxes were searched. Only native missing-object/index errors from the ID lookup are translated; permission, timeout, mailbox-resolution and later action/property errors retain their original meaning. Bulk moves preserve per-ID failures and successful move counts.

move_messages validates every ID before looking up mailboxes or moving messages. Its result reports moved, failed and an errors list containing each failed numeric ID and error text. Dynamic integer fields use locale-independent decimal digits within JavaScript's safe integer range; The shared formatter rejects invalid or out-of-range values. Account metadata treats an unrepresentable port as unavailable and returns port: null.

Search safety and partial results

Breaking search contract: search_messages returns an object instead of an array, and limit is now capped at 200 (default 50). Subject/sender searches require accountName and mailboxName by default. A bounded mailbox-info preflight permits at most 1,000 messages; an unavailable or invalid count requires deliberate allowSlow: true. That opt-in also permits subject/sender searches across an account or all accounts. mailboxName always requires accountName. Content searches require both scope names and allowSlow: true. Supply nonblank query text or an after/before date filter. Date bounds are inclusive.

Search has a 45 second overall server budget, including discovery/preflight, with at most 10 seconds per stage/mailbox. This leaves headroom below the 60 second Cowork client ceiling reported in the original issue. Opting in does not extend these budgets. Mailboxes run serially in discovery order; results retain Mail's order within each mailbox. Duplicate account+message-ID pairs are removed, retaining the first mailbox path; equal IDs in different accounts are distinct.

The response always contains messages, partial, cancelled, limitReached, timedOut, skipped, errors and warnings. Messages include accountName and the full mailboxName. timedOut identifies the active scope that exceeded its budget. errors contains operational failures with scope and message. skipped identifies known scopes not completed/scheduled, with reason timeout, cancelled, error or limit; discovery failures can leave later scopes unknown. A scope can have null account/mailbox names for broad discovery. partial means interruption, an operational failure or skipped scopes. limitReached means the requested cap was reached; more matches may exist even when partial is false. Invalid requests/count gates are MCP errors; operational failures return the structured response, preserving earlier results.

The server stops scheduling after the first timeout, cancellation or operational failure. It honors the MCP request's cancellation signal and terminates its search osascript process. The SDK suppresses replies after client cancellation, so callers cannot rely on receiving partial results after cancelling. Queued Apple events inside Mail cannot be cancelled: Mail may keep working after the process stops. After a timeout, wait for Mail to recover or restart Mail before retrying; repeated immediate searches can queue more work.

Attachments (4)

Tool

Description

list_attachments

List attachments with filename, MIME type, size, download status

save_attachment

Save a specific attachment to disk

save_all_attachments

Save all attachments from a message

read_attachment

Read UTF-8 attachment text inline using MIME type or a supported text extension

read_attachment accepts text/* (including text/calendar for .ics), application/json, application/xml and application/x-yaml, as well as the existing .txt, .csv, .json, .html, .md, .xml and .log extensions. MIME matching ignores case, surrounding spaces/tabs and parameters after ;, and requires a valid type/subtype base. If Mail's MIME property is missing, blank or unavailable, it uses the same filename fallback as list_attachments and get_message, including .ics → text/calendar. Unsupported-type errors include that effective MIME type and suggest save_attachment.

Admission uses metadata and filenames; it does not inspect bytes to prove the content is text. The inline reader supports valid UTF-8, preserves line endings and returns {name, content}. It does not transcode other charsets, stream content or impose a size cap; use save_attachment for binary files, other encodings or large attachments.

Both save tools create missing destination directories recursively before contacting Mail. ~ and ~/... expand to the home directory; relative paths resolve from the server's working directory. Empty/NUL paths, regular-file destinations and failed directory/write/search checks produce a path-bearing error. Created directories remain if a later Mail operation fails. The filesystem can change after these checks, and Mail may have different privacy or filesystem permissions from Node; native save errors still propagate in those cases.

Compose (3)

Tool

Description

send_message

Send a new email with optional CC, BCC, and attachments

reply_to_message

Reply or reply-all to a message

forward_message

Forward a message to a new recipient

All three accept an optional fromAccount to choose which account sends, and report the account actually used — see Choosing the sending account.

For send_message, attachmentPaths must contain absolute paths to readable regular files; paths containing CR, LF or NUL are rejected. Every file is checked before composing. The script checks both the parsed path count and the outgoing content's attachment count against the number requested before calling send. A mismatch fails without sending; Mail must also return true from send before the tool reports success. This confirms Mail accepted the send command, not delivery.

Choosing the sending account

By default Mail sends from whichever account is set under Settings → Composing → "Send new messages from". Pass fromAccount to override it, using either the account name or any address that account owns (matching is case-insensitive):

{ "to": "client@example.com", "subject": "Invoice", "body": "…",
  "fromAccount": "you@work.com" }

An unrecognised value is an error listing the accounts you can choose from — it never silently falls back to the default. Only enabled accounts can be selected.

Every compose tool returns the account it actually sent from, whether or not you passed fromAccount:

{ "success": true, "sender": "Your Name <you@work.com>" }

Omitting fromAccount is still the way to accept Mail's own choice; the sender in the result tells you what that choice was, so a wrong sending account is visible immediately rather than only discoverable later in the Sent mailbox.

On reply_to_message and forward_message, note that accountName is not a sender selector — it identifies where the source message lives. Use fromAccount to control who the reply or forward comes from.

Architecture

Three layers, and the boundary between them is what keeps shell and AppleScript injection out. Tools (*.tools.ts) validate input with Zod and register with MCP. The bridge (bridge/applescript-runner.ts) loads a template, substitutes parameters with escaping, prepends the shared escapeForJson handler and runs osascript, never a shell. Scripts (*.applescript) are templates with {{param}} placeholders that return JSON. Handlers never build script text themselves. The source tree and how to add a tool are in CONTRIBUTING.md, which the package does not ship either.

Known Limitations

AppleScript Foundation

This MCP communicates with Mail.app via AppleScript, which is a stable but legacy automation layer. Mail.app's scripting dictionary has been largely unchanged for years, but future macOS updates could require script adjustments. This is an inherent trade-off of the approach — AppleScript is the only officially supported way to automate Mail.app without writing a native plugin.

Performance

  • Large mailbox searches — Mail's whose query may scan/load matches before applying the result limit. The search safeguards refuse risky defaults, bound server waiting and retain completed scopes; they cannot cancel Apple events already queued inside Mail. Opted-in searches can still leave Mail busy after the tool stops.

  • IMAP attachment downloads — Attachments on IMAP accounts may not be downloaded locally. The tools check download status and report clearly when an attachment needs to be opened in Mail.app first.

Message IDs

Mail.app's internal message IDs are volatile — they can change when the app reindexes, or after move/delete operations. This means multi-step workflows (e.g., list → flag → move) should re-fetch message IDs between mutations. For single-step operations this is not an issue.

Provider-Specific Behavior

  • Account connection details — Server getters are used for reported IMAP/POP/iCloud/SMTP types; other types return null connection fields. The Mail dictionary inspected for this change declares pop/smtp/imap/iCloud/unknown, with no Exchange enumerator. If a backend reports Exchange as unknown, that value remains unknown; other raw type strings are preserved. Native Exchange/provider account retrieval has not been exercised by the local fixture tests.

  • Gmail labels — move_message adds the destination label but may not remove the original (Gmail uses labels, not folders).

Other Limitations

  • Attachments on replies/forwards — AppleScript does not support adding new attachments to reply/forward messages (Mail.app limitation).

  • MIME type detection — Uses the same extension fallback for list/get/read when Mail.app's native MIME property is missing, blank or unavailable. It does not identify content from file bytes.

  • Mailbox management — Creating mailboxes is supported, but deleting and renaming mailboxes is not possible via AppleScript (Mail.app limitation).

Known issues

An end-to-end run of every tool against 2.0.0 filed twelve findings, #84 to #95; 2.1.0 changed nothing in the server. The current source inserts reply/forward text and validates readback (#84), and validates multiple attachment paths and prepared attachment counts (#85). File reads now preserve valid UTF-8 text, line endings and trailing newlines (#86), and numeric JSON formatting preserves mixed move results under comma-decimal coercion (#87). Nested mailbox creation uses resolved full paths at the account and validates path readback (#88); existing targets are reused with explicit status metadata (#89). Executable AppleScript helper tests and Mail dictionary compilation cover these changes. Native Mail content insertion, attachment enumeration and delivery still require an end-to-end check. Inline attachment reading now accepts supported MIME types and shared filename fallbacks (#94); native Mail attachment retrieval remains unexercised by fixture tests. Other findings are in the open issues.

Roadmap

  • get_thread — Retrieve all messages in a conversation thread. Mail.app has no native threading support; implementation would require parsing RFC headers (Message-ID, In-Reply-To, References) which is slow on large mailboxes. Not scheduled: 2.0.0 and 2.1.0 shipped without it.

Development

npm run dev           # Watch mode (TypeScript compiler)
npm test              # Run tests
npm run test:coverage # Tests + coverage report
npm run test:watch    # Watch mode tests
npm run build         # Build for production

The suite covers src/ fully, and vitest.config.ts enforces 100% statement, branch, function and line thresholds. CI runs test:coverage, so new code without tests fails the build.

On macOS, tests/domains/compose/send-attachments.applescript.test.ts executes the production attachment path parser and count/send guards and compiles the complete send template with its shared handlers. It never creates or sends a Mail message. These executable AppleScript checks are skipped on other platforms; the template wiring assertions still run there.

tests/bridge/read-utf8-file.applescript.test.ts executes the production body, attachment-path, attachment-name and inline-content reads against local UTF-8 fixtures, checking JSON roundtrips for LF, CRLF, CR, trailing newlines, empty files, Unicode, controls and BOMs. It also compiles all affected templates. These macOS checks do not exercise Mail's attachment saving, content insertion or delivery; other encodings and binary content are outside the UTF-8 reader's contract.

tests/bridge/integer-for-json.applescript.test.ts executes numeric formatting and partial move result assembly with large IDs, audits every dynamic integer JSON field, and compiles all domain templates. Its macOS checks use pure serialization fixtures; native Mail lookups and moves remain unexercised.

tests/domains/mailboxes/create-mailbox.applescript.test.ts executes production path construction and readback guards and compiles the complete creation template. It executes the production existence/status branches and response assembly with fixture Mail primitives, checking existing/new statuses and lookup/creation errors. Native mailbox creation and provider behavior remain unexercised.

tests/domains/messages/recipient-names.applescript.test.ts executes both production recipient serializers and message JSON assembly using local recipient records, and compiles both lookup templates. It does not read native Mail messages.

tests/domains/accounts/account-metadata.applescript.test.ts executes production type mapping and account JSON with local records/getter fixtures, checks unavailable metadata and supported values, and compiles both account templates. It does not query native accounts. SMTP server settings are declared by Mail's dictionary; this does not establish that SMTP servers appear in account queries.

Search controller tests use fake clocks/bridge calls to exercise budgets, count gates, partial results and SDK cancellation. Bridge tests verify abort checks, search-process SIGKILL options and temp cleanup; the search template's pure guards execute and its complete script compiles. These checks do not run native Mail searches or demonstrate cancellation of queued Apple events.

tests/bridge/date-to-utc-iso.applescript.test.ts executes production date formatting with actual AppleScript dates at known instants, including historical DST, both fall-back occurrences, negative/zero epochs, offsets and year boundaries in English/Romanian process locales. It checks getter/JSON and filter reconstruction; registered/caller tests verify selective UTC environments and timestamp/error propagation. All shared script contexts compile. Native Mail date reads and provider behavior remain unexercised; host, Node and Mail timezone settings are unchanged.

tests/domains/messages/attachment-mime.applescript.test.ts executes the production MIME helpers, all three metadata loops and the inline-read flow with local lookup/save fixtures. It checks MIME case/parameters/fallbacks, every existing extension mapping, admission before saving, UTF-8/JSON readback, errors and temp cleanup. All shared template contexts compile, and registered-tool tests cover result/error propagation. These checks do not read or save native Mail attachments.

tests/bridge/resolve-message.applescript.test.ts executes production lookup/error boundaries, account-wide search and partial bulk-move flows with replaced Mail transport, and audits all 13 lookup sites. tests/domains/messages/save-directory.test.ts prepares real local directories and executes the save-path initialization/JSON expressions with special-character paths. Registered-tool tests cover path and message errors; all shared contexts compile. These checks do not perform native Mail lookups, moves or attachment saves, and do not prove Mail permissions.

Changelog

Every version's changes are in CHANGELOG.md. It ships inside the npm package, so an installed copy carries its own version's entries alongside its package.json; and each GitHub release from 2.1.0 on opens its notes with that version's section, the commit list folded beneath — when the section was recorded before the tag, which is the procedure here; a version recorded late, as 1.3.1 was, gets the commit list alone. The 2.0.0 major changed only the Node.js floor — the server itself was unchanged — which is the kind of fact this file exists to say, and the reason it now ships (#96).

License

MIT

Available Tools

20 tools
create_mailboxA

Ensure a mailbox (folder) exists in a Mail.app account. For nesting, resolve the parent and use its full slash path at the account. Returns the full path read back from Mail and explicit created/alreadyExisted booleans; an existing mailbox is reused.

NameRequiredDescriptionDefault
accountNameYesThe name of the account to create the mailbox in
mailboxNameYesThe child name to create, or a full slash path when parentMailboxName is omitted
parentMailboxNameNoAn existing parent mailbox name or full path for nesting; omit to create directly at the account

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the full burden and does well on the important traits: it is a mutation that is safe to repeat because an existing mailbox is reused, and it discloses the exact return contract (full path read back from Mail, plus created/alreadyExisted booleans). It omits prerequisites such as Mail.app permissions, account existence, and failure behavior when the parent path is invalid.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with purpose then nesting then return contract, with no filler. The phrase 'use its full slash path at the account' is slightly compressed and could be read as ambiguous, which is the only structural blemish.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description appropriately spells out the return values, and it covers the idempotency semantics an agent needs. What remains thin for an unannotated mutation tool is environmental context: permission requirements and error conditions for a non-existent account or parent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3; the description adds beyond the schema by framing the nesting convention (resolve the parent, pass its full slash path at the account) and by implying mailboxName is interpreted as a full path when the parent is omitted. It does not clarify path separator edge cases or whether the account name must match an entry from list_accounts.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a precise verb+resource: ensure a mailbox (folder) exists in a Mail.app account. The word 'ensure' immediately signals idempotent creation, which is a meaningful distinction from a plain create and cannot be inferred from the name alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives real operative guidance: for nesting, resolve the parent and pass its full slash path, and it notes that an existing mailbox is reused rather than failing. It does not explicitly point to siblings such as list_mailboxes or get_mailbox_info as the way to resolve or verify a mailbox, leaving that inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_messageA

Delete a message. Uses Mail's delete verb which routes to the correct Trash.

NameRequiredDescriptionDefault
messageIdYesThe numeric ID of the message
accountNameYesThe name of the account containing the mailbox
mailboxNameYesThe name of the mailbox containing the message

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present, the description carries the behavioral burden. It adds a useful transparency detail: deleting uses Mail's delete verb and routes to the correct Trash rather than permanently erasing the message. However, it does not mention return behavior, reversibility beyond the Trash implication, or permission/side-effect considerations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences with no filler. The primary action is front-loaded, and the second sentence adds a meaningful behavioral clarification about Trash routing. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has only three required parameters, all schema-documented, and the description explains the operational routing to Trash. However, it still has gaps: there is no output schema, no indication of what the response looks like, and no guidance on success/failure conditions. This is adequate but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage for all three required parameters, so the schema already documents messageId, accountName, and mailboxName clearly. The description adds no parameter-level meaning beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a direct, specific action: 'Delete a message.' The operation is unambiguous and distinct from the sibling tools, since no other sibling provides deletion and the closest operations (move_message, flag_message) are clearly different.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool should be used when a message must be deleted, but it does not explicitly discuss alternatives such as move_message, whether deletion is preferable to moving, or when not to use this tool. Usage context 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.

flag_messageB

Set or clear the flag on a message. Optionally specify a flag colour index.

NameRequiredDescriptionDefault
flaggedYesWhether to flag (true) or unflag (false) the message
flagIndexNoThe flag colour index (optional, default -1)
messageIdYesThe numeric ID of the message
accountNameYesThe name of the account containing the mailbox
mailboxNameYesThe name of the mailbox containing the message

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full burden of behavioral disclosure. It only states the basic set/clear action and optional colour index; it does not explain side effects, whether the operation requires an existing message, whether it is idempotent, or what the response contains.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short and front-loaded: it states the core purpose in the first sentence and adds the optional modifier in a single second sentence. There is no redundant or distracting content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple flagging operation, the basic action and parameter schema are present, and all parameters are individually documented. However, with no annotations and no output schema, the description does not fully communicate behavioral outcomes or the relationship between flagged and flagIndex, leaving the agent to guess some edge-case behavior.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 parameters. The description only mirrors the optional flagIndex concept and does not add materially to the parameter semantics provided by the input schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Set or clear the flag') and the resource ('on a message'), and adds the optional flag colour dimension. It is not tautological, though it does not explicitly differentiate itself from sibling tools like mark_read.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives, and does not mention exclusions or related sibling tools. An agent would have to infer the intended context purely from the wording of the schema and sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

forward_messageA

Forward an existing email message to a new recipient. Returns the sender the forward was sent from. Does not support adding new attachments (Mail.app limitation).

NameRequiredDescriptionDefault
toYesThe recipient email address to forward to
bodyNoOptional text to prepend to the forwarded message body
messageIdYesThe numeric ID of the message to forward
accountNameYesThe name of the account containing the mailbox. This locates the source message only — it does not control which account sends. Use fromAccount for that.
fromAccountNoAccount to send from — a Mail account name ("Google") or one of its addresses ("you@gmail.com"), as reported by list_accounts. Matching is case-insensitive and an unrecognised value is an error, never a silent fallback. Omit to use Mail's default sending account; either way the account used is returned as `sender`.
mailboxNameYesThe name of the mailbox containing the message

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden, and it does meaningful work: it discloses that the tool returns the sender account, and it flags an important behavioral limitation (no new attachments due to Mail.app). It could add more about side effects or failure modes, but the core behavior is transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three concise sentences. The main action is front-loaded, the return value is specified, and the limitation is stated directly with no unnecessary filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the schema already covers all parameter semantics, the description is nearly complete: it explains the action, the return value, and the attachment limitation. The only missing piece is explicit routing guidance among the related sibling tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

All parameters have complete descriptions in the schema, so the description does not need to compensate. It adds useful behavioral context around the sender and attachment limitation, but it does not provide additional parameter-specific details beyond what the schema already contains.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: forward an existing email message to a new recipient. This clearly distinguishes it from siblings like send_message and reply_to_message because it explicitly describes forwarding an existing message rather than composing a new one or replying to the original sender.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The usage is implied by the purpose: use this when a user wants to forward an existing message to a new recipient. However, the description does not explicitly mention when not to use it or name alternatives like send_message for new emails or reply_to_message for replying to the sender.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_account_detailB

Get detailed information about a specific Mail.app account by name. Unavailable serverName, port and usesSsl values are null; account type preserves raw Mail values beyond known canonical types.

NameRequiredDescriptionDefault
accountNameYesThe name of the account to retrieve

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden, and "Get" implies a non-destructive read but never says so. It does add genuine behavioral context about the return values — unavailable serverName, port, and usesSsl come back as null, and account type preserves raw Mail values beyond canonical types — yet says nothing about behavior when the account name is unknown or about permissions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the purpose and followed by return-value caveats; no filler. The second sentence is somewhat dense with field names, but every clause conveys information the agent would otherwise have to guess.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read tool with no output schema, the description covers purpose, the lookup key, and the noteworthy null/raw-type quirks of the response. The missing piece is failure behavior for an unknown account name, which would matter for correct usage.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the single accountName parameter is already documented in the schema. The description only restates that lookup is by name, adding no format, casing, or resolution rules for the name. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Get detailed information about a specific Mail.app account by name" gives a clear verb plus resource and the lookup key, which separates it from list_accounts at a glance. It does not explicitly name the sibling, but the singular-account scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit statement of when to use this versus list_accounts, nor any prerequisite about where the account name must come from. The only implied guidance is "by name," leaving the agent to infer that list_accounts must be called first to discover valid names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_mailbox_infoB

Get detailed information about a specific mailbox in a Mail.app account

NameRequiredDescriptionDefault
accountNameYesThe name of the account that contains the mailbox
mailboxNameYesThe name of the mailbox to retrieve

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must carry the full burden of behavioral disclosure. It indicates a read operation but does not describe what 'detailed information' contains, what happens if the mailbox does not exist, whether authentication requires to be ready, or that the operation is safe to call idempotently.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no filler or repetition. It front-loads the primary action ('Get detailed information') and scopes it to a specific mailbox. It earns a 5; it just lacks a bit of detail that would make it fully informative.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Although the parameter schema is clear, the description lacks any indication of what the 'detailed information' will contain, and there is no output schema to infer from. It also doesn't clarify why an agent would actually use this tool in the workflow vs list_mailboxes to get names. For a tool expected to return meaningful content, this is a notable gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema covers 100% of the two parameters with clear descriptions ('The name of the account that contains the mailbox', 'The name of the mailbox to retrieve'). The description adds no new semantics beyond the schema, but the schema is complete, so this meets the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific verb (Get) and a resource ('detailed information about a specific mailbox'), scoped to 'a Mail.app account.' It distinguishes from list_mailboxes implicitly by targeting one mailbox rather than enumerating them, but it never names a sibling tool or explicitly calls out what differentiates it from get_account_detail.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'specific' implies a use case where the agent already knows which mailbox to query, as opposed to listing mailboxes. However, the description provides no explicit direction on when to use this tool versus list_mailboxes or get_account_detail, and there are no stated exclusions or prerelems.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_messageA

Get the full details of a single message by its ID, including body, headers, recipients, and attachments. If mailboxName is omitted, searches all mailboxes in the account (slower but useful when you don't know which mailbox the message is in).

NameRequiredDescriptionDefault
messageIdYesThe numeric ID of the message
accountNameYesThe name of the account containing the message
mailboxNameNoThe name of the mailbox containing the message (omit to search all mailboxes in the account)

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description takes the full burden. It discloses that omitting mailboxName searches all mailboxes and notes the performance cost, which is useful. It does not explicitly discuss error handling, output structure beyond high-level fields, or confirm the absence of side effects, but the read-only nature is strongly implied by the operation name.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is only two sentences, front-loads the core operation, and spends one efficient sentence on the optional parameter. No redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a fairly simple read-only-style tool, the description is reasonably complete: it explains the primary call, the optional override, and the kind of result returned. It lacks details on error behavior or exact output structure, but it gives enough for an agent to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already explains every parameter. The description adds slight extra context about mailboxName being slower when omitted, but most parameter meaning is already in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly identifies the operation as retrieving a single message by ID and names its major components (body, headers, recipients, attachments). This distinguishes it from tools like list_messages or search_messages, since the focus is on one message's full details.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for when the optional mailboxName parameter is useful and why omitting it is slower. It does not explicitly name sibling tools as alternatives, but the usage guidance is contextually sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_accountsA

List all Mail.app accounts with their type, enabled status, and email addresses. Known types are canonicalized; other raw Mail type text is preserved, including backend-reported unknown.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral burden, and it discloses non-obvious normalization semantics: known types are canonicalized while raw Mail type text is preserved, including backend-reported unknown values. It does not describe ordering, pagination, or permission requirements, but for a simple read-only listing this is solid disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences with no filler. The primary capability is front-loaded, and the second sentence adds a genuinely useful caveat about type canonicalization rather than restating the first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter listing tool with no output schema, the description sufficiently explains what is returned and how account types are represented. It is slightly incomplete in not mentioning ordering or whether disabled accounts are included, but nothing critical to correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there are no parameter semantics to explain; the baseline for a parameterless tool is 4. The description correctly avoids inventing filtering options that do not exist.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all Mail.app accounts') and enumerates the returned fields (type, enabled status, email addresses). It is clearly distinguishable from the sibling get_account_detail, which implies a single-account lookup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: 'List all' signals enumeration versus a detail lookup, but the description never explicitly says when to prefer this over get_account_detail or list_mailboxes. An agent can infer the distinction from sibling names, but no routing guidance is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_attachmentsA

List all attachments for a message, including their name, MIME type, file size, and download status.

NameRequiredDescriptionDefault
messageIdYesThe numeric ID of the message
accountNameYesThe name of the account containing the mailbox
mailboxNameYesThe name of the mailbox containing the message

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the behavioral transparency burden. It conveys that this is a listing operation and that download status is returned, but it does not explicitly state whether it is read-only or whether any state is changed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One concise sentence that starts with the verb, identifies the resource, and lists the important return fields. There is no redundant or unnecessary content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is sufficient for a straightforward listing tool with fully documented parameters. It states what is listed and which fields are returned; the main gaps are the lack of an explicit read-only statement and detailed output format, but these are minor for this kind of tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for all three parameters, so the schema already explains messageId, mailboxName, and accountName. The description adds no parameter-level meaning, so the baseline score is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'List all attachments for a message', and enumerates the output fields. It clearly differs from read/save-related siblings by being a listing operation, but it does not explicitly compare against sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied: an agent would call this when it needs attachment metadata for a message before reading or saving attachments. However, there is no explicit when-to-use/when-not-to-use guidance, and alternatives such as get_message or read_attachment are not mentioned.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_mailboxesA

List mailboxes in a Mail.app account, or all mailboxes across all accounts

NameRequiredDescriptionDefault
accountNameNoThe name of the account to list mailboxes for; omit for all accounts

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the disclosure burden. 'List' conveys a read-only action and the description clarifies the two account scopes, but it does not mention authentication requirements, how empty or invalid accountName are handled, or the exact set of mailbox properties returned. It is adequate for a simple read-only utility but leaves some behavior unspecified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence with no unnecessary words. It presents the main verb and resource first, then the alternative scopes. Every part adds meaningful information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter, no-nested, no-output-schema tool, the description is complete. It tells the agent what the tool does and exactly how the one optional parameter affects behavior.",

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: accountName is already described as the account to list mailboxes for, or omitted for all accounts. The tool description mostly restates this same guidance, so it adds little beyond the schema. Baseline 3 applies because the schema already documents the only parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states that the tool lists mailboxes and defines its two valid scopes: a single Mail.app account or all accounts. The verb-resource pairing is unambiguous and distinguishes it from sibling tools like list_accounts (accounts vs mailboxes) and get_mailbox_info (single mailbox details).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool by defining the scope, and it explicitly says to omit accountName for all accounts. However, it gives no direct guidance about when to prefer this tool over alternatives such as list_accounts or get_mailbox_info, so usage context is mostly self-evident rather than spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_messagesB

List messages in a mailbox with pagination. Provide accountName and mailboxName to scope the listing.

NameRequiredDescriptionDefault
afterNoOnly return messages received after this ISO 8601 date (e.g. 2024-01-15T00:00:00Z)
limitNoMaximum number of messages to return (default 25)
beforeNoOnly return messages received before this ISO 8601 date (e.g. 2024-12-31T23:59:59Z)
offsetNoNumber of messages to skip for pagination (default 0)
accountNameYesThe name of the account containing the mailbox
mailboxNameYesThe name of the mailbox to list messages from

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

There are no annotations, so the description carries the full burden of behavioral disclosure. It communicates that listing is a read operation with pagination, but it does not mention ordering, inclusivity of before/after filters, the shape of the returned results, or any indirect behaviors. This is a meaningful gap for a tool with no annotation support.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is only two sentences, front-loads the primary action and pagination behavior, and includes no fluff or redundancy. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the schema fully describes all parameters and the tool is a straightforward listing operation, the description is mostly adequate. It could be improved by noting the intended pagination flow or expected message chronology, but it is not severely incomplete for an agent to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already covers all six parameters with 100% description coverage, including defaults and date formats. The description adds minimal semantic value beyond reaffirming that accountName and mailboxName scope the request, so a baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource ('List messages in a mailbox') and adds the pagination aspect, making the core purpose clear. It does not explicitly distinguish this from sibling tools like search_messages or get_message, so it does not fully earn a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description tells the agent to provide accountName and mailboxName, which clarifies the required scope for the operation. However, it gives no guidance on when to choose this tool over related alternatives such as search_messages or get_message.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

mark_readB

Mark a message as read or unread.

NameRequiredDescriptionDefault
readYesWhether to mark the message as read (true) or unread (false)
messageIdYesThe numeric ID of the message
accountNameYesThe name of the account containing the mailbox
mailboxNameYesThe name of the mailbox containing the message

TDQS

B3.1/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full disclosure burden. It states the state change but omits any side effects, return behavior, permissions, or error handling. It does clarify that both read and unread states are supported.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence with no filler. It front-loads the core action and the full range of intended behavior (read or unread) efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple, well-parameterized tool with fully documented schemas, but the description lacks behavioral context and usage guidance. It is minimally viable but leaves gaps around side effects and selection among siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage, and all four parameters already have clear meanings. The description adds no additional parameter context, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a clear verb and resource: marking a message as read or unread. It is specific enough to identify the operation, though it does not explicitly contrast with similar siblings like flag_message.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives such as flag_message or get_message. The context is implied only by the tool name and action.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

move_messageA

Move a message to a different mailbox. Gmail uses labels rather than folders. Moving a message adds the destination label but may not remove the original.

NameRequiredDescriptionDefault
messageIdYesThe numeric ID of the message
toMailboxYesThe name of the destination mailbox
accountNameYesThe name of the account containing the mailboxes
mailboxNameYesThe name of the mailbox currently containing the message

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full behavioral disclosure burden. It does this well by revealing the non-obvious consequence: moving a message adds the destination label but may not remove the original label. It does not, however, describe return values or any side effects beyond the label behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two compact sentences express the operation and its most important caveat without any filler. The main action is front-loaded, and the Gmail label explanation is kept to exactly what the agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a simple mutating tool with no output schema and no annotations, so the description must carry most of the contextual load. It covers the critical label behavior, but it could additionally mention what the result looks like or when the original label is removed. Still, the core decision-relevant context is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides descriptions for all 4 parameters, giving 100% schema coverage, so the baseline is 3. The description adds a little semantic context by explaining what 'moving' means in terms of destination label vs original label, but it does not detail each parameter's meaning beyond what the schema supplies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb+resource structure ('Move a message to a different mailbox') and immediately clarifies the Gmail label model, which distinguishes this tool from folder-based move operations. It singles out a single message action, which differentiates it from sibling move_messages.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The context implies this tool is for moving a single message, and the Gmail label caveat gives important situational guidance. However, it does not explicitly say when to use move_message versus move_messages or any other sibling, so the usage guidance is mostly inferred rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

move_messagesA

Move multiple messages to a different mailbox in a single operation. More efficient than calling move_message multiple times.

NameRequiredDescriptionDefault
toMailboxYesThe name of the destination mailbox
messageIdsYesArray of numeric message IDs to move
accountNameYesThe name of the account containing the mailboxes
mailboxNameYesThe name of the mailbox currently containing the messages

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure, but it only states the high-level action and an efficiency claim. It does not explain whether the operation removes messages from the source mailbox, what happens if some messageIds are invalid, whether the operation is atomic beyond 'single operation,' or any permission/authorization requirements. This is a meaningful gap for a batch mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two compact sentences with no filler. The core action is front-loaded, and the second sentence adds practical guidance about efficiency versus the sibling tool. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has a relatively straightforward batch-move operation with all required parameters documented in the schema, but there is no annotations or output schema. The description omits important execution context such as error handling, source-mailbox behavior after the move, or whether the operation is atomic despite the 'single operation' phrase. It is adequate for basic invocation but not fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes all four required parameters with 100% coverage. The description reinforces the notion of multiple messages and 'a different mailbox,' but it does not materially expand on parameter semantics or constraints beyond what the schema provides. The baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource—'Move multiple messages to a different mailbox'—and clearly differentiates this batch operation from the alternative move_message by describing it as a single operation and more efficient than calling move_message multiple times. The purpose is immediately unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly sets the context: moving multiple messages at once and doing so more efficiently than repeatedly calling move_message. It does not explicitly spell out when not to use the tool, such as 'for a single message use move_message,', but the efficiency comparison makes the intended use case reasonably apparent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_attachmentA

Read valid UTF-8 attachment text inline. Accepts text/*, application/json, application/xml, application/x-yaml MIME types or .txt, .csv, .json, .html, .md, .xml, .log extensions. Uses extension-based MIME fallback when unavailable. Use save_attachment for binary files.

NameRequiredDescriptionDefault
messageIdYesThe numeric ID of the message
accountNameYesThe name of the account containing the mailbox
mailboxNameYesThe name of the mailbox containing the message
attachmentNameYesThe name of the attachment to read

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the full disclosure burden. It does useful work — declaring UTF-8-only decoding, the accepted MIME/extension set, and extension-based MIME fallback — but says nothing about what happens when the type is unsupported, whether content is truncated or size-limited, or what the response looks like (no output schema exists).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences with zero filler: capability first, accepted inputs second, alternative tool last. The routing hint is placed where an agent scanning for alternatives will find it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple read tool with full schema coverage and no output schema, the description covers the essential decision inputs: what qualifies as readable and where to go otherwise. The remaining gap is error/edge-case behavior for unsupported attachments, which is minor but not trivial given there is no output schema to explain returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with all four required parameters individually documented (messageId, accountName, mailboxName, attachmentName). The description adds no parameter-level meaning such as whether attachmentName is a path, display name, or identifier, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read ... attachment text inline') plus the content constraints (valid UTF-8) that define the operation. It also explicitly names the sibling it is not ('Use save_attachment for binary files'), so an agent can separate the two without inspecting schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear routing rule: text MIME types and listed extensions go here, binary files go to save_attachment. It enumerates exactly which inputs qualify, but does not say what to do with attachments that fall in neither bucket (e.g., an unlisted text-like extension) or how to discover attachments in the first place.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

reply_to_messageA

Reply to an existing email message. Returns the sender the reply was sent from. Does not support attachments (Mail.app limitation).

NameRequiredDescriptionDefault
bodyYesThe reply body text
replyAllYesWhether to reply to all recipients (true) or just the sender (false)
messageIdYesThe numeric ID of the message to reply to
accountNameYesThe name of the account containing the mailbox. This locates the source message only — it does not control which account sends. Use fromAccount for that.
fromAccountNoAccount to send from — a Mail account name ("Google") or one of its addresses ("you@gmail.com"), as reported by list_accounts. Matching is case-insensitive and an unrecognised value is an error, never a silent fallback. Omit to use Mail's default sending account; either way the account used is returned as `sender`.
mailboxNameYesThe name of the mailbox containing the message

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden of behavior disclosure. It does disclose the returned value ('sender') and the unsupported attachment behavior, but it does not explicitly state that this sends a message as a side effect or describe the reply content/thread behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two compact sentences with high information density: the core action, the key return value, and the attachment limitation. There is no filler or redundant restating of the tool name.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The schema already covers all six parameters, and the description adds the most decision-relevant behavioral facts. It stops just short of fully complete because it does not outline the full return structure or emphasize the potentially irreversible sending side effect, and there is no output schema to fill that gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters are already well documented in the input schema. The description adds no additional parameter-level semantics, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Reply to an existing email message.' It clearly distinguishes the tool from sending a new message or forwarding by the word 'Reply' and by referencing an existing message, though it does not name sibling tools explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than explicit: it is for replying to an existing email. It also calls out a meaningful limitation, 'Does not support attachments (Mail.app limitation),' but does not explicitly say when to choose send_message or forward_message instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_all_attachmentsB

Save all downloaded attachments from a message to disk. Creates the destination directory recursively before contacting Mail.

NameRequiredDescriptionDefault
savePathNoThe directory path to save the attachments to (default ~/Downloads)~/Downloads
messageIdYesThe numeric ID of the message
accountNameYesThe name of the account containing the mailbox
mailboxNameYesThe name of the mailbox containing the message

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the full burden. It usefully discloses that the destination directory is created recursively and that this happens before contacting Mail, but it says nothing about overwrite behavior for files that already exist, what happens when a message has no attachments, or permission/error conditions.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, front-loaded with the action and free of filler. The ordering detail ('before contacting Mail') is slightly niche but does convey real behavior about partial failure, so it earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

It states the core action, the destination handling, and the mutation footprint for a 4-parameter tool with full schema coverage. The gaps are return values (output schema absent) and overwrite/duplicate handling, which would round out a write tool with no annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the schema already documents savePath with its default. The 'creates the destination directory recursively' clause adds real meaning by telling the agent that savePath need not already exist, but that is the only genuine addition beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: 'Save all downloaded attachments from a message to disk.' The word 'all' implicitly separates it from the singular save_attachment sibling, but it never names that alternative explicitly, so an agent must infer the distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use guidance at all. With siblings list_attachments, save_attachment, and read_attachment in the lineup, the definition should say when bulk-saving beats enumerating or saving one attachment, and it does not.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_attachmentA

Save a specific attachment from a message to disk. Creates the destination directory recursively before contacting Mail.

NameRequiredDescriptionDefault
savePathNoThe directory path to save the attachment to (default ~/Downloads)~/Downloads
messageIdYesThe numeric ID of the message
accountNameYesThe name of the account containing the mailbox
mailboxNameYesThe name of the mailbox containing the message
attachmentNameYesThe name of the attachment to save

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden, and it does disclose a real side effect plus ordering: the destination directory is created recursively before Mail is contacted, meaning a filesystem write can occur even if the mail operation fails. It omits equally important behavior for a disk-write tool: whether an existing file of the same name is overwritten, and what the tool returns (e.g., the resolved path).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short sentences, both front-loaded: the action first, then the side-effect ordering. Nothing is padded or repeated from the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a five-parameter tool with full schema coverage, no output schema, and no annotations, the description supplies the one non-obvious behavioral fact (recursive directory creation before the Mail call). Remaining gaps around overwrite behavior are secondary for an agent that just needs to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters, including the savePath default of ~/Downloads, are already documented in the schema. The description adds no new meaning about path semantics, filename collisions, or how attachmentName is matched, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Save a specific attachment from a message to disk" gives a concrete verb (save), a concrete resource (attachment), and a destination (disk). The word "specific" implicitly separates it from the sibling save_all_attachments, but that sibling is never named, so the differentiation is inferential rather than explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated: the agent can infer this tool is for one attachment while save_all_attachments handles bulk, but no sentence says when to pick one over the other. There is also no guidance on prerequisites, such as whether the attachment must first be listed via list_attachments.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_messagesA

Search one mailbox safely by default. Broad, content or large-mailbox searches require explicit allowSlow. Returns an object with messages and partial/timeout/skipped/error metadata within a 45 second server budget. Mail's queued Apple events can outlive process cancellation; wait or restart Mail after a timeout.

NameRequiredDescriptionDefault
afterNoInclude messages received on/after this ISO date
fieldYesField to search; content requires allowSlow and a single account/mailbox
limitNoMaximum unique results, 1–200 (default 50)
queryNoSearch text; may be empty when after or before is supplied
beforeNoInclude messages received on/before this ISO date
allowSlowNoExplicitly permit broad searches, content searches or mailboxes over 1,000 messages; queued Mail work may outlive cancellation
accountNameNoMail account; default searches require both account and mailbox
mailboxNameNoMailbox name or full path; requires accountName

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the full load and does so well: it discloses a 45-second server budget, partial/timeout/skipped/error metadata in the response, and the non-obvious side effect that queued Apple events can outlive process cancellation, including remediation ('wait or restart Mail'). These are exactly the behaviors an agent could not infer from 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences lead with the default-safe scope before the cost/constraint, which is the right front-loading. Some phrasing is compressed to the point of being cryptic ('Broad, content or large-mailbox searches'), but nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an eight-parameter, no-output-schema tool, the description covers the return envelope shape, the timeout budget, and the cancellation caveat, so an agent has enough to call it and interpret failure. It stops short of defining what counts as 'broad' (left to the schema's 1,000-message note) or describing result ordering.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all eight parameters are already documented, including the field enum and the allowSlow constraint. The description restates only the content-search constraint already present in the field and allowSlow schema entries, adding no new semantics; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Search one mailbox') and immediately scopes it to single-mailbox, default-safe operation, which separates it from a broad content sweep. It never names list_messages or get_message explicitly, so sibling differentiation is implied rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear rule for when the slow path applies: broad, content, or large-mailbox searches 'require explicit allowSlow'. That is genuine when/when-not guidance, though no alternative tool is named for the cases where this one is the wrong choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

send_messageA

Compose and send a new email message as plain text. Returns success when the message is queued for sending, along with the sender the message was sent from; actual delivery is not confirmed. Check Mail's Sent or Outbox mailbox to verify delivery.

NameRequiredDescriptionDefault
ccNoCC recipient email address (optional)
toYesThe recipient email address
bccNoBCC recipient email address (optional)
bodyYesThe plain text body of the email
subjectYesThe subject of the email
fromAccountNoAccount to send from — a Mail account name ("Google") or one of its addresses ("you@gmail.com"), as reported by list_accounts. Matching is case-insensitive and an unrecognised value is an error, never a silent fallback. Omit to use Mail's default sending account; either way the account used is returned as `sender`.
attachmentPathsNoAbsolute paths to readable regular files to attach. CR, LF and NUL in paths are unsupported; invalid files fail before composing (optional).

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the full burden and does real work: it discloses that success means 'queued for sending', that 'actual delivery is not confirmed', and how to verify via Sent or Outbox. It stops short of stating that sending is irreversible/unrecallable or what authorization the account needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the action, then the return contract, then the verification step. No filler and no repetition of the name or schema fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter mutation tool with no output schema and no annotations, the description covers the essential gaps: what a success response contains (`sender`) and that delivery is unconfirmed. Attachment and account-selection behavior is left entirely to the schema, but overall an agent has enough to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so recipient, subject, body, cc, bcc, fromAccount and attachmentPaths are already well documented in the schema, including the fromAccount fallback and error behavior. The description only adds the plain-text constraint on the body, which is a marginal addition over structured data.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb+resource pair ('Compose and send a new email message') and adds a format constraint ('as plain text'). It does not distinguish itself from siblings like reply_to_message or forward_message, which also send mail, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the description of composing a new message; there is no explicit guidance on when to use this instead of reply_to_message or forward_message, which are direct alternatives in the sibling list. The only routing hint is about verification (check Sent/Outbox), not about tool selection.

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.

  1. 3 tool updatesv3.0.0
    • Changedcreate_mailbox2 fields changed
      • changedInput schema / properties / mailboxName / description
        Previous value: -"The name of the new mailbox to create"New value: +"The child name to create, or a full slash path when parentMailboxName is omitted"
      • changedInput schema / properties / parentMailboxName / description
        Previous value: -"The name of the parent mailbox for nesting; omit for top-level"New value: +"An existing parent mailbox name or full path for nesting; omit to create directly at the account"
    • Changedsearch_messages11 fields changed
      • changedInput schema / properties / accountName / description
        Previous value: -"Limit search to a specific account (omit to search all accounts)"New value: +"Mail account; default searches require both account and mailbox"
      • changedInput schema / properties / after / description
        Previous value: -"Only return messages received after this ISO 8601 date (e.g. 2024-01-15T00:00:00Z)"New value: +"Include messages received on/after this ISO date"
      • addedInput schema / properties / allowSlow
        Added value: +{
        +  "default": false,
        +  "description": "Explicitly permit broad searches, content searches or mailboxes over 1,000 messages; queued Mail work may outlive cancellation",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / before / description
        Previous value: -"Only return messages received before this ISO 8601 date (e.g. 2024-12-31T23:59:59Z)"New value: +"Include messages received on/before this ISO date"
      • changedInput schema / properties / field / description
        Previous value: -"The field to search in"New value: +"Field to search; content requires allowSlow and a single account/mailbox"
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of results to return (default 50)"New value: +"Maximum unique results, 1–200 (default 50)"
      • removedInput schema / properties / limit / exclusiveMinimum
        Removed value: -0
      • changedInput schema / properties / limit / maximum
        Previous value: -9007199254740991New value: +200
      • addedInput schema / properties / limit / minimum
        Added value: +1
      • changedInput schema / properties / mailboxName / description
        Previous value: -"Limit search to a specific mailbox (omit to search all mailboxes)"New value: +"Mailbox name or full path; requires accountName"
      • changedInput schema / properties / query / description
        Previous value: -"The search query string (optional when using date filters)"New value: +"Search text; may be empty when after or before is supplied"
    • Changedsend_message1 field changed
      • changedInput schema / properties / attachmentPaths / description
        Previous value: -"List of absolute file paths to attach (optional)"New value: +"Absolute paths to readable regular files to attach. CR, LF and NUL in paths are unsupported; invalid files fail before composing (optional)."
  2. 19 tool updatesv1.3.2
    • Changedcreate_mailbox1 field changed
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changeddelete_message3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedflag_message5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / flagIndex / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / flagIndex / minimum
        Added value: +-9007199254740991
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedforward_message5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / accountName / description
        Previous value: -"The name of the account containing the mailbox"New value: +"The name of the account containing the mailbox. This locates the source message only — it does not control which account sends. Use fromAccount for that."
      • addedInput schema / properties / fromAccount
        Added value: +{
        +  "description": "Account to send from — a Mail account name (\"Google\") or one of its addresses (\"you@gmail.com\"), as reported by list_accounts. Matching is case-insensitive and an unrecognised value is an error, never a silent fallback. Omit to use Mail's default sending account; either way the account used is returned as `sender`.",
        +  "type": "string"
        +}
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedget_account_detail1 field changed
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedget_mailbox_info1 field changed
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedget_message3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedlist_attachments3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedlist_mailboxes1 field changed
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedlist_messages3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / limit / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / offset / maximum
        Added value: +9007199254740991
    • Changedmark_read3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedmove_message3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedmove_messages3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageIds / items / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageIds / items / minimum
        Added value: +-9007199254740991
    • Changedread_attachment3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedreply_to_message5 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • changedInput schema / properties / accountName / description
        Previous value: -"The name of the account containing the mailbox"New value: +"The name of the account containing the mailbox. This locates the source message only — it does not control which account sends. Use fromAccount for that."
      • addedInput schema / properties / fromAccount
        Added value: +{
        +  "description": "Account to send from — a Mail account name (\"Google\") or one of its addresses (\"you@gmail.com\"), as reported by list_accounts. Matching is case-insensitive and an unrecognised value is an error, never a silent fallback. Omit to use Mail's default sending account; either way the account used is returned as `sender`.",
        +  "type": "string"
        +}
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedsave_all_attachments3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedsave_attachment3 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / messageId / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / messageId / minimum
        Added value: +-9007199254740991
    • Changedsearch_messages2 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / limit / maximum
        Added value: +9007199254740991
    • Changedsend_message2 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / fromAccount
        Added value: +{
        +  "description": "Account to send from — a Mail account name (\"Google\") or one of its addresses (\"you@gmail.com\"), as reported by list_accounts. Matching is case-insensitive and an unrecognised value is an error, never a silent fallback. Omit to use Mail's default sending account; either way the account used is returned as `sender`.",
        +  "type": "string"
        +}
  3. 20 tool updatesv1.2.0
    • First observedcreate_mailbox
    • First observeddelete_message
    • First observedflag_message
    • First observedforward_message
    • First observedget_account_detail
    • First observedget_mailbox_info
    • First observedget_message
    • First observedlist_accounts
    • First observedlist_attachments
    • First observedlist_mailboxes
    • First observedlist_messages
    • First observedmark_read
    • First observedmove_message
    • First observedmove_messages
    • First observedread_attachment
    • First observedreply_to_message
    • First observedsave_all_attachments
    • First observedsave_attachment
    • First observedsearch_messages
    • First observedsend_message

TDQS

A3.6/5.0

Scored across 20 tools

Disambiguation4/5

Each tool targets a distinct resource+action, and singular/plural pairs (move_message vs move_messages, save_attachment vs save_all_attachments) are clearly differentiated by their descriptions. The only real overlap is list_messages versus search_messages (and get_message's fallback that scans all mailboxes), which could occasionally cause misselection when an agent just wants to find a message.

Naming Consistency4/5

Nearly everything follows a predictable snake_case verb_noun pattern (list_accounts, get_message, move_message, save_attachment, reply_to_message). The one deviation is mark_read, which uses verb_adjective rather than verb_noun, though its meaning remains obvious.

Tool Count4/5

20 tools is on the heavy side of the typical 3-15 band, but for a full email client each tool maps to a real operation (account, mailbox, message, attachment, and compose surfaces). Nothing looks redundant enough to cut outright, so the surface is scoped reasonably.

Completeness3/5

Message lifecycle is well covered (list, search, get, send, reply, forward, move, flag, mark_read, delete) along with attachment handling. However, the mailbox lifecycle is partial — create_mailbox exists with no delete_mailbox or rename_mailbox — and there is no draft/update-message support or batch flag/delete, leaving notable dead ends for common workflows.

Maintenance

ActivityNo data
ResponsivenessOutdated data

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    MCP server that gives Claude and other MCP hosts full access to Mail.app on macOS — search, read, send, reply, flag, move, and more across all accounts configured in Mail.app.
    24
    115 npm
    1
    MIT
  • A
    license
    B
    quality
    D
    maintenance
    MCP server that connects Claude to iCloud Mail, enabling reading, searching, sending, and organizing emails via IMAP/SMTP.
    14
    PolyForm Noncommercial 1.0.0
  • A
    license
    A
    quality
    D
    maintenance
    A read-only MCP server that lets Claude Desktop interact with Apple Mail on macOS via AppleScript. It enables listing mailboxes, searching emails, and reading email content without making network calls.
    3
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    An MCP server that provides programmatic access to Apple Mail, enabling AI assistants like Claude to read, send, search, and manage emails on macOS.
    25
    MIT