Skip to main content
Glama

Send email

sendEmail
Destructive

Use this when the user has confirmed a new outbound email. Sends real email through Primitive's relay and can wait for the first SMTP delivery outcome, or schedule the send for a future time with scheduled_at. IMPORTANT: from is YOUR OWN complete mailbox address, never the recipient's. Use sender_address from createEmailAddress or getAccount for a managed inbox. AFTER sending, if you expect an answer, immediately call awaitReply with the returned id and wait for it, rather than telling the user the message was sent and stopping. Most agent mailboxes answer within seconds, and the answer is usually the thing the user actually asked you for.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
api_keyNoPrimitive API key (prim_...). Only needed when this connection has no signed-in account: pass the api_key returned by createEmailAddress, unchanged, on every call for the rest of the conversation. Omit it when the user is signed in.
requestBodyYes
Idempotency-KeyNoClient-supplied idempotency key. Retrying with the same key returns the original result without re-sending.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataYes
toolYes
statusYes
statusTextNo

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. Changed1 schema field changed
    • changedInput schema / properties / requestBody / properties / from / description
      Previous value: -"RFC 5322 From header. The sender domain must be a verified outbound domain for your organization."New value: +"RFC 5322 From header: YOUR OWN complete mailbox address, never the recipient's. createEmailAddress.address and getAccount.managed_inbox_address are domains, not mailbox addresses. When present, use the sender_address added to those MCP results, such as agent@pink-ram.primitive.email. Putting the recipient's address here mails them as themselves, which they will ignore. The sender domain must be a verified outbound domain for your organization."
  2. Changed1 schema field changed
    • addedInput schema / properties / api_key
      Added value: +{
      +  "description": "Primitive API key (prim_...). Only needed when this connection has no signed-in account: pass the api_key returned by createEmailAddress, unchanged, on every call for the rest of the conversation. Omit it when the user is signed in.",
      +  "maxLength": 200,
      +  "minLength": 8,
      +  "type": "string"
      +}
  3. Changed16 schema fields changed
    • changedInput schema / properties / requestBody / properties / attachments / description
      Previous value: -"Optional file attachments."New value: +"Optional file attachments. Not allowed on scheduled sends (scheduled_at)."
    • addedInput schema / properties / requestBody / properties / attachments / items / properties / content_id
      Added value: +{
      +  "description": "Content-ID for an inline (cid) attachment: 1-128 printable ASCII characters, no whitespace or angle brackets. When set, the part renders inline and body_html can reference it (e.g. src=\"cid:logo-1\"). Omit for a regular downloadable attachment.",
      +  "maxLength": 128,
      +  "minLength": 1,
      +  "pattern": "^[\\x21-\\x3B\\x3D\\x3F-\\x7E]+$",
      +  "type": "string"
      +}
    • changedInput schema / properties / requestBody / properties / attachments / items / properties / content_type / description
      Previous value: -"MIME type of the attachment (e.g. \"application/pdf\")."New value: +"MIME type of the attachment (e.g. \"application/pdf\"). Inferred from the filename when omitted."
    • addedInput schema / properties / requestBody / properties / bcc
      Added value: +{
      +  "description": "Optional BCC recipients: a single address or an array of single-address strings (each entry exactly one address). Counts toward the combined to+cc+bcc max of 100.",
      +  "oneOf": [
      +    {
      +      "maxLength": 998,
      +      "minLength": 3,
      +      "type": "string"
      +    },
      +    {
      +      "items": {
      +        "maxLength": 998,
      +        "minLength": 3,
      +        "type": "string"
      +      },
      +      "maxItems": 100,
      +      "minItems": 1,
      +      "type": "array"
      +    }
      +  ]
      +}
    • changedInput schema / properties / requestBody / properties / body_html / description
      Previous value: -"HTML message body. Provide at least one of body_text or body_html."New value: +"HTML message body. Provide at least one of body_text or body_html. Reference inline attachments via cid: URLs matching their content_id."
    • addedInput schema / properties / requestBody / properties / cc
      Added value: +{
      +  "description": "Optional CC recipients: a single address or an array of single-address strings (each entry exactly one address). Counts toward the combined to+cc+bcc max of 100.",
      +  "oneOf": [
      +    {
      +      "maxLength": 998,
      +      "minLength": 3,
      +      "type": "string"
      +    },
      +    {
      +      "items": {
      +        "maxLength": 998,
      +        "minLength": 3,
      +        "type": "string"
      +      },
      +      "maxItems": 100,
      +      "minItems": 1,
      +      "type": "array"
      +    }
      +  ]
      +}
    • addedInput schema / properties / requestBody / properties / reply_to
      Added value: +{
      +  "description": "Optional Reply-To header: a single address or an array of up to 10 single-address entries. A pure header: adds no recipients and does not count toward the recipient cap.",
      +  "oneOf": [
      +    {
      +      "maxLength": 998,
      +      "minLength": 3,
      +      "type": "string"
      +    },
      +    {
      +      "items": {
      +        "maxLength": 998,
      +        "minLength": 3,
      +        "type": "string"
      +      },
      +      "maxItems": 10,
      +      "minItems": 1,
      +      "type": "array"
      +    }
      +  ]
      +}
    • addedInput schema / properties / requestBody / properties / scheduled_at
      Added value: +{
      +  "description": "Schedule the send for a future time (ISO 8601 UTC, e.g. \"2026-08-01T09:00:00Z\"). Must be strictly in the future and at most 30 days out. Cannot be combined with wait or with attachments. Cancel before dispatch with cancelScheduledSend.",
      +  "format": "date-time",
      +  "type": "string"
      +}
    • addedInput schema / properties / requestBody / properties / tags
      Added value: +{
      +  "description": "Optional metadata tags (max 10, unique names) stored on the send record for correlation and filtering via listSentEmails. Never rendered into headers and never delivered.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "name": {
      +        "description": "Tag name: ASCII letters, digits, underscores, dashes only.",
      +        "maxLength": 64,
      +        "minLength": 1,
      +        "pattern": "^[A-Za-z0-9_-]+$",
      +        "type": "string"
      +      },
      +      "value": {
      +        "description": "Tag value: same charset as the name. Use \"true\" for a bare marker tag.",
      +        "maxLength": 256,
      +        "minLength": 1,
      +        "pattern": "^[A-Za-z0-9_-]+$",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "name",
      +      "value"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 10,
      +  "type": "array"
      +}
    • changedInput schema / properties / requestBody / properties / to / description
      Previous value: -"Recipient email address (RFC 5321 mailbox)."New value: +"Recipient email address (RFC 5321 mailbox, display-name form allowed), or an array of single-address strings to address multiple recipients with one message. Each array entry must be exactly one address. Combined to+cc+bcc count max 100."
    • removedInput schema / properties / requestBody / properties / to / maxLength
      Removed value: -320
    • removedInput schema / properties / requestBody / properties / to / minLength
      Removed value: -3
    • addedInput schema / properties / requestBody / properties / to / oneOf
      Added value: +[
      +  {
      +    "maxLength": 998,
      +    "minLength": 3,
      +    "type": "string"
      +  },
      +  {
      +    "items": {
      +      "maxLength": 998,
      +      "minLength": 3,
      +      "type": "string"
      +    },
      +    "maxItems": 100,
      +    "minItems": 1,
      +    "type": "array"
      +  }
      +]
    • removedInput schema / properties / requestBody / properties / to / type
      Removed value: -"string"
    • changedInput schema / properties / requestBody / properties / wait / description
      Previous value: -"When true, wait for the first SMTP delivery outcome before returning. Respects wait_timeout_ms."New value: +"When true, wait for the first SMTP delivery outcome before returning. Respects wait_timeout_ms. Cannot be combined with scheduled_at."
    • changedInput schema / properties / requestBody / properties / wait_timeout_ms / description
      Previous value: -"How long to wait for delivery confirmation when wait is true (1000–30000 ms, default 10000)."New value: +"How long to wait for delivery confirmation when wait is true (1000-30000 ms, default 10000)."
  4. Changed13 schema fields changed
    • addedInput schema / properties / Idempotency-Key / description
      Added value: +"Client-supplied idempotency key. Retrying with the same key returns the original result without re-sending."
    • addedInput schema / properties / requestBody / properties / attachments / description
      Added value: +"Optional file attachments."
    • addedInput schema / properties / requestBody / properties / attachments / items / properties / content_base64 / description
      Added value: +"Base64-encoded attachment content."
    • addedInput schema / properties / requestBody / properties / attachments / items / properties / content_type / description
      Added value: +"MIME type of the attachment (e.g. \"application/pdf\")."
    • addedInput schema / properties / requestBody / properties / attachments / items / properties / filename / description
      Added value: +"Attachment filename including extension."
    • addedInput schema / properties / requestBody / properties / body_html / description
      Added value: +"HTML message body. Provide at least one of body_text or body_html."
    • addedInput schema / properties / requestBody / properties / body_text / description
      Added value: +"Plain-text message body. Provide at least one of body_text or body_html."
    • addedInput schema / properties / requestBody / properties / in_reply_to / description
      Added value: +"Message-ID of the email being replied to, for threading (e.g. \"<abc@example.com>\")."
    • addedInput schema / properties / requestBody / properties / references / description
      Added value: +"List of Message-IDs for the References header, oldest-first."
    • addedInput schema / properties / requestBody / properties / subject / description
      Added value: +"Email subject line."
    • addedInput schema / properties / requestBody / properties / to / description
      Added value: +"Recipient email address (RFC 5321 mailbox)."
    • addedInput schema / properties / requestBody / properties / wait / description
      Added value: +"When true, wait for the first SMTP delivery outcome before returning. Respects wait_timeout_ms."
    • addedInput schema / properties / requestBody / properties / wait_timeout_ms / description
      Added value: +"How long to wait for delivery confirmation when wait is true (1000–30000 ms, default 10000)."
  5. First observed

