Mailtrap Email Sending
With this server, you can send transactional emails via Mailtrap with the following capabilities:
Send emails to specified recipients
Customize subject lines and sender details (optional, defaults to
DEFAULT_FROM_EMAIL)Include email content in plain text, HTML format, or both
Add CC and BCC recipients
Assign categories to emails for tracking purposes
Easily integrate with development environments like Claude Desktop, Cursor, or VS Code
Provides a tool for sending transactional emails via Mailtrap, supporting features like recipients (to, cc, bcc), HTML/text content, subject lines, categories, and sender customization.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Mailtrap Email Sendingsend a welcome email to newuser@example.com with subject 'Welcome!' and body 'Thanks for signing up!'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Mailtrap Server
An MCP server that provides tools for sending and testing in sandbox via Mailtrap.
Prerequisites
Before using this MCP server, you need to:
Get your API token from Mailtrap API settings
Get your Account ID from Mailtrap account management
Required Environment Variables:
MAILTRAP_API_TOKEN- Required for all functionalityMAILTRAP_ACCOUNT_ID- Required for templates, stats, email logs, sandbox list/show, sending domains, and suppressions. Optional only for the send tools (send-email, send-sandbox-email, and the batch-send-* tools), the email campaign tools, the company info tools, and the tracking opt-out tools.
Optional (can be passed as tool parameters instead):
DEFAULT_FROM_EMAIL- Default sender email whenfromis not provided to send-email, send-sandbox-email, or the batch-send-* tools (where it fillsbase.from). Enables switching sender per call via thefromparameter.MAILTRAP_SANDBOX_ID- Default sandbox ID for sandbox tools whensandbox_idis not provided. Enables switching between sandboxes per call via thesandbox_idparameter.MAILTRAP_TEST_INBOX_ID- Default test inbox ID for sandbox tools whentest_inbox_idis not provided. Enables switching between inboxes per call via thetest_inbox_idparameter. Legacy alias forMAILTRAP_SANDBOX_ID, still honored as a fallback.MAILTRAP_ORGANIZATION_ID- Required for organization tools (list-sub-accounts,create-sub-account).MAILTRAP_ORGANIZATION_API_TOKEN- Organization-scoped API token. Required for organization tools (separate fromMAILTRAP_API_TOKEN).
Related MCP server: Resend MCP Server
Quick Install
Smithery CLI
Smithery is a registry installer and manager for MCP servers that works with all AI clients.
npx @smithery/cli install mailtrapSmithery automatically handles client configuration and provides an interactive setup process. It's the easiest way to get started with MCP servers locally.
Setup
Claude Desktop
Use MCPB to install the Mailtrap server. You can find those files in Releases. Download .MCPB file and open it. If you have Claude Desktop - it will open it and suggest to configure.
Claude Desktop or Cursor
Add the following configuration:
{
"mcpServers": {
"mailtrap": {
"command": "npx",
"args": ["-y", "mcp-mailtrap"],
"env": {
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id",
"MAILTRAP_TEST_INBOX_ID": "your_test_inbox_id"
}
}
}
}If you are using asdf for managing Node.js you must use absolute path to executable (example for Mac)
{
"mcpServers": {
"mailtrap": {
"command": "/Users/<username>/.asdf/shims/npx",
"args": ["-y", "mcp-mailtrap"],
"env": {
"PATH": "/Users/<username>/.asdf/shims:/usr/bin:/bin",
"ASDF_DIR": "/opt/homebrew/opt/asdf/libexec",
"ASDF_DATA_DIR": "/Users/<username>/.asdf",
"ASDF_NODEJS_VERSION": "20.6.1",
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id",
"MAILTRAP_TEST_INBOX_ID": "your_test_inbox_id"
}
}
}
}Claude Desktop config file location
Mac: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
Cursor config file location
Mac: ~/.cursor/mcp.json
Windows: %USERPROFILE%\.cursor\mcp.json
VS Code
Manually changing config
Run in Command Palette: Preferences: Open User Settings (JSON)
Then, in the settings file, add the following configuration:
{
"mcp": {
"servers": {
"mailtrap": {
"command": "npx",
"args": ["-y", "mcp-mailtrap"],
"env": {
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id",
"MAILTRAP_TEST_INBOX_ID": "your_test_inbox_id"
}
}
}
}
}Don't forget to restart your MCP server after changing the "env" section.
MCP Bundle (MCPB)
For easy installation in hosts that support MCP Bundles, you can distribute an .mcpb bundle file.
# Build TypeScript and pack the MCPB bundle
npm run mcpb:pack
# Inspect bundle metadata
npm run mcpb:info
# Sign the bundle for distribution (optional)
npm run mcpb:signThis creates mailtrap-mcp.mcpb using the repository manifest.json and built artifacts in dist/.
Usage
Once configured, you can ask agent to send emails and manage templates, for example:
Email Sending Operations:
"Send an email to john.doe@example.com with the subject 'Meeting Tomorrow' and a friendly reminder about our upcoming meeting."
"Email sarah@example.com about the project update, and CC the team at team@example.com"
"Send the welcome template (uuid
b81aabcd-1a1e-41cf-91b6-eca0254b3d96) to new@example.com with variables{ name: 'Alex' }""Send a sandbox email to test@example.com with subject 'Test Template' to preview how our welcome email looks"
Email Logs (debug delivery):
"List my recent sent email logs"
"Show email logs for emails sent to user@example.com"
"Get the email log message for ID abc-123-uuid to check delivery status"
Sending Statistics:
"Get sending stats for January 2025"
"Show delivery rates broken down by domain for last month"
"What are my email stats by category from 2025-01-01 to 2025-01-31?"
Sandbox Operations:
"Get all messages from my sandbox inbox"
"Show me the first page of sandbox messages"
"Search for messages containing 'test' in my sandbox inbox"
"Show me the details of sandbox message with ID 5159037506"
Template Operations:
"List all email templates in my Mailtrap account"
"Create a new email template called 'Welcome Email' with subject 'Welcome to our platform!'"
"Update the template with ID 12345 to change the subject to 'Updated Welcome Message'"
"Delete the template with ID 67890"
Sending Domains:
"List my sending domains"
"Get sending domain with ID 3938"
"Create a sending domain for example.com"
"Turn on click tracking for sending domain 3938"
"Delete sending domain 3938"
"Get sending domain 3938 with DNS setup instructions"
"Show the company info for sending domain 3938"
"Set the company info for domain 3938 to Acme Inc, 123 Main St, San Francisco, US, 94105, https://acme.com"
"Change the company info city for domain 3938 to New York"
Suppressions:
"List suppressions for bounced@example.com"
"Suppress bounced@example.com on the transactional stream of domain 3938"
Tracking Opt-outs:
"Stop tracking opens and clicks for privacy@example.com on domain 3938"
"List everyone who opted out of tracking"
Available Tools
send-email
Sends a transactional email through Mailtrap. Supports two mutually exclusive modes — inline content (subject + text/html) or template-based (template_uuid).
Parameters:
from(optional): Sender as{ email, name? }(a bare email string is also accepted at runtime). If not provided,DEFAULT_FROM_EMAILis used.to(optional): Array of recipients as{ email, name? }objects (bare email strings, or a single non-array address, are also accepted at runtime). Optional ifccorbccis provided; at least one ofto/cc/bccmust contain a recipient.cc(optional): Array of CC recipients as{ email, name? }objects (bare email strings also accepted at runtime).bcc(optional): Array of BCC recipients as{ email, name? }objects (bare email strings also accepted at runtime).subject(conditional): Email subject line. Required for inline sends; must be omitted whentemplate_uuidis set.text(conditional): Email body text. Required (alongside or instead ofhtml) for inline sends; must be omitted whentemplate_uuidis set.html(conditional): HTML version of the email body. Required (alongside or instead oftext) for inline sends; must be omitted whentemplate_uuidis set.category(optional): Email category for tracking and analytics. Must be omitted whentemplate_uuidis set.template_uuid(optional): Use a Mailtrap email template instead of inline content. When set,subject/text/html/categorymust be omitted (per Mailtrap API).template_variables(optional): Object of variables substituted into the template referenced bytemplate_uuid. Only allowed together withtemplate_uuid.
batch-send-transactional-email
Sends a batch of transactional emails in one Mailtrap API call (default sending stream). Shared fields go on base; per-recipient overrides go in requests[]. Each request must include at least one recipient via to, cc, or bcc. Same inline-vs-template mutual exclusion as send-email — checked after merging base with each request.
Parameters:
base(optional): Object with fields shared across the batch.from(optional): Sender as{ email, name? }(a bare email string is also accepted at runtime). Falls back toDEFAULT_FROM_EMAIL.reply_to(optional): Reply-to address.subject/text/html/category(optional, inline mode): Default content for every request.template_uuid/template_variables(optional, template mode): Default template + variables. Mutually exclusive with the inline fields.custom_variables(optional): Default custom variables (string-valued).headers(optional): Default custom headers.
requests(required): Non-empty array of per-recipient messages. Each entry has:to(optional): Array of recipients as{ email, name? }objects (bare email strings, or a single non-array address, are also accepted at runtime). Optional ifccorbccis provided; at least one ofto/cc/bccmust contain a recipient.cc,bcc,reply_to(optional).Inline (
subject/text/html/category) or template (template_uuid/template_variables) overrides; any field omitted falls back to the matchingbasevalue.custom_variables,headers(optional).
batch-send-bulk-email
Sends a batch of bulk emails through Mailtrap's bulk-stream API. Same base + requests[] shape, validation, and inline-vs-template rules as batch-send-transactional-email — the only difference is that this tool routes the call through the bulk endpoint instead of the transactional one. See the parameters above.
list-email-logs
Lists sent email logs (delivery history) with optional pagination and filters. Use to debug delivery issues from the IDE.
Parameters:
search_after(optional): Pagination cursor from the previous response'snext_page_cursorsent_after(optional): ISO 8601 date/time; only logs sent after this timesent_before(optional): ISO 8601 date/time; only logs sent before this timefrom_email(optional): Filter by sender email; use withfrom_operator(default: ci_equal)to_email(optional): Filter by recipient email; use withto_operator(default: ci_equal)status(optional): Filter by delivery status: delivered, not_delivered, enqueued, opted_out; use withstatus_operator(default: equal)subject(optional): Filter by email subject; use withsubject_operator(default: ci_contain). Usesubject_operator: empty/not_empty to filter by presence of subject.sending_domain_id(optional): Filter by sending domain ID (number); use withsending_domain_id_operator(default: equal)sending_stream(optional): Filter by stream: transactional or bulk; use withsending_stream_operator(default: equal)events(optional): Filter by event type(s): delivery, open, click, bounce, spam, unsubscribe, soft_bounce, reject, suspension; use withevents_operator(include_event / not_include_event)clicks_count/opens_count(optional): Filter by click/open count; use with*_operator: equal, greater_than, less_thanclient_ip/sending_ip(optional): Filter by IP; use with*_operator: equal, not_equal, contain, not_containemail_service_provider_response(optional): Filter by provider response text; use with*_operator(ci_contain, etc.)email_service_provider(optional): Filter by provider (exact); use with*_operator: equal, not_equalrecipient_mx(optional): Filter by recipient MX; use withrecipient_mx_operator(ci_contain, etc.)category(optional): Filter by email category; use withcategory_operator: equal, not_equal
All parameters are optional.
get-email-log-message
Gets a single email log message by ID (UUID): a readable summary (from, to, subject, sent time, status, category, stream, engagement, delivery context), then detailed event history. Optionally, with include_content: true, you can also load and show the message body (HTML and plain text) when Mailtrap exposes a raw message URL.
Parameters:
message_id(required): UUID of the email log message (from send response or list-email-logs). Uselist-email-logsto find message IDs.include_content(optional): Whentrue, fetches the raw EML (ifraw_message_urlis available) and appends parsed HTML and plain-text body sections, similar to show-sandbox-email-message.
get-sending-stats
Get email sending statistics (delivery, bounce, open, click, spam rates) for a date range. Optionally break down by domain, category, email service provider, or date. Check delivery rates without leaving the editor.
Parameters:
start_date(required): Start date for the stats range (YYYY-MM-DD)end_date(required): End date for the stats range (YYYY-MM-DD)breakdown(optional): How to break down the stats:aggregated(default),by_domain,by_category,by_email_service_provider, orby_datesending_domain_ids(optional): Limit results to these sending domain IDs (array of integers)sending_streams(optional): Limit totransactionaland/orbulk(array of strings)categories(optional): Limit to these email categories (array of strings)email_service_providers(optional): Limit to these providers, e.g. Google, Yahoo, Outlook (array of strings)
create-template
Creates a new email template in your Mailtrap account.
Parameters:
name(required): Name of the templatesubject(required): Email subject linehtml(ortextis required): HTML content of the templatetext(orhtmlis required): Plain text version of the templatecategory(optional): Template category (defaults to "General")
list-templates
Lists all email templates in your Mailtrap account.
Parameters:
No parameters required
get-template
Get a single email template by ID, including subject, category, and HTML/text body.
Parameters:
template_id(required): ID of the template to fetch
update-template
Updates an existing email template.
Parameters:
template_id(required): ID of the template to updatename(optional): New name for the templatesubject(optional): New email subject linehtml(optional): New HTML content of the templatetext(optional): New plain text version of the templatecategory(optional): New category for the template
At least one updatable field (name, subject, html, text, or category) must be provided when calling update-template to perform an update.
delete-template
Deletes an existing email template.
Parameters:
template_id(required): ID of the template to delete
send-sandbox-email
Sends an email to your Mailtrap test inbox for development and testing purposes. This is perfect for testing email templates without sending emails to real recipients. Supports the same two modes as send-email — inline content or template-based (template_uuid).
Parameters:
test_inbox_id(optional): Mailtrap test inbox ID. Required unlessMAILTRAP_TEST_INBOX_IDis set; pass per call to target a specific inbox.from(optional): Sender as{ email, name? }(a bare email string is also accepted at runtime). If not provided,DEFAULT_FROM_EMAILis used.to(optional): Array of recipients as{ email, name? }objects (bare email strings in the array, or a comma-separated string of plain emails, are also accepted at runtime). Optional ifccorbccis provided; at least one ofto/cc/bccmust contain a recipient.cc(optional): Array of CC recipients as{ email, name? }objects (bare email strings also accepted at runtime).bcc(optional): Array of BCC recipients as{ email, name? }objects (bare email strings also accepted at runtime).subject(conditional): Email subject line. Required for inline sends; must be omitted whentemplate_uuidis set.text(conditional): Email body text. Required (alongside or instead ofhtml) for inline sends; must be omitted whentemplate_uuidis set.html(conditional): HTML version of the email body. Required (alongside or instead oftext) for inline sends; must be omitted whentemplate_uuidis set.category(optional): Email category for tracking. Must be omitted whentemplate_uuidis set.template_uuid(optional): Use a Mailtrap email template instead of inline content. When set,subject/text/html/categorymust be omitted.template_variables(optional): Object of variables substituted into the template referenced bytemplate_uuid. Only allowed together withtemplate_uuid.
batch-send-sandbox-email
Sends a batch of emails to your Mailtrap test inbox in one API call, without delivering to real recipients. Same base + requests[] shape, validation, and inline-vs-template rules as batch-send-transactional-email — the difference is that this tool routes the call through the sandbox endpoint for a single test inbox.
Parameters:
sandbox_id(optional): Mailtrap sandbox (test inbox) ID. Required unlessMAILTRAP_SANDBOX_IDis set; pass per call to target a specific sandbox.base(optional),requests(required): Seebatch-send-transactional-emailabove.
For sandbox tools, providetest_inbox_id in the tool call or set the MAILTRAP_TEST_INBOX_ID environment variable. You can switch between inboxes per call by passing test_inbox_id. Tools taking sandbox_id use MAILTRAP_SANDBOX_ID first.
get-sandbox-messages
Retrieves a list of messages from your Mailtrap test inbox. Useful for checking what emails have been received in your sandbox during testing.
Parameters:
page(optional): Page number for pagination (minimum: 1)last_id(optional): Pagination using last message ID. Returns messages after the specified message ID (minimum: 1)search(optional): Search query to filter messages
All parameters are optional. If none are provided, the first page of messages from the inbox will be returned. Use page for traditional pagination, last_id for cursor-based pagination, or search to filter messages by content.
show-sandbox-email-message
Shows detailed information and content of a specific email message from your Mailtrap test inbox, including HTML and text body content.
Parameters:
message_id(required): ID of the sandbox email message to retrieve
Useget-sandbox-messages first to get the list of messages and their IDs, then use this tool to view the full content of a specific message.
get-sandbox-project
Get a sandbox project by ID, including its inboxes and email counts.
Parameters:
project_id(required): ID of the project to fetch
update-sandbox-project
Rename an existing sandbox project.
Parameters:
project_id(required): ID of the project to updatename(required): New name for the project (2–100 characters)
list-sandboxes
List every sandbox accessible to the API token across all projects.
Parameters:
No parameters required
mark-sandbox-as-read
Mark all messages in a sandbox as read.
Parameters:
sandbox_id(required): ID of the sandbox to act on
reset-sandbox-credentials
Reset the SMTP credentials for a sandbox. Returns the new username/password.
Parameters:
sandbox_id(required): ID of the sandbox to act on
enable-sandbox-email-address
Enable the receive-by-email address for a sandbox (turns on the Mailtrap address that delivers messages to the sandbox via SMTP).
Parameters:
sandbox_id(required): ID of the sandbox to act on
reset-sandbox-email-address
Generate a new receive-by-email address for a sandbox.
Parameters:
sandbox_id(required): ID of the sandbox to act on
forward-sandbox-message
Forward a sandbox message to an external email address. Counts against your monthly forwarding quota.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message to forwardemail(required): Email address to forward the message to
update-sandbox-message
Mark a sandbox message as read or unread.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message to updateis_read(required):truemarks as read,falsemarks as unread
delete-sandbox-message
Delete a single sandbox message.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message to delete
get-sandbox-message-spam-score
Get the SpamAssassin spam report for a sandbox message (score, rules, full report). Standalone alternative to include_spam_report: true on show-sandbox-email-message.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
get-sandbox-message-html-analysis
Get the HTML analysis report for a sandbox message (client compatibility scores, problematic elements). Standalone alternative to include_html_analysis: true on show-sandbox-email-message.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
get-sandbox-message-headers
Get the parsed mail headers for a sandbox message.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
get-sandbox-message-html
Get the rendered HTML body of a sandbox message.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
get-sandbox-message-text
Get the plain-text body of a sandbox message.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
get-sandbox-message-raw
Get the raw, MIME-formatted message (headers + body) for a sandbox message.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
get-sandbox-message-eml
Get the message rendered as an EML file payload (suitable for attaching to a ticket or importing into another mail client).
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
get-sandbox-message-html-source
Get the unrendered HTML source of a sandbox message (HTML before any Mailtrap-side transformations like CID-link rewrites).
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
list-sandbox-attachments
List all attachments on a sandbox message (filename, content type, size, download path).
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message
get-sandbox-attachment
Get metadata and download URL for a single attachment.
Parameters:
sandbox_id(optional): Sandbox ID. Falls back toMAILTRAP_SANDBOX_ID.message_id(required): ID of the sandbox message that contains the attachmentattachment_id(required): ID of the attachment to fetch
list-sending-domains
List sending domains and their DNS verification status.
Parameters:
No parameters required
get-sending-domain
Get a sending domain by ID and its verification status (including DNS records). Optionally include DNS setup instructions by setting include_setup_instructions to true.
Parameters:
sending_domain_id(required): Sending domain IDinclude_setup_instructions(optional): Iftrue, append DNS setup instructions to the response. Default:false
create-sending-domain
Create a new sending domain. After creation, add DNS records to verify the domain (use get-sending-domain with include_setup_instructions: true to see the records).
Parameters:
domain_name(required): Domain name (e.g. example.com)
update-sending-domain
Update a sending domain's tracking and inbound settings.
Parameters:
sending_domain_id(required): Sending domain IDopen_tracking_enabled(optional): Track opens on emails sent from this domainclick_tracking_enabled(optional): Track clicks on links in emails sent from this domaintracking_opt_out_enabled(optional): Add the tracking opt-out link to tracked emails. Requires open or click trackingauto_unsubscribe_link_enabled(optional): Automatically add an unsubscribe link to emailsinbound_enabled(optional): Allow the domain to be attached to an inbound inbox as a catch-all
At least one setting besides sending_domain_id must be provided.
delete-sending-domain
Delete a sending domain.
Parameters:
sending_domain_id(required): Sending domain ID to delete
send-sending-domain-setup-instructions
Email DNS setup instructions for a sending domain to a given address. Useful for forwarding DNS records to a DevOps teammate.
Parameters:
sending_domain_id(required): Sending domain IDemail(required): Email address to send DNS setup instructions to
get-company-info
Get the company info of a sending domain, used for domain compliance verification.
Parameters:
sending_domain_id(required): Sending domain ID
create-company-info
Set the company info of a sending domain, required for domain compliance verification.
Parameters:
sending_domain_id(required): Sending domain IDname(required): Company or individual nameaddress(required): Street addresscity(required): Citycountry(required): Countryzip_code(required): ZIP or postal codewebsite_url(required): Company website URLphone(optional): Phone numberprivacy_policy_url(optional): URL of the privacy policy pageterms_of_service_url(optional): URL of the terms of service pageinfo_level(optional):businessorindividual
update-company-info
Update the company info of a sending domain.
Parameters:
sending_domain_id(required): Sending domain IDEvery field of create-company-info, all optional. At least one must be provided; fields left out are unchanged.
list-suppressions
List or search suppressions (hard bounces, spam complaints, unsubscriptions, manual imports). Returns up to 1000 results per call.
Parameters:
email(optional): Email filter. Returns only suppressions matching this address.
create-suppression
Add an email address to the account's suppression list, so Mailtrap stops delivering to it.
Parameters:
email(required): Email address to suppressdomain_id(required): ID of the sending domain the suppression applies tosending_stream(required):transactionalorbulktype(optional):hard bounce,spam complaint,unsubscriptionormanual import. Defaults tomanual import
delete-suppression
Delete a suppression by ID. Mailtrap will resume delivery to this email unless it gets suppressed again.
Parameters:
suppression_id(required): ID of the suppression to delete
list-tracking-opt-outs
List email addresses excluded from open and click tracking. Returns up to 1000 records per call.
Parameters:
email(optional): Email filter. Returns only opt-outs matching this addressstart_time(optional): Only opt-outs created at or after this time (ISO 8601)end_time(optional): Only opt-outs created at or before this time (ISO 8601)last_id(optional): Pagination cursor — thelast_idfrom the previous response
create-tracking-opt-out
Exclude an email address from open and click tracking for a sending domain.
Parameters:
email(required): Email address to opt out of trackingdomain_id(required): ID of the sending domain the opt-out applies to
delete-tracking-opt-out
Remove an email address from the tracking opt-out list, so open and click tracking applies to it again.
Parameters:
tracking_opt_out_id(required): ID of the tracking opt-out to delete
list-webhooks
List all webhooks configured for the account. Returns the full webhook records as JSON.
Parameters:
No parameters required
get-webhook
Get a single webhook by ID. Returns the full webhook record as JSON. Note: signing_secret is not returned here — it is only available in the response from create-webhook.
Parameters:
webhook_id(required): ID of the webhook to fetch
create-webhook
Create a webhook. The response includes a signing_secret for verifying webhook payload signatures — this secret is returned only on creation, so store it now. If you lose it, recreate the webhook.
Parameters:
url(required): URL Mailtrap will POST webhook events towebhook_type(required):"email_sending","audit_log", or"inbound_receiving"active(optional, boolean): defaults totruepayload_format(optional):"json"or"jsonlines". Defaults to"json"sending_stream(optional,email_sendingonly):"transactional"or"bulk"event_types(optional,email_sendingonly): array ofdelivery,soft_bounce,bounce,suspension,unsubscribe,open,spam_complaint,click,rejectdomain_id(optional,email_sendingonly): sending domain ID to scope this webhook toinbound_inbox_id(optional,inbound_receivingonly): ID of the inbound inbox the webhook is linked to; omit to apply to all inboxes in the account
update-webhook
Update a webhook's mutable fields. webhook_type, sending_stream, and domain_id cannot be changed after creation — recreate the webhook if you need to change those.
Parameters:
webhook_id(required): ID of the webhook to updateurl(optional): New webhook URLactive(optional, boolean): Enable or disable the webhookpayload_format(optional):"json"or"jsonlines"event_types(optional,email_sendingonly): array ofdelivery,soft_bounce,bounce,suspension,unsubscribe,open,spam_complaint,click,rejectinbound_inbox_id(optional,inbound_receivingonly): ID of the inbound inbox the webhook is linked to
delete-webhook
Permanently delete a webhook by ID. Returns the deleted webhook record.
Parameters:
webhook_id(required): ID of the webhook to delete
get-contact
Get a contact by ID or email. Returns the full contact record (list memberships, status, custom fields).
Parameters:
contact_identifier(required): Contact ID or email address
create-contact
Create a new contact.
Parameters:
email(required): Email addressfields(optional): Custom field values keyed by merge tag (e.g.first_name). String, number, or boolean valueslist_ids(optional): IDs of contact lists to subscribe this contact tounsubscribed(optional, boolean): Create the contact inunsubscribedstatus
update-contact
Update an existing contact identified by ID or email. list_ids replaces the contact's full membership set; list_ids_included/list_ids_excluded add/remove without disturbing the rest.
Parameters:
contact_identifier(required): Contact ID or emailemail(optional): New email addressfields(optional): Custom field values keyed by merge taglist_ids(optional): Replace membership set with this exact listlist_ids_included(optional): List IDs to add (additive)list_ids_excluded(optional): List IDs to removeunsubscribed(optional, boolean): Set tounsubscribed(true) orsubscribed(false)
delete-contact
Permanently delete a contact by ID or email. Returns the deleted contact record when the API responds with one; otherwise returns a confirmation payload.
Parameters:
contact_identifier(required): Contact ID or email
create-contact-event
Record a contact event against a contact (by ID or email). Used to trigger contact-list automations.
Parameters:
contact_identifier(required): Contact ID or emailname(required): Event name (matches automation triggers)params(required): Object of arbitrary key/value pairs. Values may be string, number, boolean, or null
list-contact-lists
List all contact lists for the account.
Parameters:
search(optional): Filter contact lists by name (case-insensitive match), e.g.news
get-contact-list
Get a contact list by ID.
Parameters:
list_id(required): ID of the contact list to fetch
create-contact-list
Create a new contact list.
Parameters:
name(required): Name for the new list
update-contact-list
Rename an existing contact list.
Parameters:
list_id(required): ID of the contact listname(required): New name for the list
delete-contact-list
Permanently delete a contact list by ID.
Parameters:
list_id(required): ID of the contact list to delete
list-contact-fields
List all contact field definitions for the account.
Parameters:
No parameters required
get-contact-field
Get a contact field definition by ID.
Parameters:
field_id(required): ID of the contact field
create-contact-field
Create a new contact field definition. merge_tag must be unique within the account and is used as the placeholder name in template variables.
Parameters:
name(required): Display name (e.g. "First Name")merge_tag(required): Unique placeholder name (e.g.first_name)data_type(required): One oftext,number,boolean,date
update-contact-field
Update a contact field definition. Any combination of name, merge_tag, and data_type can be changed.
Parameters:
field_id(required): ID of the contact fieldname(optional): New display namemerge_tag(optional): New merge tag (must remain unique)data_type(optional): One oftext,number,boolean,date
delete-contact-field
Permanently delete a contact field definition by ID.
Parameters:
field_id(required): ID of the contact field to delete
create-contact-import
Bulk import contacts. Returns an import job record; poll its status with get-contact-import.
Parameters:
contacts(required): Array of contact entries. Each entry needs:email(required): Contact email addressfields(optional): Custom field values keyed by merge tag (string or number values)list_ids_included(optional): List IDs to add the contact tolist_ids_excluded(optional): List IDs to remove the contact from
get-contact-import
Get the status of a contact import job (created/started/finished/failed) with created/updated/over-limit counts.
Parameters:
import_id(required): ID of the contact import job
create-contact-export
Export contacts matching a set of AND-combined filters. Returns an export job record; poll status with get-contact-export to retrieve the download URL once status is finished.
Parameters:
filters(required): Array of filter objects. Each has:name(required): Field to filter on (list_id,subscription_status,email, etc.)operator(required): One ofequal,not_equal,contains,not_contains,is_empty,is_not_emptyvalue(required): Comparison value (string, number, boolean, or array)
get-contact-export
Get the status of a contact export job. Once status is finished, the url field holds the CSV download link.
Parameters:
export_id(required): ID of the contact export job
list-email-campaigns
List the account's email campaigns, newest first, with page-token pagination. Optionally filter by name with search.
Parameters:
token(optional): Page number to retrieve (page-token pagination). Defaults to1per_page(optional): Number of campaigns per page. Defaults to50, maximum100search(optional): Filter campaigns by name (case-insensitive partial match)
get-email-campaign
Get an email campaign by ID.
Parameters:
email_campaign_id(required): ID of the email campaign
create-email-campaign
Create a new email campaign. The campaign is always created in the draft state; scheduling and starting are separate tools (schedule-email-campaign, start-email-campaign).
Parameters:
name(required): Campaign namedomain_id(required): ID of the verified sending domain used for the campaign, as returned by the Sending Domains endpointsfrom_local_part(required): Local part (before the @) of the From addresstemplate_attributes(required): Inline email template. Has:subject(required): Email subject line (max 255 chars). Supports merge tags, e.g.Hi {{first_name}}body_html(optional): HTML body (the design). Required before the campaign can be scheduled or started. Include an unsubscribe link via an anchor whosehrefcontains the__unsubscribe_url__placeholderbody_text(optional): Plain-text alternative of the email bodymerge_tags(optional): Bare names of the merge tags referenced in the subject/body, e.g.["first_name"]
from_display_name(optional): Display name shown in the From headerreply_to(optional): Reply-To address parts (display_name,local_part,domain)delivery_mode(optional):rapid(send as fast as possible) orgradual(throttle todelivery_options.emails_per_hour)delivery_options(optional): Delivery throttling options (emails_per_hour)contact_list_ids(optional): IDs of contact lists to send to (treated as the full set of included lists)contact_segment_ids(optional): IDs of contact segments to send to (treated as the full set of included segments)
update-email-campaign
Update a draft email campaign. Only the provided fields change; the template is edited in place. Campaigns in any other state cannot be updated.
Parameters:
email_campaign_id(required): ID of the email campaign to updateAll other parameters are optional and identical to
create-email-campaign(name,domain_id,from_local_part,from_display_name,reply_to,template_attributes,delivery_mode,delivery_options,contact_list_ids,contact_segment_ids)
delete-email-campaign
Delete an email campaign by ID. Only a campaign in the draft state can be deleted.
Parameters:
email_campaign_id(required): ID of the email campaign to delete
start-email-campaign
Start sending a draft email campaign immediately. Only draft campaigns can be started; the template must have a body_html design and the audience and verified sending domain must be set.
Parameters:
email_campaign_id(required): ID of the email campaign to start
schedule-email-campaign
Schedule a draft email campaign to start sending at a future time. Only draft campaigns can be scheduled.
Parameters:
email_campaign_id(required): ID of the email campaign to scheduledatetime(required): When to send the campaign (ISO 8601). Must be in the future and no more than 1 month ahead
cancel-email-campaign
Cancel a scheduled email campaign, returning it to draft. Only scheduled campaigns can be cancelled.
Parameters:
email_campaign_id(required): ID of the email campaign to cancel
terminate-email-campaign
Terminate an email campaign that is currently sending (started, queued, or paused), aborting the in-flight send.
Parameters:
email_campaign_id(required): ID of the email campaign to terminate
reset-email-campaign
Reset a scheduled email campaign back to draft. Only scheduled campaigns can be reset.
Parameters:
email_campaign_id(required): ID of the email campaign to reset
get-email-campaign-stats
Get aggregated performance statistics for an email campaign (counts and rates for deliveries, opens, clicks, bounces, spam complaints, and unsubscriptions).
Parameters:
email_campaign_id(required): ID of the email campaignstart_date(optional): Start of the aggregation window (inclusive),YYYY-MM-DD. Defaults to the day the campaign was last startedend_date(optional): End of the aggregation window (inclusive),YYYY-MM-DD. Defaults to the current date
list-accounts
List Mailtrap accounts the current API token can access, with each account's access levels.
Parameters:
No parameters required
get-billing-usage
Get the current billing cycle usage for the account: sending and testing plans, limits, and current counts.
Parameters:
No parameters required
list-account-accesses
List account accesses (users, invites, API tokens) for the account. Optional filters narrow the result to specific resources. Requires account admin/owner permissions.
Parameters:
domain_uuids(optional): Filter by sending domain UUIDs (array of strings)inbox_ids(optional): Filter by sandbox inbox IDs (array of strings)project_ids(optional): Filter by sandbox project IDs (array of strings)
remove-account-access
Remove an account access by ID. For User specifiers this revokes their permissions; for Invite or ApiToken specifiers it removes the specifier entirely. Requires admin/owner.
Parameters:
account_access_id(required): ID of the access record to remove
get-permission-resources
Get all resources (inboxes, projects, domains, billing, account) to which the API token has admin access, nested by hierarchy.
Parameters:
No parameters required
bulk-update-permissions
Bulk create, update, or destroy permissions for a single account access. Existing (resource_type, resource_id) pairs are updated; new ones are created. Set destroy: true on an entry to remove it.
Parameters:
account_access_id(required): Target account access IDpermissions(required): Array of permission entries. Each has:resource_id(required): Resource ID (number or string)resource_type(required): One ofaccount,project,inbox,domain,billingaccess_level(optional):admin/100orviewer/10destroy(optional, boolean): When true, removes this permission instead of creating/updating it
list-api-tokens
List all API tokens for the account.
Parameters:
No parameters required
create-api-token
Create a new API token. The response includes the secret token value — this is the only time the full token is returned, so store it immediately. If you lose it, recreate the token.
Parameters:
name(required): Display name for the tokenexpires_at(optional): Token expiration as an ISO 8601 date-time. Omit for the server default (1 year); pass an explicitnullfor a token that never expires. Past values or values more than 5 years ahead are rejectedresources(optional): Array of resource permissions to scope the token to. Each entry has:resource_type(required): One ofaccount,project,inbox,domain,billingresource_id(required): ID of the resourceaccess_level(required):100(admin) or10(viewer)
get-api-token
Get an API token by ID. Returns metadata only — the secret token value is not returned here (only from create-api-token / reset-api-token).
Parameters:
api_token_id(required): ID of the API token
reset-api-token
Reset (rotate) an API token by ID. The response includes the new secret token value — returned only on this call, so store it immediately. The previous token is invalidated.
Parameters:
api_token_id(required): ID of the API token to resetexpires_at(optional): Expiration for the new token as an ISO 8601 date-time. Omit for the server default (1 year); pass an explicitnullfor a token that never expires. Past values or values more than 5 years ahead are rejected
delete-api-token
Permanently delete an API token by ID. The token can no longer authenticate after deletion.
Parameters:
api_token_id(required): ID of the API token to delete
list-sub-accounts
List sub-accounts in the organization. Requires MAILTRAP_ORGANIZATION_ID env var and sub-account management permissions.
Parameters:
No parameters required
create-sub-account
Create a new sub-account under the organization. Requires MAILTRAP_ORGANIZATION_ID env var and sub-account management permissions.
Parameters:
name(required): Display name for the new sub-account
list-inbound-folders
List all inbound folders in the account. Returns a formatted summary.
Parameters:
No parameters required
get-inbound-folder
Get a single inbound folder by ID. Returns the full folder record as JSON.
Parameters:
folder_id(required): ID of the inbound folder
create-inbound-folder
Create a new inbound folder.
Parameters:
name(required): The folder name
update-inbound-folder
Rename an inbound folder.
Parameters:
folder_id(required): ID of the inbound foldername(required): The new folder name
delete-inbound-folder
Permanently delete an inbound folder along with all of its inboxes.
Parameters:
folder_id(required): ID of the inbound folder
list-inbound-inboxes
List all inboxes in an inbound folder. Returns a formatted summary.
Parameters:
folder_id(required): ID of the inbound folder
get-inbound-inbox
Get a single inbound inbox by ID. Returns the full inbox record as JSON.
Parameters:
folder_id(required): ID of the inbound folderinbox_id(required): ID of the inbox
create-inbound-inbox
Create a new inbound inbox in a folder.
Parameters:
folder_id(required): ID of the inbound foldername(required): The inbox namedomain_id(optional): Attach to a custom sending domain (catch-all inbox). Omit for a Mailtrap-hosted inbox
update-inbound-inbox
Rename an inbound inbox.
Parameters:
folder_id(required): ID of the inbound folderinbox_id(required): ID of the inboxname(required): The new inbox name
delete-inbound-inbox
Permanently delete an inbound inbox.
Parameters:
folder_id(required): ID of the inbound folderinbox_id(required): ID of the inbox
list-inbound-messages
List received messages in an inbound inbox (cursor-paginated). Returns a formatted summary with a next-page hint when more results exist.
Parameters:
inbox_id(required): ID of the inboxlast_id(optional): Pagination cursor from a previous response'slast_id
get-inbound-message
Get a single inbound message with its full body and attachment download URLs. Returns the full message record as JSON.
Parameters:
inbox_id(required): ID of the inboxmessage_id(required): ID of the message
delete-inbound-message
Permanently delete an inbound message.
Parameters:
inbox_id(required): ID of the inboxmessage_id(required): ID of the message
reply-to-inbound-message
Reply to an inbound message (sends to the original sender). Sends a real email. Addresses accept a bare email string or { email, name? }.
Parameters:
inbox_id(required): ID of the inboxmessage_id(required): ID of the message to reply totext/html(at least one recommended): Reply bodyfrom(optional): Sender. Rejected for Mailtrap-hosted inboxes; required for custom-domain inboxescc/bcc/reply_to(optional): Additional addressescategory(optional): Message categoryattachments(optional): Array of{ content (base64), filename, type?, disposition?, content_id? }headers/custom_variables(optional): Objects of string values
reply-all-to-inbound-message
Reply to an inbound message and copy the original's other recipients. Sends a real email. Same parameters as reply-to-inbound-message.
Parameters:
inbox_id(required): ID of the inboxmessage_id(required): ID of the message to reply toPlus the same optional send fields as
reply-to-inbound-message
forward-inbound-message
Forward an inbound message to new recipients. Sends a real email.
Parameters:
inbox_id(required): ID of the inboxmessage_id(required): ID of the message to forwardto(required): At least one recipient (bare email string or{ email, name? }, or an array)Plus the same optional send fields as
reply-to-inbound-message
list-inbound-threads
List conversation threads in an inbound inbox (cursor-paginated). Returns a formatted summary with a next-page hint when more results exist.
Parameters:
inbox_id(required): ID of the inboxlast_id(optional): Pagination cursor from a previous response'slast_id
get-inbound-thread
Get a single inbound thread with its messages embedded (oldest first). Returns the full thread record as JSON.
Parameters:
inbox_id(required): ID of the inboxthread_id(required): ID of the thread
delete-inbound-thread
Permanently delete an inbound thread.
Parameters:
inbox_id(required): ID of the inboxthread_id(required): ID of the thread
Development
Clone the repository:
git clone https://github.com/mailtrap/mailtrap-mcp.git
cd mailtrap-mcpInstall dependencies:
npm installConfiguration with Claude Desktop or Cursor
See the location of the config file in theSetup section.
Add the following configuration:
{
"mcpServers": {
"mailtrap": {
"command": "node",
"args": ["/path/to/mailtrap-mcp/dist/index.js"],
"env": {
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id",
"MAILTRAP_TEST_INBOX_ID": "your_test_inbox_id"
}
}
}
}If you are using asdf for managing Node.js you should use absolute path to executable:
(example for Mac)
{
"mcpServers": {
"mailtrap": {
"command": "/Users/<username>/.asdf/shims/node",
"args": ["/path/to/mailtrap-mcp/dist/index.js"],
"env": {
"PATH": "/Users/<username>/.asdf/shims:/usr/bin:/bin",
"ASDF_DIR": "/opt/homebrew/opt/asdf/libexec",
"ASDF_DATA_DIR": "/Users/<username>/.asdf",
"ASDF_NODEJS_VERSION": "20.6.1",
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id",
"MAILTRAP_TEST_INBOX_ID": "your_test_inbox_id"
}
}
}
}VS Code
See the location of the config file in theSetup section.
{
"mcp": {
"servers": {
"mailtrap": {
"command": "node",
"args": ["/path/to/mailtrap-mcp/dist/index.js"],
"env": {
"MAILTRAP_API_TOKEN": "your_mailtrap_api_token",
"DEFAULT_FROM_EMAIL": "your_sender@example.com",
"MAILTRAP_ACCOUNT_ID": "your_account_id",
"MAILTRAP_TEST_INBOX_ID": "your_test_inbox_id"
}
}
}
}
}Testing
Running tools against real Mailtrap
There are two ways to exercise a tool end-to-end against a real Mailtrap account: the MCP Inspector browser UI for interactive exploration, or its CLI mode for one-shot calls from the shell.
Both require the bundle to be built first:
npm run buildand MAILTRAP_API_TOKEN + MAILTRAP_ACCOUNT_ID exported in your shell (the mcp:cli script forwards both to the spawned server).
Browser UI
npm run devThe Inspector prints a URL like http://localhost:6274. Open it, switch to the Tools tab, pick a tool (e.g. get-template), fill the parameters as JSON, and hit Run. The Mailtrap response appears in the panel below.
CLI
For one-shot calls without the UI, use npm run mcp:cli. Pass the Inspector's CLI flags after -- so npm forwards them verbatim:
# List all tools
npm run mcp:cli -- --method tools/list
# Call a tool — flags after the `--`
npm run mcp:cli -- \
--method tools/call \
--tool-name get-template \
--tool-arg template_id=12345
# Multiple --tool-arg flags for tools with several params
npm run mcp:cli -- \
--method tools/call \
--tool-name send-sending-domain-setup-instructions \
--tool-arg sending_domain_id=3938 \
--tool-arg email=devops@example.comRunning the MCPB Server
# Run the MCPB server directly
node dist/mcpb-server.js
# Or use the provided binary
mailtrap-mcpb-serverFor development with the MCP Inspector:
npm run dev:mcpbError Handling
This server uses structured error handling aligned with MCP conventions:
VALIDATION_ERROR: Input validation failuresCONFIGURATION_ERROR: Missing or invalid configurationEXECUTION_ERROR: Runtime execution errorsTIMEOUT: Operation timeout (30 seconds default)
Errors include actionable messages and are logged in structured form.
Security
Input validated via Zod schemas
Environment variables handled securely
Timeout protection on operations (30 seconds)
Sensitive details sanitized in error output
Logging
Structured JSON logs with levels: INFO, WARN, ERROR, DEBUG.
Enable debug logging by setting DEBUG=true.
# Example: enable debug logging
DEBUG=true node dist/mcpb-server.jsImportant: The server writes logs to stderr so stdout remains reserved for JSON-RPC frames. This prevents hosts from encountering JSON parsing errors due to interleaved logs.
Log analysis example using jq:
# Filter error logs
node dist/mcpb-server.js 2>&1 | jq 'select(.level == "error")'
# Filter debug logs
node dist/mcpb-server.js 2>&1 | jq 'select(.level == "debug")'Troubleshooting
Common issues:
Missing API Token: ensure
MAILTRAP_API_TOKENis setSandbox not working: provide
test_inbox_idin the tool call or setMAILTRAP_TEST_INBOX_IDenvTimeout errors: check network connectivity and Mailtrap API status
Validation errors: ensure all required fields are provided
Contributing
Bug reports and pull requests are welcome on GitHub. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
License
The package is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Mailtrap project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
Available Tools
8 toolscreate-templateBDestructive
Create a new email template
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Name of the template | |
| subject | Yes | Email subject line | |
| html | No | HTML content of the template (optional) | |
| text | No | Plain text version of the template (optional) | |
| category | No | Template category (optional, defaults to 'General') |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true, indicating this is a write operation. The description adds minimal behavioral context beyond that - it confirms creation but doesn't specify what happens on success/failure, whether templates are immediately usable, or any permissions required. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that states the core purpose without unnecessary words. It's appropriately sized for a creation tool with good schema documentation and gets straight to the point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a creation tool with destructiveHint annotation and no output schema, the description is minimally adequate. It identifies the resource type but doesn't explain what an email template entails in this system, how it's used, or what the creation result looks like. The combination of basic description and annotations provides the essentials but leaves contextual gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, all parameters are documented in the schema. The description adds no additional parameter information beyond what's already in the schema descriptions. The baseline score of 3 reflects adequate but not enhanced parameter documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('create') and resource ('email template'), making the purpose immediately understandable. However, it doesn't differentiate this tool from its sibling 'update-template' beyond the obvious verb difference, nor does it specify what distinguishes a template from other email-related resources in the system.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (like needing to be logged in), when to choose this over 'update-template' for existing templates, or how it relates to email-sending tools like 'send-email' or 'send-sandbox-email'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete-templateADestructive
Delete an existing email template
| Name | Required | Description | Default |
|---|---|---|---|
| template_id | Yes | ID of the template to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare destructiveHint=true, indicating this is a destructive operation. The description adds value by specifying 'Delete an existing email template,' which reinforces the destructive nature and clarifies the resource type. However, it doesn't provide additional behavioral details like confirmation prompts, error handling, or permissions required beyond what annotations imply.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, clear sentence with no unnecessary words. It's front-loaded with the core action and resource, making it highly efficient and easy to parse. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's destructive nature (annotations cover this) and simple single-parameter schema, the description is adequate but minimal. It lacks output information (no schema provided) and doesn't address error cases or dependencies on other tools (e.g., needing to list templates first). For a destructive tool, more context would be beneficial.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, with the 'template_id' parameter fully documented. The description doesn't add any parameter-specific information beyond what the schema provides, such as format examples or constraints. Since the schema coverage is high, the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Delete') and resource ('an existing email template'), making the purpose immediately understandable. However, it doesn't differentiate this tool from its sibling 'update-template' or 'list-templates' in terms of scope or intent, which prevents a perfect score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'update-template' or 'list-templates', nor does it mention prerequisites (e.g., needing a valid template_id). It simply states what the tool does without contextual usage information.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get-sandbox-messagesC
Get list of messages from the sandbox test inbox
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number for pagination | |
| last_id | No | Pagination using last message ID. Returns messages after the specified message ID. | |
| search | No | Search query to filter messages |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It states the action but lacks details on permissions, rate limits, response format, or whether this is a read-only operation. For a list operation with zero annotation coverage, this leaves significant gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that directly states the tool's purpose without unnecessary words or redundancy, making it appropriately front-loaded and concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of annotations and output schema, the description is incomplete. It doesn't explain the return format, pagination behavior beyond schema hints, or how it interacts with sibling tools, leaving the agent with insufficient context for a list operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, so the schema fully documents all three parameters (page, last_id, search). The description adds no additional parameter semantics beyond what the schema provides, meeting the baseline for high coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get' and resource 'list of messages from the sandbox test inbox', making the purpose understandable. However, it doesn't explicitly differentiate from sibling tools like 'show-sandbox-email-message' which might retrieve a single message, leaving some ambiguity about scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'show-sandbox-email-message' or 'send-sandbox-email', nor does it mention any prerequisites or contextual constraints for usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list-templatesBRead-only
List all email templates
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds minimal behavioral context beyond the readOnlyHint annotation. It doesn't specify whether this returns a paginated list, the format of returned templates, or any rate limits. However, it doesn't contradict the annotation (which correctly indicates a read-only operation).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero wasted words. It's appropriately sized for a simple list operation and front-loads the core purpose immediately.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only list tool with no parameters and no output schema, the description is minimally adequate. However, it lacks details about the return format (e.g., structured list vs. raw data) and doesn't leverage the sibling context to clarify its role in the template management workflow.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0 parameters and 100% schema description coverage, the description appropriately doesn't need to explain parameters. The baseline for this scenario is 4 since there are no parameters to document.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('List') and resource ('all email templates'), making the purpose unambiguous. However, it doesn't differentiate from potential sibling tools like 'get-sandbox-messages' or explain what distinguishes listing templates from other template operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'create-template', 'update-template', or 'delete-template'. It doesn't mention prerequisites, context for listing templates, or any exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send-emailBDestructive
Send an email to your recipient email address using Mailtrap Email API. You can send emails to multiple recipients at once.
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Email address of the sender | |
| to | Yes | Email address(es) of the recipient(s) - can be a single email or array of emails | |
| subject | Yes | Email subject line | |
| cc | No | Optional CC recipients | |
| bcc | No | Optional BCC recipients | |
| category | Yes | Email category for tracking | |
| text | No | Email body text | |
| html | No | Optional HTML version of the email body |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations include 'destructiveHint: true', indicating this is a write operation with potential side effects. The description adds that it uses 'Mailtrap Email API' and supports multiple recipients, providing some context beyond annotations. However, it doesn't disclose additional behavioral traits like rate limits, authentication needs, or what 'destructive' entails (e.g., email delivery, no undo). With annotations covering the safety profile, a 3 is appropriate for adding moderate value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise with two sentences: one stating the purpose and one adding a usage detail. It's front-loaded with the core functionality. However, the second sentence could be more informative (e.g., clarifying 'multiple recipients' vs. schema details), slightly reducing efficiency.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (8 parameters, destructive operation) and lack of output schema, the description is moderately complete. It covers the basic purpose and API context but lacks details on when to use, behavioral nuances, or return values. With annotations providing some safety info, it's adequate but has clear gaps for a mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, with clear documentation for all 8 parameters (e.g., 'from' as 'Email address of the sender'). The description doesn't add meaning beyond the schema, such as explaining parameter interactions or constraints. According to the rules, with high schema coverage (>80%), the baseline is 3 even without param info in the description.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Send an email to your recipient email address using Mailtrap Email API.' It specifies the action (send), resource (email), and technology (Mailtrap Email API). However, it doesn't explicitly differentiate from sibling tools like 'send-sandbox-email' or 'get-sandbox-messages', which would require a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides minimal usage guidance: 'You can send emails to multiple recipients at once.' It doesn't specify when to use this tool versus alternatives like 'send-sandbox-email' (e.g., for testing vs. production), nor does it mention prerequisites, exclusions, or context for use. This lack of explicit guidance limits its effectiveness.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send-sandbox-emailA
Send an email in sandbox mode to a test inbox without delivering to your recipients
| Name | Required | Description | Default |
|---|---|---|---|
| from | Yes | Email address of the sender | |
| to | Yes | Email addresses (comma-separated or single) | |
| subject | Yes | Email subject line | |
| cc | No | Optional CC recipients | |
| bcc | No | Optional BCC recipients | |
| category | No | Optional email category for tracking | |
| text | No | Email body text | |
| html | No | Optional HTML version of the email body |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds valuable behavioral context beyond the annotations. While annotations only indicate destructiveHint=false (non-destructive), the description clarifies that emails go to a 'test inbox' and won't reach actual recipients, which is crucial for understanding the tool's testing/simulation behavior. No contradiction with annotations exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that front-loads the key information (sandbox mode, test inbox, no delivery) with zero wasted words. Every element serves a clear purpose in distinguishing this tool's behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with good annotations (destructiveHint=false) and full schema coverage, the description provides sufficient context about the sandbox/testing behavior. The main gap is the lack of output schema, but the description compensates by clarifying the test inbox destination. It adequately covers the tool's purpose and usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage, all parameters are well-documented in the schema itself. The description doesn't add any parameter-specific information beyond what's in the schema, so it meets the baseline of 3 for adequate coverage without extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the specific action ('send an email') and resource ('in sandbox mode to a test inbox'), with explicit differentiation from normal email sending ('without delivering to your recipients'). It distinguishes from the sibling 'send-email' tool by specifying the sandbox/testing context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool ('in sandbox mode to a test inbox') and when not to use it ('without delivering to your recipients'), providing clear context for testing versus production email sending. It implicitly contrasts with the sibling 'send-email' tool for actual delivery.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
show-sandbox-email-messageB
Show sandbox email message details and content from the sandbox test inbox
| Name | Required | Description | Default |
|---|---|---|---|
| message_id | Yes | ID of the sandbox email message to retrieve |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries full burden. It states 'show' implies a read operation, but doesn't disclose behavioral traits like whether it requires authentication, rate limits, error handling (e.g., invalid message_id), or what 'details and content' includes (e.g., headers, body, attachments). This leaves significant gaps for a tool with no annotation coverage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero waste. It's front-loaded with the core purpose and includes essential context ('from the sandbox test inbox'), making it appropriately sized for a simple tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 1 parameter with full schema coverage and no output schema, the description is minimally adequate. It specifies the resource scope ('sandbox test inbox') but lacks behavioral details (e.g., response format, error cases) and usage guidelines, leaving room for improvement despite the tool's low complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, with 'message_id' documented as 'ID of the sandbox email message to retrieve'. The description adds no additional parameter semantics beyond this, such as format examples or constraints. Baseline 3 is appropriate when schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'show' and the resource 'sandbox email message details and content', specifying it's from the 'sandbox test inbox'. It distinguishes from siblings like 'get-sandbox-messages' (which likely lists messages) and 'send-sandbox-email' (which sends messages), but doesn't explicitly contrast them in the description text.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., needing a valid message_id from the sandbox), exclusions, or comparisons to sibling tools like 'get-sandbox-messages' for listing messages first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update-templateBDestructive
Update an existing email template
| Name | Required | Description | Default |
|---|---|---|---|
| template_id | Yes | ID of the template to update | |
| name | No | New name for the template | |
| subject | No | New email subject line | |
| html | No | New HTML content of the template | |
| text | No | New plain text version of the template | |
| category | No | New category for the template |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations include 'destructiveHint: true', which already indicates this is a mutation operation. The description adds minimal behavioral context beyond this, as 'Update an existing email template' implies modification but doesn't detail effects like whether changes are reversible, permission requirements, or rate limits. With annotations covering the destructive nature, the description provides basic but insufficient additional insight.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence with zero wasted words, front-loading the core action ('Update') and resource. It's appropriately sized for the tool's complexity, making it easy for an agent to parse quickly without unnecessary elaboration.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, destructive operation, no output schema), the description is inadequate. It lacks information on return values, error conditions, or how partial updates are handled (e.g., if only some fields are provided). With annotations covering only destructiveness, more context is needed for safe and effective use.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage, with each parameter clearly documented (e.g., 'template_id' as 'ID of the template to update'). The description adds no extra meaning beyond what the schema provides, such as explaining relationships between parameters or usage examples. Baseline 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Update') and resource ('an existing email template'), making the purpose immediately understandable. However, it doesn't differentiate from sibling tools like 'create-template' or 'list-templates' beyond the basic action, missing explicit comparison that would earn a perfect score.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives like 'create-template' for new templates or 'delete-template' for removal. It also doesn't mention prerequisites (e.g., needing an existing template ID) or contextual constraints, leaving the agent to infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
8 tool updates
v1.0.0- Added
create-template - Added
delete-template - Added
get-sandbox-messages - Added
list-templates - Changed
send-email8 fields changed- removed
Input schema / $schemaRemoved value: -"http://json-schema.org/draft-07/schema#" - changed
Input schema / properties / category / descriptionPrevious value: -"Optional email category for tracking"New value: +"Email category for tracking" - changed
Input schema / properties / from / descriptionPrevious value: -"Email address of the sender (optional with default)"New value: +"Email address of the sender" - changed
Input schema / properties / to / descriptionPrevious value: -"Email address of the recipient"New value: +"Email address(es) of the recipient(s) - can be a single email or array of emails" - removed
Input schema / properties / to / formatRemoved value: -"email" - added
Input schema / properties / to / oneOfAdded value: +[ + { + "description": "Single email address", + "format": "email", + "type": "string" + }, + { + "description": "Array of email addresses", + "items": { + "format": "email", + "type": "string" + }, + "type": "array" + } +] - removed
Input schema / properties / to / typeRemoved value: -"string" - changed
Input schema / requiredPrevious value: -[ - "to", - "subject" -]New value: +[ + "to", + "subject", + "category" +]
- Added
send-sandbox-email - Added
show-sandbox-email-message - Added
update-template
1 tool update
- First observed
send-email
TDQS
Every tool has a clearly distinct purpose with no ambiguity. Template management tools (create, delete, list, update) are separate from sandbox operations (get messages, send sandbox email, show message) and production email sending, making misselection unlikely.
Mostly consistent with a verb-noun pattern using kebab-case, but there is a minor deviation: 'get-sandbox-messages' and 'show-sandbox-email-message' both retrieve sandbox data with different verbs ('get' vs 'show'), slightly breaking the pattern.
Well-scoped with 8 tools, each earning its place. This covers core email sending workflows (production and sandbox) and template management (CRUD operations), fitting the server's purpose without being overwhelming.
Complete coverage for the email sending domain with no obvious gaps. It includes full CRUD for templates, sandbox testing (send, list, view), and production email sending, allowing agents to handle all typical email workflows without dead ends.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Send, track, and manage transactional and bulk email delivery
Send transactional email over a verified domain — templates, attachments, custom headers.
Send, track, and manage transactional emails at scale
Send transactional emails for AI agents via SMTP. Templates included.
Related MCP Servers
- AlicenseAqualityAmaintenanceEnables sending emails via SMTP with template management, supporting multiple SMTP configurations, template creation with variable substitution, and bulk email sending with rate limiting.623419MIT
- AlicenseBqualityDmaintenanceEnables sending single and batch emails through the Resend API with support for HTML/plain text content, CC/BCC recipients, and custom tracking tags.122Apache 2.0
- FlicenseBqualityNot gradedmaintenanceEnables sending emails and managing webhooks through the SendLayer API. Supports plain text and HTML emails with attachments, CC/BCC recipients, and webhook event management for email delivery tracking.5-
- AlicenseNot gradedqualityDmaintenanceEnables sending and managing emails via Postmark, including email delivery with templates, template listing, and delivery statistics.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mailtrap/mailtrap-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server