{
  "schema_version": 1,
  "server": {
    "name": "sendhq",
    "command": "sendhq mcp",
    "transport": "stdio"
  },
  "excluded": [
    {
      "capability": "Create, rotate, revoke, or delete API keys",
      "endpoints": [
        "POST /keys",
        "DELETE /keys/:id"
      ],
      "reason": "Deliberately excluded: an agent must not mint or destroy credentials. Keys are managed by a human in the dashboard."
    },
    {
      "capability": "Start a checkout or cancel a subscription",
      "endpoints": [
        "POST /billing/checkout",
        "POST /billing/cancel"
      ],
      "reason": "Billing changes are session-only by design and require the account owner in the dashboard. Billing state is readable with get_account."
    },
    {
      "capability": "Cloudflare one-click DNS (OAuth)",
      "endpoints": [
        "GET /api/dns/cloudflare/connect"
      ],
      "reason": "Requires an interactive browser session and Cloudflare OAuth consent. Use get_domain records, get_dns_provider hosts, or get_domain_connect_link instead."
    },
    {
      "capability": "Sign up, log in, log out, Google account linking",
      "endpoints": [
        "/api/auth/*"
      ],
      "reason": "Human browser authentication; the MCP server authenticates with an API key."
    },
    {
      "capability": "Contact support form",
      "endpoints": [
        "POST /api/contact"
      ],
      "reason": "Public marketing-site form for humans, not a workspace operation."
    }
  ],
  "tools": [
    {
      "name": "send_email",
      "title": "Send one email",
      "group": "emails",
      "description": "SENDS REAL EMAIL. Send one message from a verified domain: raw html/text, a published hosted template, a reply in an existing thread, or a message with attachments. Pass `idempotency_key` so a retry cannot send twice; a retry must reuse the same key AND an identical request, otherwise SendHQ returns 409. `attachments` is a convenience that creates a draft, uploads each file, and sends with that draft; it cannot be combined with `idempotency_key` or `draft_id` (use create_draft + upload_attachment + send_email with draft_id for retry-safe attachment sends). Unpaid workspaces (integration trial) can deliver only to the account email or an AWS SES simulator address, and cannot send attachments.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": true,
        "title": "Send one email"
      },
      "sends_email": true,
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Sender, e.g. `Acme <hello@example.com>`. The domain must be verified in this workspace (see list_sending_identities).",
            "minLength": 3,
            "maxLength": 998
          },
          "to": {
            "type": "array",
            "description": "Recipients. Each entry is an address, optionally with a display name. To+cc+bcc may total at most 100; every destination consumes one delivery credit.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 1,
            "maxItems": 100
          },
          "cc": {
            "type": "array",
            "description": "Carbon-copy recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 0,
            "maxItems": 100
          },
          "bcc": {
            "type": "array",
            "description": "Blind-copy recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 0,
            "maxItems": 100
          },
          "subject": {
            "type": "string",
            "description": "Subject line. Omit when sending a template.",
            "maxLength": 998
          },
          "text": {
            "type": "string",
            "description": "Plain-text body. Provide text, html, or template."
          },
          "html": {
            "type": "string",
            "description": "HTML body. SendHQ sanitizes it and derives text when `text` is omitted."
          },
          "reply_to": {
            "type": "string",
            "description": "Reply-To address."
          },
          "headers": {
            "type": "object",
            "description": "Extra safe custom headers (string values), e.g. {\"X-Entity-Ref-ID\": \"123\"}. Routing headers such as From/To/Message-ID are controlled by SendHQ.",
            "additionalProperties": {
              "type": "string"
            }
          },
          "message_class": {
            "type": "string",
            "description": "`transactional` (default) or `marketing`. Marketing requires a marketing-enabled plan or domain and adds unsubscribe handling.",
            "enum": [
              "transactional",
              "marketing"
            ]
          },
          "reply_to_email_id": {
            "type": "string",
            "description": "Reply inside an existing conversation: the `em_…` ID of the message being answered. SendHQ sets In-Reply-To/References and the thread."
          },
          "thread_id": {
            "type": "string",
            "description": "Explicit thread ID to file the message under."
          },
          "draft_id": {
            "type": "string",
            "description": "Send a stored draft's attachments with this message (`dr_…`). The draft is deleted after a successful send."
          },
          "template": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "description": "Template ID (`tmpl_…`). Provide `id` or `key`."
              },
              "key": {
                "type": "string",
                "description": "Template key such as `account-welcome`. Provide `id` or `key`."
              },
              "version_id": {
                "type": "string",
                "description": "Optional published release ID (`tmplv_…`). Defaults to the current published release."
              },
              "data": {
                "type": "object",
                "description": "Values for the template's typed variables.",
                "additionalProperties": true
              }
            },
            "additionalProperties": false,
            "anyOf": [
              {
                "required": [
                  "id"
                ]
              },
              {
                "required": [
                  "key"
                ]
              }
            ],
            "description": "Send a published hosted template instead of raw html/text. Requires exactly one `to` recipient and no cc/bcc; the template supplies the subject."
          },
          "labels": {
            "type": "array",
            "description": "Label names or `lbl_…` IDs to file this message under. Unknown names are created. Replies in the conversation inherit the labels, and a bucket label (`skip_inbox`) keeps those replies out of the Inbox. Max 10.",
            "maxItems": 10,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "idempotency_key": {
            "type": "string",
            "description": "Idempotency-Key header (max 200 chars). Reuse it only to retry this exact request.",
            "minLength": 1,
            "maxLength": 200
          },
          "attachments": {
            "type": "array",
            "maxItems": 10,
            "description": "Files to attach (max 10 files, 10 MB total). Each needs `content_base64` (plus `filename`) or a local `file_path`.",
            "items": {
              "type": "object",
              "properties": {
                "filename": {
                  "type": "string",
                  "description": "File name shown to the recipient. Required with content_base64; defaults to the basename of file_path.",
                  "minLength": 1,
                  "maxLength": 255
                },
                "content_type": {
                  "type": "string",
                  "description": "MIME type, e.g. `application/pdf`. Defaults to `application/octet-stream`."
                },
                "content_base64": {
                  "type": "string",
                  "description": "Standard base64 file content."
                },
                "file_path": {
                  "type": "string",
                  "description": "Absolute path of a local file readable by the MCP server process."
                }
              },
              "additionalProperties": false,
              "anyOf": [
                {
                  "required": [
                    "content_base64"
                  ]
                },
                {
                  "required": [
                    "file_path"
                  ]
                }
              ]
            }
          }
        },
        "additionalProperties": false,
        "required": [
          "from",
          "to"
        ],
        "anyOf": [
          {
            "required": [
              "html"
            ]
          },
          {
            "required": [
              "text"
            ]
          },
          {
            "required": [
              "template"
            ]
          }
        ]
      },
      "returns": "{id: `em_…`, providerMessageId, threadId, templateId, templateVersionId, isTest}. Acceptance is not delivery: follow up with list_email_events.",
      "example": {
        "from": "Acme <hello@example.com>",
        "to": [
          "owner@example.com"
        ],
        "subject": "Your export is ready",
        "text": "Download it from your dashboard.",
        "idempotency_key": "export-ready-42"
      },
      "http": {
        "method": "POST",
        "path": "/emails",
        "body": "args",
        "idempotency": true
      },
      "handler": "send_email"
    },
    {
      "name": "send_batch",
      "title": "Send a batch of individualized emails",
      "group": "emails",
      "description": "SENDS REAL EMAIL. Send 1–100 independent messages in one request (use this for per-recipient template personalization). Each item has the same shape as send_email (without attachments/idempotency_key). Items succeed or fail individually: HTTP 207 means partial success; inspect each `data[i].ok` and `data[i].error`. One `idempotency_key` covers the whole batch body.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": true,
        "title": "Send a batch of individualized emails"
      },
      "sends_email": true,
      "inputSchema": {
        "type": "object",
        "properties": {
          "emails": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "type": "object",
              "properties": {
                "from": {
                  "type": "string",
                  "description": "Sender, e.g. `Acme <hello@example.com>`. The domain must be verified in this workspace (see list_sending_identities).",
                  "minLength": 3,
                  "maxLength": 998
                },
                "to": {
                  "type": "array",
                  "description": "Recipients. Each entry is an address, optionally with a display name. To+cc+bcc may total at most 100; every destination consumes one delivery credit.",
                  "items": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320
                  },
                  "minItems": 1,
                  "maxItems": 100
                },
                "cc": {
                  "type": "array",
                  "description": "Carbon-copy recipients.",
                  "items": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320
                  },
                  "minItems": 0,
                  "maxItems": 100
                },
                "bcc": {
                  "type": "array",
                  "description": "Blind-copy recipients.",
                  "items": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320
                  },
                  "minItems": 0,
                  "maxItems": 100
                },
                "subject": {
                  "type": "string",
                  "description": "Subject line. Omit when sending a template.",
                  "maxLength": 998
                },
                "text": {
                  "type": "string",
                  "description": "Plain-text body. Provide text, html, or template."
                },
                "html": {
                  "type": "string",
                  "description": "HTML body. SendHQ sanitizes it and derives text when `text` is omitted."
                },
                "reply_to": {
                  "type": "string",
                  "description": "Reply-To address."
                },
                "headers": {
                  "type": "object",
                  "description": "Extra safe custom headers (string values), e.g. {\"X-Entity-Ref-ID\": \"123\"}. Routing headers such as From/To/Message-ID are controlled by SendHQ.",
                  "additionalProperties": {
                    "type": "string"
                  }
                },
                "message_class": {
                  "type": "string",
                  "description": "`transactional` (default) or `marketing`. Marketing requires a marketing-enabled plan or domain and adds unsubscribe handling.",
                  "enum": [
                    "transactional",
                    "marketing"
                  ]
                },
                "reply_to_email_id": {
                  "type": "string",
                  "description": "Reply inside an existing conversation: the `em_…` ID of the message being answered. SendHQ sets In-Reply-To/References and the thread."
                },
                "thread_id": {
                  "type": "string",
                  "description": "Explicit thread ID to file the message under."
                },
                "draft_id": {
                  "type": "string",
                  "description": "Send a stored draft's attachments with this message (`dr_…`). The draft is deleted after a successful send."
                },
                "template": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Template ID (`tmpl_…`). Provide `id` or `key`."
                    },
                    "key": {
                      "type": "string",
                      "description": "Template key such as `account-welcome`. Provide `id` or `key`."
                    },
                    "version_id": {
                      "type": "string",
                      "description": "Optional published release ID (`tmplv_…`). Defaults to the current published release."
                    },
                    "data": {
                      "type": "object",
                      "description": "Values for the template's typed variables.",
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": false,
                  "anyOf": [
                    {
                      "required": [
                        "id"
                      ]
                    },
                    {
                      "required": [
                        "key"
                      ]
                    }
                  ],
                  "description": "Send a published hosted template instead of raw html/text. Requires exactly one `to` recipient and no cc/bcc; the template supplies the subject."
                },
                "labels": {
                  "type": "array",
                  "description": "Label names or `lbl_…` IDs to file this message under. Unknown names are created. Replies in the conversation inherit the labels, and a bucket label (`skip_inbox`) keeps those replies out of the Inbox. Max 10.",
                  "maxItems": 10,
                  "items": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 64
                  }
                }
              },
              "additionalProperties": false,
              "required": [
                "from",
                "to"
              ],
              "anyOf": [
                {
                  "required": [
                    "html"
                  ]
                },
                {
                  "required": [
                    "text"
                  ]
                },
                {
                  "required": [
                    "template"
                  ]
                }
              ]
            },
            "description": "Messages to send."
          },
          "idempotency_key": {
            "type": "string",
            "description": "Idempotency-Key for the entire batch (max 200 chars).",
            "minLength": 1,
            "maxLength": 200
          }
        },
        "additionalProperties": false,
        "required": [
          "emails"
        ]
      },
      "returns": "{data: [{index, ok, id?, error?: {message, status}}], count, successful, failed}.",
      "example": {
        "emails": [
          {
            "from": "Acme <hello@example.com>",
            "to": [
              "owner@example.com"
            ],
            "template": {
              "key": "account-welcome",
              "data": {
                "first_name": "Asha"
              }
            }
          }
        ],
        "idempotency_key": "welcome-batch-2026-09-26"
      },
      "http": {
        "method": "POST",
        "path": "/emails/batch",
        "body": [
          "emails"
        ],
        "idempotency": true
      }
    },
    {
      "name": "list_emails",
      "title": "List and search email",
      "group": "emails",
      "description": "List sent (`direction: out`) and received (`direction: in`) email newest-first with filters. Received mail is classified: read the human inbox with `direction: in`, `archived: false`, `category: primary`; triage with `important: true`; spam is hidden unless `category: spam` or `include_spam: true`. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List and search email"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "direction": {
            "type": "string",
            "description": "`in` for received, `out` for sent.",
            "enum": [
              "in",
              "out"
            ]
          },
          "status": {
            "type": "string",
            "description": "Status filter, e.g. `queued`, `sent`, `delivered`, `bounced`, `complained`, `failed`."
          },
          "domain": {
            "type": "string",
            "description": "Only messages for this domain, or a comma-separated list of domains (matches any)."
          },
          "inbox_id": {
            "type": "string",
            "description": "Only messages received by this inbox (`inb_…`)."
          },
          "label": {
            "type": "string",
            "description": "Only messages carrying this label: a label ID `lbl_…` or exact name, or a comma-separated list (matches any). Use list_labels to see folders."
          },
          "archived": {
            "type": "boolean",
            "description": "false = the Inbox view (received mail not archived), true = archived only. Omit for all mail."
          },
          "category": {
            "type": "string",
            "description": "`primary` (people), `updates` (newsletters, bulk, automated), or `spam`; or a comma-separated list. Spam is hidden unless requested."
          },
          "important": {
            "type": "boolean",
            "description": "true = only messages flagged important (replies to conversations you started, and senders marked important)."
          },
          "include_spam": {
            "type": "boolean",
            "description": "Include spam in the results (for searches across every folder)."
          },
          "from": {
            "type": "string",
            "description": "Sender address contains this value."
          },
          "to": {
            "type": "string",
            "description": "Recipient address contains this value."
          },
          "unread": {
            "type": "boolean",
            "description": "true = unread only, false = read only."
          },
          "after": {
            "type": "string",
            "description": "ISO-8601 timestamp; only messages created after it.",
            "format": "date-time"
          },
          "before": {
            "type": "string",
            "description": "ISO-8601 timestamp; only messages created before it.",
            "format": "date-time"
          },
          "query": {
            "type": "string",
            "description": "Free-text search over subjects, bodies, sender/recipient addresses, and attachment filenames.",
            "maxLength": 200
          },
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [email summaries], count, pagination}.",
      "example": {
        "direction": "in",
        "unread": true,
        "limit": 25
      },
      "http": {
        "method": "GET",
        "path": "/emails",
        "query": [
          "direction",
          "status",
          "domain",
          "inbox_id",
          "label",
          "archived",
          "category",
          "important",
          "include_spam",
          "from",
          "to",
          "unread",
          "after",
          "before",
          "query",
          "limit",
          "offset"
        ],
        "pagination": "server"
      }
    },
    {
      "name": "get_email",
      "title": "Get one email",
      "group": "emails",
      "description": "Retrieve one message with headers, html/text body, status, thread metadata, and attachment metadata (download bytes with download_attachment).",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get one email"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "email_id": {
            "type": "string",
            "description": "Email ID (starts with `em_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "email_id"
        ]
      },
      "returns": "Email object: {id, direction, status, from, to, cc, bcc, subject, html, text, threadId, messageId, providerMessageId, readAt, createdAt, attachments: [{id, filename, contentType, sizeBytes, available}]}.",
      "example": {
        "email_id": "em_123"
      },
      "http": {
        "method": "GET",
        "path": "/emails/{email_id}"
      }
    },
    {
      "name": "mark_email",
      "title": "Mark read, archived, spam, or important",
      "group": "emails",
      "description": "Update one message: `read`, `archived`, `category` (`primary`, `updates`, `spam`; received mail only), and `important`. Reporting spam or marking important teaches SendHQ about that sender for future mail; pass `learn: false` to change only this message. Pass at least one field.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Mark read, archived, spam, or important"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "email_id": {
            "type": "string",
            "description": "Email ID (starts with `em_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "read": {
            "type": "boolean",
            "description": "true = read, false = unread."
          },
          "archived": {
            "type": "boolean",
            "description": "true = archive (skip the Inbox), false = move back to the Inbox."
          },
          "category": {
            "type": "string",
            "enum": [
              "primary",
              "updates",
              "spam"
            ],
            "description": "Move a received message to primary, updates, or spam."
          },
          "important": {
            "type": "boolean",
            "description": "Flag or unflag the message as important."
          },
          "learn": {
            "type": "boolean",
            "description": "false = do not remember this verdict for the sender (default true)."
          }
        },
        "additionalProperties": false,
        "required": [
          "email_id"
        ]
      },
      "returns": "The updated email object.",
      "example": {
        "email_id": "em_123",
        "read": true
      },
      "http": {
        "method": "PATCH",
        "path": "/emails/{email_id}",
        "body": [
          "read",
          "archived",
          "category",
          "important",
          "learn"
        ]
      }
    },
    {
      "name": "delete_email",
      "title": "Delete an email",
      "group": "emails",
      "description": "DESTRUCTIVE: permanently delete a retained message and its stored attachments from SendHQ. It does not recall a message that was already delivered.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Delete an email"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "email_id": {
            "type": "string",
            "description": "Email ID (starts with `em_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "email_id"
        ]
      },
      "returns": "{ok: true}.",
      "example": {
        "email_id": "em_123"
      },
      "http": {
        "method": "DELETE",
        "path": "/emails/{email_id}"
      }
    },
    {
      "name": "list_email_events",
      "title": "List delivery events for an email",
      "group": "emails",
      "description": "Provider events for one sent message: delivery, bounce, complaint, reject, open, click. This is the evidence for whether a message was delivered or why it failed. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List delivery events for an email"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "email_id": {
            "type": "string",
            "description": "Email ID (starts with `em_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false,
        "required": [
          "email_id"
        ]
      },
      "returns": "{data: [{event_type, recipient, reason, created_at, …}], count, pagination}.",
      "example": {
        "email_id": "em_123"
      },
      "http": {
        "method": "GET",
        "path": "/emails/{email_id}/events",
        "pagination": "client"
      }
    },
    {
      "name": "get_thread",
      "title": "Get a conversation",
      "group": "emails",
      "description": "Retrieve every message in a conversation in chronological order (sent and received), each with attachment metadata.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get a conversation"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "thread_id": {
            "type": "string",
            "description": "Thread ID (usually the `em_…` ID of the first message; see `threadId` on any email).",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "thread_id"
        ]
      },
      "returns": "{id, subject, data: [emails]}.",
      "example": {
        "thread_id": "em_123"
      },
      "http": {
        "method": "GET",
        "path": "/threads/{thread_id}"
      }
    },
    {
      "name": "list_labels",
      "title": "List labels",
      "group": "labels",
      "description": "List the workspace's labels (folders) with total and unread counts and their auto-filing rules. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List labels"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [{id, name, color, totalCount, unreadCount, rules: [...]}], count, pagination}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/labels",
        "pagination": "client"
      }
    },
    {
      "name": "get_label",
      "title": "Get a label",
      "group": "labels",
      "description": "Retrieve one label with counts and auto-filing rules.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get a label"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "label_id": {
            "type": "string",
            "description": "Label ID (starts with `lbl_`) or the exact label name.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "label_id"
        ]
      },
      "returns": "Label object.",
      "example": {
        "label_id": "Billing"
      },
      "http": {
        "method": "GET",
        "path": "/labels/{label_id}"
      }
    },
    {
      "name": "create_label",
      "title": "Create a label",
      "group": "labels",
      "description": "Create a folder-style label. Set `skip_inbox: true` to make it a bucket an agent owns: send with `labels: [name]` and the replies are filed into the label and kept out of the Inbox. Optional auto-filing rules file new sent/received mail (every condition on a rule must match). Set `apply_to_existing` to also file retained mail.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Create a label"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Label name, e.g. `Billing` or `Clients/Acme`. Unique per workspace (case-insensitive).",
            "minLength": 1,
            "maxLength": 64
          },
          "color": {
            "type": "string",
            "description": "Hex color such as `#1a73e8`. Optional."
          },
          "skip_inbox": {
            "type": "boolean",
            "description": "Bucket mode: received mail that gets this label (by rule, by replying to a conversation sent with this label, or by hand) is archived so it appears only in the label, not the Inbox."
          },
          "rules": {
            "type": "array",
            "description": "Optional auto-filing rules (max 20). Each needs at least one of inbox_id, from, to, subject.",
            "maxItems": 20,
            "items": {
              "type": "object",
              "properties": {
                "direction": {
                  "type": "string",
                  "description": "Only `in` (received) or `out` (sent) mail. Omit for both.",
                  "enum": [
                    "in",
                    "out"
                  ]
                },
                "inbox_id": {
                  "type": "string",
                  "description": "Only mail received by this inbox (`inb_…`). Files each receiving address into its own folder."
                },
                "from": {
                  "type": "string",
                  "description": "Sender contains this text (case-insensitive), e.g. `@stripe.com`.",
                  "maxLength": 200
                },
                "to": {
                  "type": "string",
                  "description": "To/Cc contains this text (case-insensitive).",
                  "maxLength": 200
                },
                "subject": {
                  "type": "string",
                  "description": "Subject contains this text (case-insensitive).",
                  "maxLength": 200
                },
                "skip_inbox": {
                  "type": "boolean",
                  "description": "Archive matching received mail so it appears only in the label folder, not the Inbox."
                }
              },
              "additionalProperties": false
            }
          },
          "apply_to_existing": {
            "type": "boolean",
            "description": "Also file already-retained mail that matches the rules."
          }
        },
        "additionalProperties": false,
        "required": [
          "name"
        ]
      },
      "returns": "The created label with rules.",
      "example": {
        "name": "Agent/Orders",
        "skip_inbox": true,
        "rules": [
          {
            "from": "@stripe.com"
          }
        ]
      },
      "http": {
        "method": "POST",
        "path": "/labels",
        "body": [
          "name",
          "color",
          "skip_inbox",
          "rules",
          "apply_to_existing"
        ]
      }
    },
    {
      "name": "update_label",
      "title": "Rename, recolor, or bucket a label",
      "group": "labels",
      "description": "Rename a label, change its color, or toggle bucket mode (`skip_inbox`). Turning bucket mode on archives received mail already in the label.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Rename, recolor, or bucket a label"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "label_id": {
            "type": "string",
            "description": "Label ID (starts with `lbl_`) or the exact label name.",
            "minLength": 1,
            "maxLength": 128
          },
          "name": {
            "type": "string",
            "description": "New name.",
            "minLength": 1,
            "maxLength": 64
          },
          "color": {
            "type": "string",
            "description": "New hex color."
          },
          "skip_inbox": {
            "type": "boolean",
            "description": "Bucket mode: received mail that gets this label (by rule, by replying to a conversation sent with this label, or by hand) is archived so it appears only in the label, not the Inbox."
          }
        },
        "additionalProperties": false,
        "required": [
          "label_id"
        ]
      },
      "returns": "Updated label.",
      "example": {
        "label_id": "lbl_123",
        "name": "Finance/Billing"
      },
      "http": {
        "method": "PATCH",
        "path": "/labels/{label_id}",
        "body": [
          "name",
          "color",
          "skip_inbox"
        ]
      }
    },
    {
      "name": "delete_label",
      "title": "Delete a label",
      "group": "labels",
      "description": "DESTRUCTIVE: delete a label and its rules. The email itself is kept; it only loses this label.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Delete a label"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "label_id": {
            "type": "string",
            "description": "Label ID (starts with `lbl_`) or the exact label name.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "label_id"
        ]
      },
      "returns": "{ok: true}.",
      "example": {
        "label_id": "lbl_123"
      },
      "http": {
        "method": "DELETE",
        "path": "/labels/{label_id}"
      }
    },
    {
      "name": "create_label_rule",
      "title": "Add an auto-filing rule",
      "group": "labels",
      "description": "Add a rule to a label so matching new mail is filed automatically. Every condition you set must match. Use `inbox_id` to give a receiving address its own folder; add `skip_inbox` to keep it out of the Inbox.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Add an auto-filing rule"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "label_id": {
            "type": "string",
            "description": "Label ID (starts with `lbl_`) or the exact label name.",
            "minLength": 1,
            "maxLength": 128
          },
          "direction": {
            "type": "string",
            "description": "Only `in` (received) or `out` (sent) mail. Omit for both.",
            "enum": [
              "in",
              "out"
            ]
          },
          "inbox_id": {
            "type": "string",
            "description": "Only mail received by this inbox (`inb_…`). Files each receiving address into its own folder."
          },
          "from": {
            "type": "string",
            "description": "Sender contains this text (case-insensitive), e.g. `@stripe.com`.",
            "maxLength": 200
          },
          "to": {
            "type": "string",
            "description": "To/Cc contains this text (case-insensitive).",
            "maxLength": 200
          },
          "subject": {
            "type": "string",
            "description": "Subject contains this text (case-insensitive).",
            "maxLength": 200
          },
          "skip_inbox": {
            "type": "boolean",
            "description": "Archive matching received mail so it appears only in the label folder, not the Inbox."
          },
          "apply_to_existing": {
            "type": "boolean",
            "description": "Also file already-retained mail that matches."
          }
        },
        "additionalProperties": false,
        "required": [
          "label_id"
        ]
      },
      "returns": "{id: `lrule_…`, labelId, direction, inboxId, from, to, subject, skipInbox}.",
      "example": {
        "label_id": "Billing",
        "inbox_id": "inb_123",
        "skip_inbox": true
      },
      "http": {
        "method": "POST",
        "path": "/labels/{label_id}/rules",
        "body": [
          "direction",
          "inbox_id",
          "from",
          "to",
          "subject",
          "skip_inbox",
          "apply_to_existing"
        ]
      }
    },
    {
      "name": "delete_label_rule",
      "title": "Delete an auto-filing rule",
      "group": "labels",
      "description": "DESTRUCTIVE: remove one auto-filing rule. Mail already filed keeps its label.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Delete an auto-filing rule"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "label_id": {
            "type": "string",
            "description": "Label ID (starts with `lbl_`) or the exact label name.",
            "minLength": 1,
            "maxLength": 128
          },
          "rule_id": {
            "type": "string",
            "description": "Rule ID (starts with `lrule_`), from get_label.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "label_id",
          "rule_id"
        ]
      },
      "returns": "{ok: true}.",
      "example": {
        "label_id": "lbl_123",
        "rule_id": "lrule_123"
      },
      "http": {
        "method": "DELETE",
        "path": "/labels/{label_id}/rules/{rule_id}"
      }
    },
    {
      "name": "label_email",
      "title": "Add or remove labels on an email",
      "group": "labels",
      "description": "Move a message between folders: add and/or remove labels by name or `lbl_…` ID. Unknown names in `add` are created unless `create` is false.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Add or remove labels on an email"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "email_id": {
            "type": "string",
            "description": "Email ID (starts with `em_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "add": {
            "type": "array",
            "description": "Labels to add.",
            "maxItems": 10,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "remove": {
            "type": "array",
            "description": "Labels to remove.",
            "maxItems": 10,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            }
          },
          "create": {
            "type": "boolean",
            "description": "Create unknown labels in `add` (default true)."
          }
        },
        "additionalProperties": false,
        "required": [
          "email_id"
        ]
      },
      "returns": "The updated email with `labels`.",
      "example": {
        "email_id": "em_123",
        "add": [
          "Billing"
        ],
        "remove": [
          "Support"
        ]
      },
      "http": {
        "method": "POST",
        "path": "/emails/{email_id}/labels",
        "body": [
          "add",
          "remove",
          "create"
        ]
      }
    },
    {
      "name": "list_sending_identities",
      "title": "List verified sender identities",
      "group": "drafts",
      "description": "Addresses and domains this workspace can send from right now (verified domains, their default From, and active inbox addresses). Call before send_email to pick a valid `from`.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List verified sender identities"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "returns": "{domains: [verified domain names], addresses: [sender addresses], localParts: [...]}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/sending-identities"
      }
    },
    {
      "name": "create_draft",
      "title": "Create a draft",
      "group": "drafts",
      "description": "Create a composer draft. Drafts hold attachments: create a draft, upload_attachment, then send_email with `draft_id`. Does not send anything.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Create a draft"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Sender address on a verified domain (may be empty while drafting)."
          },
          "to": {
            "type": "array",
            "description": "Recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 0,
            "maxItems": 100
          },
          "cc": {
            "type": "array",
            "description": "Carbon-copy recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 0,
            "maxItems": 100
          },
          "bcc": {
            "type": "array",
            "description": "Blind-copy recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 0,
            "maxItems": 100
          },
          "subject": {
            "type": "string",
            "description": "Subject line.",
            "maxLength": 998
          },
          "html": {
            "type": "string",
            "description": "HTML body."
          },
          "text": {
            "type": "string",
            "description": "Plain-text body."
          },
          "reply_to_email_id": {
            "type": "string",
            "description": "Email ID this draft replies to."
          },
          "thread_id": {
            "type": "string",
            "description": "Thread ID this draft belongs to."
          }
        },
        "additionalProperties": false
      },
      "returns": "Draft object {id: `dr_…`, from, to, cc, bcc, subject, html, text, attachments: []}.",
      "example": {
        "from": "hello@example.com",
        "to": [
          "owner@example.com"
        ],
        "subject": "Invoice"
      },
      "http": {
        "method": "POST",
        "path": "/drafts",
        "body": [
          "from",
          "to",
          "cc",
          "bcc",
          "subject",
          "html",
          "text",
          "reply_to_email_id",
          "thread_id"
        ]
      }
    },
    {
      "name": "list_drafts",
      "title": "List drafts",
      "group": "drafts",
      "description": "List composer drafts, most recently updated first. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List drafts"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [drafts], count, pagination}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/drafts",
        "pagination": "client"
      }
    },
    {
      "name": "get_draft",
      "title": "Get a draft",
      "group": "drafts",
      "description": "Retrieve one draft with its attachment metadata.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get a draft"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "draft_id": {
            "type": "string",
            "description": "Draft ID (starts with `dr_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "draft_id"
        ]
      },
      "returns": "Draft object with `attachments`.",
      "example": {
        "draft_id": "dr_123"
      },
      "http": {
        "method": "GET",
        "path": "/drafts/{draft_id}"
      }
    },
    {
      "name": "update_draft",
      "title": "Replace draft content",
      "group": "drafts",
      "description": "Replace a draft's content and recipients. This is a full replacement: fields you omit are cleared, so read get_draft first and send every field you want to keep. Attachments are unaffected.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Replace draft content"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "draft_id": {
            "type": "string",
            "description": "Draft ID (starts with `dr_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "from": {
            "type": "string",
            "description": "Sender address on a verified domain (may be empty while drafting)."
          },
          "to": {
            "type": "array",
            "description": "Recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 0,
            "maxItems": 100
          },
          "cc": {
            "type": "array",
            "description": "Carbon-copy recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 0,
            "maxItems": 100
          },
          "bcc": {
            "type": "array",
            "description": "Blind-copy recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 0,
            "maxItems": 100
          },
          "subject": {
            "type": "string",
            "description": "Subject line.",
            "maxLength": 998
          },
          "html": {
            "type": "string",
            "description": "HTML body."
          },
          "text": {
            "type": "string",
            "description": "Plain-text body."
          },
          "reply_to_email_id": {
            "type": "string",
            "description": "Email ID this draft replies to."
          },
          "thread_id": {
            "type": "string",
            "description": "Thread ID this draft belongs to."
          }
        },
        "additionalProperties": false,
        "required": [
          "draft_id"
        ]
      },
      "returns": "Updated draft object.",
      "example": {
        "draft_id": "dr_123",
        "from": "hello@example.com",
        "to": [
          "owner@example.com"
        ],
        "subject": "Invoice (updated)",
        "text": "Attached."
      },
      "http": {
        "method": "PUT",
        "path": "/drafts/{draft_id}",
        "body": [
          "from",
          "to",
          "cc",
          "bcc",
          "subject",
          "html",
          "text",
          "reply_to_email_id",
          "thread_id"
        ]
      }
    },
    {
      "name": "delete_draft",
      "title": "Discard a draft",
      "group": "drafts",
      "description": "DESTRUCTIVE: discard a draft and permanently delete its stored attachments.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Discard a draft"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "draft_id": {
            "type": "string",
            "description": "Draft ID (starts with `dr_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "draft_id"
        ]
      },
      "returns": "{ok: true}.",
      "example": {
        "draft_id": "dr_123"
      },
      "http": {
        "method": "DELETE",
        "path": "/drafts/{draft_id}"
      }
    },
    {
      "name": "upload_attachment",
      "title": "Upload an attachment to a draft",
      "group": "drafts",
      "description": "Upload one file to a draft (max 10 files and 10 MB total per message). Provide `content_base64` or a local `file_path`. Attachments require a paid plan at send time.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Upload an attachment to a draft"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "draft_id": {
            "type": "string",
            "description": "Draft ID (starts with `dr_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "filename": {
            "type": "string",
            "description": "File name shown to the recipient. Defaults to the basename of `file_path`.",
            "maxLength": 255
          },
          "content_type": {
            "type": "string",
            "description": "MIME type, e.g. `application/pdf`. Defaults to `application/octet-stream`."
          },
          "content_base64": {
            "type": "string",
            "description": "Standard base64 file content."
          },
          "file_path": {
            "type": "string",
            "description": "Absolute path of a local file readable by the MCP server process."
          }
        },
        "additionalProperties": false,
        "required": [
          "draft_id"
        ],
        "anyOf": [
          {
            "required": [
              "content_base64"
            ]
          },
          {
            "required": [
              "file_path"
            ]
          }
        ]
      },
      "returns": "{id: `att_…`, filename, contentType, sizeBytes, available}.",
      "example": {
        "draft_id": "dr_123",
        "filename": "invoice.pdf",
        "content_type": "application/pdf",
        "file_path": "/tmp/invoice.pdf"
      },
      "http": {
        "method": "POST",
        "path": "/drafts/{draft_id}/attachments"
      },
      "handler": "upload_attachment"
    },
    {
      "name": "download_attachment",
      "title": "Download an attachment",
      "group": "drafts",
      "description": "Download a private attachment (sent, received, or draft). Returns base64 content, or writes the file when `save_to_path` is set (refuses to overwrite unless `overwrite` is true).",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Download an attachment"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "attachment_id": {
            "type": "string",
            "description": "Attachment ID (starts with `att_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "save_to_path": {
            "type": "string",
            "description": "Optional absolute local path to write the file to instead of returning base64."
          },
          "overwrite": {
            "type": "boolean",
            "description": "Allow replacing an existing file at save_to_path. Defaults to false."
          }
        },
        "additionalProperties": false,
        "required": [
          "attachment_id"
        ]
      },
      "returns": "{attachment_id, filename, content_type, size_bytes, content_base64} or {attachment_id, filename, content_type, size_bytes, saved_to}.",
      "example": {
        "attachment_id": "att_123",
        "save_to_path": "/tmp/invoice.pdf"
      },
      "http": {
        "method": "GET",
        "path": "/attachments/{attachment_id}"
      },
      "handler": "download_attachment"
    },
    {
      "name": "delete_attachment",
      "title": "Delete an attachment",
      "group": "drafts",
      "description": "DESTRUCTIVE: permanently delete a stored attachment (for example, remove a file from a draft before sending).",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Delete an attachment"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "attachment_id": {
            "type": "string",
            "description": "Attachment ID (starts with `att_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "attachment_id"
        ]
      },
      "returns": "{ok: true}.",
      "example": {
        "attachment_id": "att_123"
      },
      "http": {
        "method": "DELETE",
        "path": "/attachments/{attachment_id}"
      }
    },
    {
      "name": "list_templates",
      "title": "List hosted templates",
      "group": "templates",
      "description": "List hosted email templates with publish state and usage. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List hosted templates"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "lifecycle": {
            "type": "string",
            "description": "`active` (default), `archived`, or `all`.",
            "enum": [
              "active",
              "archived",
              "all"
            ]
          },
          "query": {
            "type": "string",
            "description": "Search by name or key.",
            "maxLength": 120
          },
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [templates], count, pagination}.",
      "example": {
        "lifecycle": "active"
      },
      "http": {
        "method": "GET",
        "path": "/templates",
        "query": [
          "lifecycle",
          "query"
        ],
        "pagination": "client"
      }
    },
    {
      "name": "create_template",
      "title": "Create a hosted template",
      "group": "templates",
      "description": "Create a template with an editable draft, optionally from a starter (`welcome`, `reset`, `receipt`, or `blank`). Publish it before sending by key.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Create a hosted template"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Human name.",
            "maxLength": 120
          },
          "key": {
            "type": "string",
            "description": "Stable send key: lowercase letters, numbers, hyphens; starts with a letter (2–64 chars). Derived from name when omitted.",
            "pattern": "^[a-z][a-z0-9-]{1,63}$"
          },
          "starter": {
            "type": "string",
            "description": "Starter content.",
            "enum": [
              "blank",
              "welcome",
              "reset",
              "receipt"
            ]
          }
        },
        "additionalProperties": false,
        "required": [
          "name"
        ]
      },
      "returns": "{template, draft, activeVersion, versions, usage}.",
      "example": {
        "name": "Account welcome",
        "key": "account-welcome",
        "starter": "welcome"
      },
      "http": {
        "method": "POST",
        "path": "/templates",
        "body": [
          "name",
          "key",
          "starter"
        ]
      }
    },
    {
      "name": "get_template",
      "title": "Get a template",
      "group": "templates",
      "description": "Retrieve a template's current draft (with `revision`), active published release, release history, and usage. Accepts ID or key.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get a template"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "Template ID (`tmpl_…`) or key.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "template_id"
        ]
      },
      "returns": "{template, draft: {id, revision, subjectTemplate, htmlTemplate, textTemplate, variables, sampleData, …} | null, activeVersion, versions, usage}.",
      "example": {
        "template_id": "account-welcome"
      },
      "http": {
        "method": "GET",
        "path": "/templates/{template_id}"
      }
    },
    {
      "name": "update_template_draft",
      "title": "Save a template draft",
      "group": "templates",
      "description": "Save the template's editable draft using optimistic concurrency: pass the current `revision` from get_template (409 means someone else saved first; re-read and retry). This is a full replacement of draft content: omitted fields are cleared, so send every field you want to keep. Use `{{variable}}` placeholders.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Save a template draft"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "Template ID or key.",
            "minLength": 1,
            "maxLength": 128
          },
          "revision": {
            "type": "integer",
            "description": "Current draft revision from get_template.",
            "minimum": 1
          },
          "name": {
            "type": "string",
            "description": "Template name.",
            "maxLength": 120
          },
          "subject_template": {
            "type": "string",
            "description": "Subject with placeholders.",
            "maxLength": 998
          },
          "preheader_template": {
            "type": "string",
            "description": "Preview text.",
            "maxLength": 240
          },
          "html_template": {
            "type": "string",
            "description": "HTML body with placeholders."
          },
          "text_template": {
            "type": "string",
            "description": "Plain-text body with placeholders."
          },
          "from": {
            "type": "string",
            "description": "Default sender for sends of this template."
          },
          "reply_to": {
            "type": "string",
            "description": "Default Reply-To."
          },
          "variables": {
            "type": "array",
            "description": "Typed variable contract. Each item: {key (lowercase/underscores), label, type: text|number|url|boolean, required (default true), fallback, description}.",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "text",
                    "number",
                    "url",
                    "boolean"
                  ]
                },
                "required": {
                  "type": "boolean"
                },
                "fallback": {},
                "description": {
                  "type": "string"
                }
              },
              "required": [
                "key"
              ],
              "additionalProperties": false
            }
          },
          "sample_data": {
            "type": "object",
            "description": "Sample values used for previews and tests.",
            "additionalProperties": true
          }
        },
        "additionalProperties": false,
        "required": [
          "template_id",
          "revision"
        ]
      },
      "returns": "{template, draft: {revision: next}, validation: {valid, findings}}.",
      "example": {
        "template_id": "account-welcome",
        "revision": 3,
        "name": "Account welcome",
        "subject_template": "Welcome, {{first_name}}",
        "text_template": "Hi {{first_name}}",
        "variables": [
          {
            "key": "first_name",
            "type": "text",
            "required": true
          }
        ],
        "sample_data": {
          "first_name": "Asha"
        }
      },
      "http": {
        "method": "PUT",
        "path": "/templates/{template_id}/draft",
        "body": [
          "revision",
          "name",
          "subject_template:subjectTemplate",
          "preheader_template:preheaderTemplate",
          "html_template:htmlTemplate",
          "text_template:textTemplate",
          "from",
          "reply_to:replyTo",
          "variables",
          "sample_data:sampleData"
        ]
      }
    },
    {
      "name": "create_template_draft",
      "title": "Start a new draft from the published release",
      "group": "templates",
      "description": "Create a new editable draft copied from the current published release (409 if a draft already exists or nothing is published).",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Start a new draft from the published release"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "Template ID or key.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "template_id"
        ]
      },
      "returns": "{draft}.",
      "example": {
        "template_id": "account-welcome"
      },
      "http": {
        "method": "POST",
        "path": "/templates/{template_id}/draft"
      }
    },
    {
      "name": "render_template",
      "title": "Render a template preview",
      "group": "templates",
      "description": "Render the exact server output (subject, html, text) for the draft, the published release, or a specific version with the given data. Does not send. Returns 422 with `findings` when data violates the variable contract.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Render a template preview"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "Template ID or key.",
            "minLength": 1,
            "maxLength": 128
          },
          "version_id": {
            "type": "string",
            "description": "Optional version ID; defaults to the draft, then the published release."
          },
          "data": {
            "type": "object",
            "description": "Variable values; defaults to the version's sample data.",
            "additionalProperties": true
          }
        },
        "additionalProperties": false,
        "required": [
          "template_id"
        ]
      },
      "returns": "{subject, html, text, preheader, versionId, versionNumber, isDraft, findings}.",
      "example": {
        "template_id": "account-welcome",
        "data": {
          "first_name": "Asha"
        }
      },
      "http": {
        "method": "POST",
        "path": "/templates/{template_id}/render",
        "body": [
          "version_id:versionId",
          "data"
        ]
      }
    },
    {
      "name": "send_template_test",
      "title": "Send a template test email",
      "group": "templates",
      "description": "SENDS REAL EMAIL. Send a `[Test]`-prefixed snapshot of the draft (or a given version) to the given recipients. Counts against usage; trial workspaces can only send to the account email or an SES simulator address.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": true,
        "title": "Send a template test email"
      },
      "sends_email": true,
      "inputSchema": {
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "Template ID or key.",
            "minLength": 1,
            "maxLength": 128
          },
          "to": {
            "type": "array",
            "description": "Test recipients.",
            "items": {
              "type": "string",
              "minLength": 3,
              "maxLength": 320
            },
            "minItems": 1,
            "maxItems": 100
          },
          "from": {
            "type": "string",
            "description": "Sender on a verified domain; defaults to the template's From."
          },
          "version_id": {
            "type": "string",
            "description": "Optional version ID."
          },
          "data": {
            "type": "object",
            "description": "Variable values; defaults to sample data.",
            "additionalProperties": true
          }
        },
        "additionalProperties": false,
        "required": [
          "template_id",
          "to"
        ]
      },
      "returns": "{id: `em_…`, providerMessageId, threadId, isTest: true}.",
      "example": {
        "template_id": "account-welcome",
        "to": [
          "owner@example.com"
        ]
      },
      "http": {
        "method": "POST",
        "path": "/templates/{template_id}/test",
        "body": [
          "to",
          "from",
          "version_id:versionId",
          "data"
        ]
      }
    },
    {
      "name": "publish_template",
      "title": "Publish a template release",
      "group": "templates",
      "description": "Publish the current draft as an immutable release that `send_email` with `template.key` will use. Fails with 422 findings on validation errors, or 409 if it would break the live variable contract of a template already used in production.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Publish a template release"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "Template ID or key.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "template_id"
        ]
      },
      "returns": "{template, published}.",
      "example": {
        "template_id": "account-welcome"
      },
      "http": {
        "method": "POST",
        "path": "/templates/{template_id}/publish"
      }
    },
    {
      "name": "archive_template",
      "title": "Archive a template",
      "group": "templates",
      "description": "Stop new sends that use this template (history is kept; reversible with restore_template). Any integration sending this key will start failing with 404.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Archive a template"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "Template ID or key.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "template_id"
        ]
      },
      "returns": "{template}.",
      "example": {
        "template_id": "account-welcome"
      },
      "http": {
        "method": "POST",
        "path": "/templates/{template_id}/archive"
      }
    },
    {
      "name": "restore_template",
      "title": "Restore an archived template",
      "group": "templates",
      "description": "Make an archived template active again.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Restore an archived template"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "template_id": {
            "type": "string",
            "description": "Template ID or key.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "template_id"
        ]
      },
      "returns": "{template}.",
      "example": {
        "template_id": "account-welcome"
      },
      "http": {
        "method": "POST",
        "path": "/templates/{template_id}/restore"
      }
    },
    {
      "name": "list_domains",
      "title": "List domains",
      "group": "domains",
      "description": "List sending domains with aggregate `setup_status` (verified | checking | pending), per-record DNS state, and inbound status. Can be slow: unverified domains are re-checked live. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List domains"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [domains with records], count, pagination}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/domains",
        "pagination": "client"
      }
    },
    {
      "name": "get_domain",
      "title": "Get domain setup details",
      "group": "domains",
      "description": "Retrieve one domain with the exact DNS records to publish (type, name, value), each record's live state from two public resolvers, `dns_issues` with fixes, and inbound status.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get domain setup details"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Domain ID (starts with `dom_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "domain_id"
        ]
      },
      "returns": "{id, name, status, setup_status, dns_propagating, records: [{type, name, value, verified, dns_state}], dns_issues: [{code, message, …}], inbound_domain, inbound_status}.",
      "example": {
        "domain_id": "dom_123"
      },
      "http": {
        "method": "GET",
        "path": "/domains/{domain_id}"
      }
    },
    {
      "name": "add_domain",
      "title": "Add a sending domain",
      "group": "domains",
      "description": "Register a domain you control for sending. Returns the DNS records (SES Easy DKIM CNAMEs) the owner must publish. Does not change DNS itself. Counts against the plan's domain limit.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": true,
        "title": "Add a sending domain"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Bare domain name, e.g. `example.com` or `mail.example.com`.",
            "minLength": 3,
            "maxLength": 253,
            "pattern": "^[a-z0-9.-]+\\.[a-z]{2,}$"
          },
          "default_from": {
            "type": "string",
            "description": "Optional default sender address on this domain."
          }
        },
        "additionalProperties": false,
        "required": [
          "name"
        ]
      },
      "returns": "{id: `dom_…`, name, status: pending, records: [...], ses: {configured}}.",
      "example": {
        "name": "example.com"
      },
      "http": {
        "method": "POST",
        "path": "/domains",
        "body": [
          "name",
          "default_from"
        ]
      }
    },
    {
      "name": "verify_domain",
      "title": "Verify a domain",
      "group": "domains",
      "description": "Run a live SES/DNS verification check now. Safe to repeat; poll every 30–60 s after DNS changes (propagation can take minutes to hours). Sending is allowed once status is `verified`.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Verify a domain"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Domain ID (starts with `dom_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "domain_id"
        ]
      },
      "returns": "{domain, checks: {ses, dkim, dkim_status}, status: verified|pending}.",
      "example": {
        "domain_id": "dom_123"
      },
      "http": {
        "method": "POST",
        "path": "/domains/{domain_id}/verify"
      }
    },
    {
      "name": "delete_domain",
      "title": "Delete a domain",
      "group": "domains",
      "description": "DESTRUCTIVE: remove the domain from the workspace, including its inbound receiving route. Sends from it fail immediately afterwards. It does not delete DNS records at your DNS provider.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Delete a domain"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Domain ID (starts with `dom_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "domain_id"
        ]
      },
      "returns": "{ok: true}.",
      "example": {
        "domain_id": "dom_123"
      },
      "http": {
        "method": "DELETE",
        "path": "/domains/{domain_id}"
      }
    },
    {
      "name": "get_dns_provider",
      "title": "Detect DNS provider and record hosts",
      "group": "domains",
      "description": "Detect the domain's authoritative DNS provider and return the relative host to type into that provider for each record, the recommended DMARC record, inbound MX guidance, and whether one-click setup (Domain Connect) is available.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Detect DNS provider and record hosts"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Domain ID (starts with `dom_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "domain_id"
        ]
      },
      "returns": "{detectionStatus, detected, zone, nameservers, recordHosts: {recordId: host}, inbound, recommendations, authentication, providers: {domainConnect: {available, providerName}}}.",
      "example": {
        "domain_id": "dom_123"
      },
      "http": {
        "method": "GET",
        "path": "/dns/provider",
        "query": [
          "domain_id"
        ]
      }
    },
    {
      "name": "get_domain_connect_link",
      "title": "Get a one-click DNS setup link",
      "group": "domains",
      "description": "When get_dns_provider reports `providers.domainConnect.available`, create a signed consent URL. Give it to the human: they open it and approve the DNS change at their provider. Nothing changes until they approve. 409 if unsupported.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": true,
        "title": "Get a one-click DNS setup link"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Domain ID (starts with `dom_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "domain_id"
        ]
      },
      "returns": "{url, providerName}.",
      "example": {
        "domain_id": "dom_123"
      },
      "http": {
        "method": "GET",
        "path": "/dns/domain-connect/connect",
        "query": [
          "domain_id"
        ]
      }
    },
    {
      "name": "setup_inbound",
      "title": "Enable inbound receiving for a domain",
      "group": "inbound",
      "description": "Provision SES inbound receiving for a verified domain. Uses the root domain when it has no conflicting MX, otherwise `inbound.<domain>`. Returns the MX record the owner must publish; it does not edit DNS.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Enable inbound receiving for a domain"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Domain ID (starts with `dom_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "domain_id"
        ]
      },
      "returns": "{domain: receiving domain, status: dns_pending|ready, record: {type: MX, name, value}}.",
      "example": {
        "domain_id": "dom_123"
      },
      "http": {
        "method": "POST",
        "path": "/domains/{domain_id}/inbound/setup"
      }
    },
    {
      "name": "verify_inbound",
      "title": "Verify inbound MX",
      "group": "inbound",
      "description": "Re-check the inbound MX record. Status becomes `ready` when both public resolvers see it.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Verify inbound MX"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Domain ID (starts with `dom_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "domain_id"
        ]
      },
      "returns": "{domain, status: ready|dns_pending|propagating|checking, record}.",
      "example": {
        "domain_id": "dom_123"
      },
      "http": {
        "method": "POST",
        "path": "/domains/{domain_id}/inbound/verify"
      }
    },
    {
      "name": "list_inboxes",
      "title": "List inbound addresses",
      "group": "inbound",
      "description": "List receiving addresses, optionally for one domain. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List inbound addresses"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Optional domain ID filter."
          },
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [{id, address, name, status, domainId}], count, pagination}.",
      "example": {
        "domain_id": "dom_123"
      },
      "http": {
        "method": "GET",
        "path": "/inboxes",
        "query": [
          "domain_id"
        ],
        "pagination": "client"
      }
    },
    {
      "name": "get_inbox",
      "title": "Get an inbox",
      "group": "inbound",
      "description": "Retrieve one inbound address.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get an inbox"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "inbox_id": {
            "type": "string",
            "description": "Inbox ID (starts with `inb_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "inbox_id"
        ]
      },
      "returns": "Inbox object.",
      "example": {
        "inbox_id": "inb_123"
      },
      "http": {
        "method": "GET",
        "path": "/inboxes/{inbox_id}"
      }
    },
    {
      "name": "create_inbox",
      "title": "Create an inbound address",
      "group": "inbound",
      "description": "Create an address such as `support@<receiving domain>` on a domain whose inbound status is `ready` (run setup_inbound and verify_inbound first). Received mail appears in list_emails with direction `in`.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": false,
        "openWorldHint": false,
        "title": "Create an inbound address"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "domain_id": {
            "type": "string",
            "description": "Domain ID (starts with `dom_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "local_part": {
            "type": "string",
            "description": "Part before @, e.g. `support`.",
            "minLength": 1,
            "maxLength": 64
          },
          "name": {
            "type": "string",
            "description": "Optional display name."
          }
        },
        "additionalProperties": false,
        "required": [
          "domain_id",
          "local_part"
        ]
      },
      "returns": "{id: `inb_…`, address, name, status: active}.",
      "example": {
        "domain_id": "dom_123",
        "local_part": "support",
        "name": "Support"
      },
      "http": {
        "method": "POST",
        "path": "/inboxes",
        "body": [
          "domain_id",
          "local_part",
          "name"
        ]
      }
    },
    {
      "name": "update_inbox",
      "title": "Rename, enable, or disable an inbox",
      "group": "inbound",
      "description": "Rename an inbox or set its status to `active` / `disabled`.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Rename, enable, or disable an inbox"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "inbox_id": {
            "type": "string",
            "description": "Inbox ID (starts with `inb_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "name": {
            "type": "string",
            "description": "New display name."
          },
          "status": {
            "type": "string",
            "description": "New status.",
            "enum": [
              "active",
              "disabled"
            ]
          }
        },
        "additionalProperties": false,
        "required": [
          "inbox_id"
        ]
      },
      "returns": "Updated inbox.",
      "example": {
        "inbox_id": "inb_123",
        "status": "disabled"
      },
      "http": {
        "method": "PATCH",
        "path": "/inboxes/{inbox_id}",
        "body": [
          "name",
          "status"
        ]
      }
    },
    {
      "name": "set_inbox_forwarding",
      "title": "Forward an inbox to another address",
      "group": "inbound",
      "description": "SENDS REAL EMAIL when forwarding to someone other than the account owner: sets where an inbox's received mail is forwarded. The owner's own address activates immediately; any other address gets a confirmation email and forwarding stays `pending` until someone there confirms. Pass `forward_to: null` to turn forwarding off. Forwarded copies come from the inbox address with the original sender as Reply-To.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Forward an inbox to another address"
      },
      "sends_email": true,
      "inputSchema": {
        "type": "object",
        "properties": {
          "inbox_id": {
            "type": "string",
            "description": "Inbox ID (starts with `inb_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          },
          "forward_to": {
            "type": [
              "string",
              "null"
            ],
            "description": "Forwarding target email address, or null to turn forwarding off.",
            "maxLength": 254
          }
        },
        "additionalProperties": false,
        "required": [
          "inbox_id",
          "forward_to"
        ]
      },
      "returns": "Inbox with `forwardTo` and `forwardStatus` (`off`, `pending`, or `active`).",
      "example": {
        "inbox_id": "inb_123",
        "forward_to": "team@example.net"
      },
      "http": {
        "method": "PUT",
        "path": "/inboxes/{inbox_id}/forwarding",
        "body": [
          "forward_to"
        ]
      }
    },
    {
      "name": "delete_inbox",
      "title": "Delete an inbox",
      "group": "inbound",
      "description": "DESTRUCTIVE: delete an inbound address. Mail already received is retained; new mail to the address is no longer filed to it.",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Delete an inbox"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "inbox_id": {
            "type": "string",
            "description": "Inbox ID (starts with `inb_`), as returned by a list or create tool.",
            "minLength": 1,
            "maxLength": 128
          }
        },
        "additionalProperties": false,
        "required": [
          "inbox_id"
        ]
      },
      "returns": "{ok: true}.",
      "example": {
        "inbox_id": "inb_123"
      },
      "http": {
        "method": "DELETE",
        "path": "/inboxes/{inbox_id}"
      }
    },
    {
      "name": "deliverability_stats",
      "title": "Get 30-day delivery stats",
      "group": "deliverability",
      "description": "Workspace-wide 30-day totals: sent, delivery, bounce, complaint, reject, open, click, and deliveryRate (%).",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get 30-day delivery stats"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "returns": "{window: 30d, sent, delivery, bounce, complaint, reject, open, click, deliveryRate}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/deliverability/stats"
      }
    },
    {
      "name": "list_sender_reputation",
      "title": "List sender reputation",
      "group": "deliverability",
      "description": "Reputation state per exact From address: `active`, `throttled` (lower daily limit), or `paused` (sends return 423), with the reason and daily limit. Check this when sends fail with 423 or 429. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List sender reputation"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [{sender, status, dailyLimit, reason, cleanSince, warnedAt, pausedAt, evaluatedAt}], count, pagination}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/deliverability/reputation",
        "pagination": "client"
      }
    },
    {
      "name": "list_suppressions",
      "title": "List suppressions",
      "group": "deliverability",
      "description": "Workspace suppression list: recipients blocked after a permanent bounce or a spam complaint. Sends to them fail with 422. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List suppressions"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [{email, reason, detail, created_at}], count, pagination}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/suppressions",
        "query": [
          "limit",
          "offset"
        ],
        "pagination": "server"
      }
    },
    {
      "name": "remove_suppression",
      "title": "Remove a bounce suppression",
      "group": "deliverability",
      "description": "DESTRUCTIVE (weakens a safety block): remove a bounce suppression so the address can be mailed again. Only do this when the human confirms the address is now valid. Complaint suppressions cannot be removed (409).",
      "annotations": {
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false,
        "title": "Remove a bounce suppression"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "description": "Suppressed recipient address.",
            "minLength": 3,
            "maxLength": 320
          }
        },
        "additionalProperties": false,
        "required": [
          "email"
        ]
      },
      "returns": "{ok: true}.",
      "example": {
        "email": "fixed-mailbox@example.net"
      },
      "http": {
        "method": "DELETE",
        "path": "/suppressions/{email}"
      }
    },
    {
      "name": "list_blocked_recipients",
      "title": "List blocked recipients",
      "group": "deliverability",
      "description": "Every recipient SendHQ will refuse: bounces, complaints, and domain-scoped marketing unsubscribes, with a summary by kind. Reads up to the newest 500. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List blocked recipients"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [{email, domain, kind: bounce|complaint|unsubscribe, reason, detail, source, status, created_at}], count, summary: {total, bounce, complaint, unsubscribe}, pagination}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/blocked-recipients",
        "fixed_query": {
          "limit": "500"
        },
        "pagination": "client"
      }
    },
    {
      "name": "get_account",
      "title": "Get account, usage, and billing",
      "group": "account",
      "description": "Account owner email, plan/access tier, current-period recipient deliveries used vs quota, domains used vs limit, attachment transfer, reputation summary, subscription state, published plans, and workspace counts. Use it to check remaining quota or who the trial can deliver to (the account email).",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get account, usage, and billing"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "returns": "{user: {email, …}, usage: {domainsUsed, domainLimit, recipientDeliveries, emailQuotaMonth, attachmentBytes, attachmentByteLimit, periodKey}, access: {tier, planCode}, reputation, infrastructure, billing: {status, subscriptions, …}, plans, workspace: {mailer, stats}}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/account"
      }
    },
    {
      "name": "get_analytics",
      "title": "Get sending analytics",
      "group": "account",
      "description": "Dashboard analytics for the last 7, 30, or 90 days: sent/received/delivered/bounced/blocked/opened/clicked/complaint totals, a daily timeline, top sending domains, and top subjects.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Get sending analytics"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "days": {
            "type": "integer",
            "description": "Window in days: 7, 30 (default), or 90.",
            "enum": [
              7,
              30,
              90
            ]
          }
        },
        "additionalProperties": false
      },
      "returns": "{window, days, metrics, timeline: [{day, sent, received}], domains, topContent}.",
      "example": {
        "days": 30
      },
      "http": {
        "method": "GET",
        "path": "/analytics",
        "query": [
          "days"
        ]
      }
    },
    {
      "name": "list_api_keys",
      "title": "List API key metadata",
      "group": "account",
      "description": "List API key names, non-secret prefixes, and last-used times. Read-only: this MCP server cannot create, rotate, or revoke keys; a human does that in the dashboard. Paginated: the result includes `pagination` {offset, limit, returned, total?, has_more, next_offset}.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "List API key metadata"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Page size. Defaults to 50.",
            "minimum": 1,
            "maximum": 200,
            "default": 50
          },
          "offset": {
            "type": "integer",
            "description": "Number of records to skip. Use `pagination.next_offset` from the previous page.",
            "minimum": 0,
            "default": 0
          }
        },
        "additionalProperties": false
      },
      "returns": "{data: [{id, name, prefix, lastUsedAt, createdAt}], count, pagination}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/keys",
        "pagination": "client"
      }
    },
    {
      "name": "get_service_health",
      "title": "Check SendHQ service health",
      "group": "account",
      "description": "Check that the SendHQ API is up and which mail provider is active. Does not need a valid API key.",
      "annotations": {
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": true,
        "title": "Check SendHQ service health"
      },
      "sends_email": false,
      "inputSchema": {
        "type": "object",
        "properties": {},
        "additionalProperties": false
      },
      "returns": "{ok, service, mailer}.",
      "example": {},
      "http": {
        "method": "GET",
        "path": "/health"
      },
      "handler": "health"
    }
  ],
  "documentation": "https://sendhq.cc/docs/mcp",
  "install": {
    "unix": "curl -fsSL https://downloads.sendhq.cc/install.sh | sh",
    "windows": "irm https://downloads.sendhq.cc/install.ps1 | iex",
    "run": "sendhq mcp",
    "env": {
      "SENDHQ_API_KEY": "required",
      "SENDHQ_API_BASE_URL": "optional, default https://sendhq.cc/api/v1",
      "SENDHQ_MCP_READ_ONLY": "optional"
    }
  }
}