TDQS

A4.2/5.0
Behavior4/5

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

Annotations already mark destructiveHint=true, and the description reinforces that by stating 'sends real email.' It adds behavioral details: can wait for SMTP delivery outcome, schedule send, and warns about `from` misuse. It mentions the post-send awaitReply step. Missing details like rate limits or cancellation behavior are partially covered by sibling tools, and annotations provide the base safety profile.

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

Conciseness5/5

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

The description is compact: three sentences each serving a distinct purpose (usage trigger, core behavior, critical instruction and post-send action). It is front-loaded with the use case, and every sentence adds necessary information without redundancy. No filler.

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

Completeness4/5

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

Given the tool's complexity (nested schema, many parameters, output schema present), the description covers the essential workflow: when to use, what it does, the critical `from` rule, and the post-send step with awaitReply. It references sibling tools for setup (createEmailAddress) and follow-up (awaitReply). The output schema exists, so the lack of return value details is acceptable. Minor gap: no mention of error states or the Idempotency-Key behavior, but these are covered in the schema.

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

Parameters3/5

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

The schema itself has a high level of detail (67% coverage) with descriptions for most parameters. The main description adds value for the `from` parameter ('YOUR OWN complete mailbox address, never the recipient's') and references sender_address from createEmailAddress/getAccount. However, it does not explain other key parameters like to, subject, attachments, or the interplay between wait and scheduled_at beyond a brief mention. The schema does the heavy lifting, so the description's additional semantic contribution is modest.

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

Purpose5/5

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

The description clearly states it sends real email through Primitive's relay, with options to wait or schedule. It specifies it is for new outbound emails only, distinguishing it from siblings like replyToEmail (replies) and sendEmailDemo (demo). The verb 'sends' plus resource 'email' with explicit scope is specific and unambiguous.

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

Usage Guidelines4/5

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

The description explicitly says 'Use this when the user has confirmed a new outbound email,' providing clear when-to-use context. It adds critical guidance: the `from` field must be your own address, and after sending, call awaitReply if expecting an answer. It does not explicitly exclude sibling tools for other scenarios (e.g., replying), but the narrowing to 'new outbound' is sufficient.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

TDQS

A4.1/5.0
Disambiguation5/5

Each tool targets a distinct resource or action: domain management (addDomain, verifyDomain), sending (sendEmail, replyToEmail), receiving (getEmail, listEmails), webhooks (createEndpoint, listWebhookDeliveries), status (getAccount, getInboxStatus), etc. There is no overlap in purpose, and descriptions clearly differentiate them.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern in snake_case, such as listDomains, createFilter, downloadEmailAttachments, and getSentEmail. The verbs (get, list, create, delete, send, reply, etc.) are used predictably, with no mixing of conventions.

Tool Count4/5

29 tools is slightly on the high side but still reasonable for an email server covering domains, sending, receiving, webhooks, filters, and status. Each tool serves a specific purpose and earns its place, though some consolidation might be possible.

Completeness4/5

The tool set covers core email workflows: domain setup (add, verify, list), sending/receiving, threading, webhook lifecycle, and filtering. Minor gaps exist, such as missing deleteDomain or updateEndpoint, but the surface is largely complete for the intended domain.

Resources