Skip to main content
Glama
apple-mail-mcp

apple-mail-mcp

by sweetrb

create-draft

Compose a reviewable email draft in Apple Mail with recipients, body, attachments, and optional threading, without sending it; the user sends it manually.

Instructions

Use when: composing an email the user should review in Mail.app before sending — the safe default for any new message (to/cc/bcc are arrays, optional attachments). With inReplyTo/references the draft is threaded: it is composed by this server and filed over IMAP into the account's Drafts mailbox (Mail.app's AppleScript cannot set those headers), so an IMAP account is required. Returns: a confirmation that the draft was created, with recipients and attachment count; for a threaded draft also its Drafts mailbox, account and Message-ID (transport: imap). Do not use when: the user has already confirmed they want it sent now (use send-email), or is replying to an existing message (use reply-to-message with send=false — it derives recipients, threading and the quote and takes attachments). Safety: low risk — creates a draft only and sends nothing; the user must open Mail.app and send it themselves.

Input Schema

NameRequiredDescriptionDefault
ccNoCC recipients
toYes
bccNoBCC recipients
bodyYes
accountNoAccount to create draft in: a Mail account name or an exact sender address, resolved and verified before the draft is saved (no match or a different sender → error, no draft). With inReplyTo/references this must name a configured IMAP account (label or login); when omitted, the IMAP account matching the SMTP identity, else the only IMAP account, is used.
subjectYes
inReplyToNoThread this message as a reply: the parent's Message-ID token, angle brackets included (e.g. '<abc123@mail.example.com>'). Emitted verbatim as In-Reply-To, never RFC 2047-encoded. When `references` is omitted, References defaults to [inReplyTo]. Prefer reply-to-message, which derives recipients, threading and the quote from the original for you.
referencesNoThread chain, oldest first: the parent's own References followed by the parent's Message-ID (each an angle-bracketed token). Emitted verbatim, never RFC 2047-encoded.
attachmentsNoFiles to attach: absolute paths in the configured attachment read roots (e.g. '/Users/me/Documents/report.pdf') and/or inline {filename, contentBase64} objects up to 25 MiB decoded each.
compositionNoOpt in to Mail's visible native editor: inserts only new prose, preserving its signature, HTML quotation and reply ancestry without the AppleScript content setter. Requires an unlocked desktop and existing Accessibility and Automation permissions. Uses Mail.app even when SMTP is configured; cannot be combined with transport=smtp or caller-built threading headers. New messages require an explicit account. Do not interact with Mail or the clipboard while it runs. Failure never falls back to another composition method or sends an unverified message.

Output Schema

NameRequiredDescriptionDefault
okNo
fromNoAppleScript draft: the sender Mail.app used
accountNoThreaded draft only: IMAP account it was filed in
mailboxNoThreaded draft only: Drafts mailbox path
inReplyToNo
messageIdNoThreaded draft only: the draft's Message-ID
transportNo
recipientsNo
referencesNo
attachmentCountNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv2.20.39
    • addedInput schema / properties / composition
      Added value: +{
      +  "const": "native-editor",
      +  "description": "Opt in to Mail's visible native editor: inserts only new prose, preserving its signature, HTML quotation and reply ancestry without the AppleScript content setter. Requires an unlocked desktop and existing Accessibility and Automation permissions. Uses Mail.app even when SMTP is configured; cannot be combined with transport=smtp or caller-built threading headers. New messages require an explicit account. Do not interact with Mail or the clipboard while it runs. Failure never falls back to another composition method or sends an unverified message.",
      +  "type": "string"
      +}
  2. Changed5 schema fields changedv2.20.29
    • removedInput schema / properties / references / items / $ref
      Removed value: -"#/properties/inReplyTo"
    • addedInput schema / properties / references / items / description
      Added value: +"Thread this message as a reply: the parent's Message-ID token, angle brackets included (e.g. '<abc123@mail.example.com>'). Emitted verbatim as In-Reply-To, never RFC 2047-encoded. When `references` is omitted, References defaults to [inReplyTo]. Prefer reply-to-message, which derives recipients, threading and the quote from the original for you."
    • addedInput schema / properties / references / items / maxLength
      Added value: +998
    • addedInput schema / properties / references / items / pattern
      Added value: +"^<[^<>\\s@]+@[^<>\\s@]+>$"
    • addedInput schema / properties / references / items / type
      Added value: +"string"
  3. Changed2 schema fields changedv2.20.16
    • changedInput schema / properties / account / description
      Previous value: -"Account to create draft in. With inReplyTo/references this must name a configured IMAP account (label or login); when omitted, the IMAP account matching the SMTP identity, else the only IMAP account, is used."New value: +"Account to create draft in: a Mail account name or an exact sender address, resolved and verified before the draft is saved (no match or a different sender → error, no draft). With inReplyTo/references this must name a configured IMAP account (label or login); when omitted, the IMAP account matching the SMTP identity, else the only IMAP account, is used."
    • addedOutput schema / properties / from
      Added value: +{
      +  "description": "AppleScript draft: the sender Mail.app used",
      +  "type": "string"
      +}
  4. Changed9 schema fields changedv2.20.11
    • changedInput schema / properties / account / description
      Previous value: -"Account to create draft in"New value: +"Account to create draft in. With inReplyTo/references this must name a configured IMAP account (label or login); when omitted, the IMAP account matching the SMTP identity, else the only IMAP account, is used."
    • addedInput schema / properties / inReplyTo
      Added value: +{
      +  "description": "Thread this message as a reply: the parent's Message-ID token, angle brackets included (e.g. '<abc123@mail.example.com>'). Emitted verbatim as In-Reply-To, never RFC 2047-encoded. When `references` is omitted, References defaults to [inReplyTo]. Prefer reply-to-message, which derives recipients, threading and the quote from the original for you.",
      +  "maxLength": 998,
      +  "pattern": "^<[^<>\\s@]+@[^<>\\s@]+>$",
      +  "type": "string"
      +}
    • addedInput schema / properties / references
      Added value: +{
      +  "description": "Thread chain, oldest first: the parent's own References followed by the parent's Message-ID (each an angle-bracketed token). Emitted verbatim, never RFC 2047-encoded.",
      +  "items": {
      +    "$ref": "#/properties/inReplyTo"
      +  },
      +  "maxItems": 100,
      +  "minItems": 1,
      +  "type": "array"
      +}
    • addedOutput schema / properties / account
      Added value: +{
      +  "description": "Threaded draft only: IMAP account it was filed in",
      +  "type": "string"
      +}
    • addedOutput schema / properties / inReplyTo
      Added value: +{
      +  "type": "string"
      +}
    • addedOutput schema / properties / mailbox
      Added value: +{
      +  "description": "Threaded draft only: Drafts mailbox path",
      +  "type": "string"
      +}
    • addedOutput schema / properties / messageId
      Added value: +{
      +  "description": "Threaded draft only: the draft's Message-ID",
      +  "type": "string"
      +}
    • addedOutput schema / properties / references
      Added value: +{
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / transport
      Added value: +{
      +  "enum": [
      +    "applescript",
      +    "imap"
      +  ],
      +  "type": "string"
      +}
  5. Changed2 schema fields changedv2.16.1
    • changedInput schema / properties / attachments / description
      Previous value: -"Files to attach: absolute paths (e.g. '/Users/me/report.pdf') and/or inline {filename, contentBase64} objects up to 25 MiB decoded each."New value: +"Files to attach: absolute paths in the configured attachment read roots (e.g. '/Users/me/Documents/report.pdf') and/or inline {filename, contentBase64} objects up to 25 MiB decoded each."
    • changedInput schema / properties / attachments / items / anyOf
      Previous value: -[
      -  {
      -    "description": "Absolute path to an existing file",
      -    "type": "string"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentBase64": {
      -        "description": "Base64-encoded file content (maximum 25 MiB decoded)",
      -        "maxLength": 69905072,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "filename": {
      -        "description": "Filename to give the attachment",
      -        "maxLength": 255,
      -        "minLength": 1,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "filename",
      -      "contentBase64"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "description": "Absolute path to an existing file in an allowed read root",
      +    "type": "string"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentBase64": {
      +        "description": "Base64-encoded file content (maximum 25 MiB decoded)",
      +        "maxLength": 69905072,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "filename": {
      +        "description": "Filename to give the attachment",
      +        "maxLength": 255,
      +        "minLength": 1,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "filename",
      +      "contentBase64"
      +    ],
      +    "type": "object"
      +  }
      +]
  6. Changed2 schema fields changedv2.10.24
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • changedOutput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  7. Changed1 schema field changedv2.10.8
    • changedOutput schema / additionalProperties
      Previous value: -falseNew value: +true
  8. Addedv2.8.14
  9. Removedv2.8.10
  10. First observedv2.6.1

TDQS

A4.8/5.0
Behavior5/5

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

No annotations exist, so the description carries the full burden and does so well: it discloses that a threaded draft is filed over IMAP and therefore needs an IMAP account, that the AppleScript path cannot set those headers, the transport used, the required desktop/permission state for composition, and that failure never falls back or sends an unverified message. It also states the risk profile directly ('creates a draft only and sends nothing').

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?

Labeled sections (Use when / Returns / Do not use when / Safety) front-load the decision-relevant content. The sentences are dense and the Returns clause is somewhat verbose, but no sentence is wasted given the tool's complexity.

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 10-parameter mutation-adjacent tool with no annotations, the description covers purpose, alternatives, the IMAP threading constraint, permissions, failure semantics and a return summary. Even with an output schema present, the brief return description orients the caller correctly.

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 70%, and the description adds real meaning on top: recipient fields are arrays, attachments are optional, inReplyTo/references cause the draft to be threaded via IMAP rather than AppleScript, and account must name a configured IMAP account in that case. It does not cover every parameter (composition, attachment limits) in prose, but the schema documents those well.

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 ('composing an email the user should review in Mail.app before sending') and frames it as the safe default for new messages. It is immediately distinguishable from send-email and reply-to-message, which are named as the alternatives.

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

Usage Guidelines5/5

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

Explicit 'Use when' and 'Do not use when' clauses name both competing tools and the exact condition that selects each ('user has already confirmed they want it sent now' → send-email; 'replying to an existing message' → reply-to-message with send=false). It even explains why reply-to-message is preferable (derives recipients, threading and quote).

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