Full-featured email infrastructure for AI agents — send, receive, search, and reply over MCP.
Do not connect
A critical issue was found. Do not connect this server as-is.
Scanned 6 days ago
A server can change after it's graded. Re-run the automated scan to refresh this report.
This grade is deterministic and reproducible: the same server surface always yields the same grade under a given algorithm version. It is a real automated assessment computed by the MCPGrade engine from what the probe actually observed — not a fabricated or opinion score. It is not a manual human pentest, so it can miss context-specific risks.
Every signal below was measured directly by the automated probe. The grade is derived only from evidence like this — nothing is assumed.
The primitive MCP server exposes 30 tools, focused primarily on general-purpose capabilities. Its published description reads: "Full-featured email infrastructure for AI agents — send, receive, search, and reply over MCP". It communicates over Streamable HTTP using the 2026-07-28 protocol revision, and does not require authorization to connect. MCPGrade currently rates primitive F — a critical issue was found and the server should not be connected as-is. Its most notable findings include "Hidden instructions in a tool description" and "Hidden instructions in a tool description". This report is a deterministic, reproducible automated assessment: the same observed surface always yields the same grade under a given algorithm version, and it is refreshed as new scans arrive and free to read — but it is not a substitute for a manual human security review. Always re-check primitive's advertised tools, transport security, and authorization posture before connecting an autonomous agent or sharing sensitive context with it.
Add primitive to an MCP client using the endpoint below. Review the grade and findings above before granting an autonomous agent access.
MCP endpoint
https://www.primitive.dev/mcpStreamable HTTP transport. This is the MCP endpoint, not a website — paste it into your MCP client server list rather than a browser.
Captured passively during the read-only scan. Click any value to find servers that match it.
The tools this server advertises via tools/list — names, purposes, and the parameters each accepts, exactly as enumerated read-only.
List all inbound domains for the organization, both verified and unverified. Each domain includes its verification status and DNS records. Use before addDomain to check whether a domain is already cla
Claim a new domain and receive the DNS records to publish. Returns dns_records with the exact records to add. If the domain has an mx_conflict (existing mail provider), re-call with confirmed: true to
Check DNS records for a domain claim (MX, TXT, SPF, DKIM, DMARC). On success the domain becomes verified and starts receiving mail. On failure, returns which checks passed and which still need attenti
Sorted worst-first. Each finding shows its severity, what it means, its OWASP MCP Top-10 mapping, and a recommended fix — the check id links to the exact methodology row that produced it.
tool: sendEmail
A tool description contains imperative text aimed at the model (e.g. "ignore previous", "before answering read …").
h scheduled_at. IMPORTANT: `from` is YOUR OWN complete mailbox address, neRecommendationRemove model-directed instructions from tool descriptions.
tool: createEmailAddress
A tool description contains imperative text aimed at the model (e.g. "ignore previous", "before answering read …").
rns an api_key. IMPORTANT: pass that api_key as the `api_key` argument onRecommendationRemove model-directed instructions from tool descriptions.
tool: listDomains
A tool description tries to alter the model’s use of another tool.
rds. Use before addDomain to check whether a domain is already claimed.RecommendationDescriptions must describe only their own tool.
tool: addDomain
A tool description tries to alter the model’s use of another tool.
S records, call verifyDomain to complete setup.RecommendationDescriptions must describe only their own tool.
tool: getAccount
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
,"properties":{"api_key":{"type":"string","minLength":8,"maxLength":200RecommendationRemove side-channel parameters; constrain tool inputs.
tool: getAccount
A tool description tries to alter the model’s use of another tool.
ail, for use as sendEmail.requestBody.from.RecommendationDescriptions must describe only their own tool.
tool: getAccount
The input schema declares a parameter that asks the caller to hand over a password, key, token, or other secret — a credential-harvest / token-passthrough risk. (Bare pagination `token` params are excluded.)
parameter "api_key"RecommendationNever pass secrets as tool arguments; authenticate out-of-band and remove credential parameters from the schema.
tool: getInboxStatus
The input schema declares a parameter that asks the caller to hand over a password, key, token, or other secret — a credential-harvest / token-passthrough risk. (Bare pagination `token` params are excluded.)
parameter "api_key"RecommendationNever pass secrets as tool arguments; authenticate out-of-band and remove credential parameters from the schema.
tool: getOutboundStatus
A tool description tries to alter the model’s use of another tool.
all this BEFORE sendEmail to pick a valid `from` domain — the account emaRecommendationDescriptions must describe only their own tool.
tool: listEmails
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
ion":"Backward (history) pagination cursor from a previous response's `RecommendationRemove side-channel parameters; constrain tool inputs.
tool: listEmails
A tool description tries to alter the model’s use of another tool.
RecommendationDescriptions must describe only their own tool.
tool: listEmails
One tool reads private data, ingests untrusted content, AND can send data outbound — the three preconditions for autonomous data theft in a single call. A prompt injection reaching this tool can exfiltrate secrets with no further step.
hen you need to browse inbound emails received at verified domains with cursor paginaRecommendationSplit the capabilities across separate least-privilege tools so no single tool can read secrets, read untrusted input, and reach the network at once.
tool: listEmails
The input schema declares a parameter that asks the caller to hand over a password, key, token, or other secret — a credential-harvest / token-passthrough risk. (Bare pagination `token` params are excluded.)
parameter "api_key"RecommendationNever pass secrets as tool arguments; authenticate out-of-band and remove credential parameters from the schema.
tool: getEmail
The input schema declares a parameter that asks the caller to hand over a password, key, token, or other secret — a credential-harvest / token-passthrough risk. (Bare pagination `token` params are excluded.)
parameter "api_key"RecommendationNever pass secrets as tool arguments; authenticate out-of-band and remove credential parameters from the schema.
tool: replyToEmail
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
t_base64"]}}}},"api_key":{"type":"string","minLength":8,"maxLength":200RecommendationRemove side-channel parameters; constrain tool inputs.
tool: replyToEmail
The input schema declares a parameter that asks the caller to hand over a password, key, token, or other secret — a credential-harvest / token-passthrough risk. (Bare pagination `token` params are excluded.)
parameter "api_key"RecommendationNever pass secrets as tool arguments; authenticate out-of-band and remove credential parameters from the schema.
tool: sendEmail
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
o","subject"]},"api_key":{"type":"string","minLength":8,"maxLength":200RecommendationRemove side-channel parameters; constrain tool inputs.
tool: sendEmail
A tool description tries to alter the model’s use of another tool.
EmailAddress or getAccount for a managed inbox. AFTER sending, if you expeRecommendationDescriptions must describe only their own tool.
tool: sendEmail
The input schema declares a parameter that asks the caller to hand over a password, key, token, or other secret — a credential-harvest / token-passthrough risk. (Bare pagination `token` params are excluded.)
parameter "api_key"RecommendationNever pass secrets as tool arguments; authenticate out-of-band and remove credential parameters from the schema.
tool: sendEmailDemo
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
dEmail with the api_key it returns; that is the correct path for any geRecommendationRemove side-channel parameters; constrain tool inputs.
tool: sendEmailDemo
A tool description tries to alter the model’s use of another tool.
ation) and then sendEmail with the api_key it returns; that is the correcRecommendationDescriptions must describe only their own tool.
tool: listSentEmails
A tool description tries to alter the model’s use of another tool.
ses small — use getSentEmail to fetch a specific row with full body. UsefulRecommendationDescriptions must describe only their own tool.
tool: cancelScheduledSend
A tool description tries to alter the model’s use of another tool.
email id from a sendEmail response that used scheduled_at, or from listSeRecommendationDescriptions must describe only their own tool.
tool: awaitReply
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
ts to 30000."},"api_key":{"type":"string","minLength":8,"maxLength":200RecommendationRemove side-channel parameters; constrain tool inputs.
tool: awaitReply
A tool description tries to alter the model’s use of another tool.
er sendEmail or replyToEmail when you expect an answer. With only the sent eRecommendationDescriptions must describe only their own tool.
tool: awaitReply
The input schema declares a parameter that asks the caller to hand over a password, key, token, or other secret — a credential-harvest / token-passthrough risk. (Bare pagination `token` params are excluded.)
parameter "api_key"RecommendationNever pass secrets as tool arguments; authenticate out-of-band and remove credential parameters from the schema.
tool: getConversation
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
getConversation Get conversation Get the full conversation an iRecommendationRemove side-channel parameters; constrain tool inputs.
tool: getThread
Tools that execute commands / write files / make arbitrary requests are exposed without annotations or guards.
ection (inbound/outbound) and id; fetch inbound message bodies via getEmail, or outbounRecommendationAnnotate destructive tools and require human approval.
tool: getThread
A tool description tries to alter the model’s use of another tool.
sage bodies via getEmail, or outbound bodies via getSentEmail. DiscoverRecommendationDescriptions must describe only their own tool.
tool: downloadEmailAttachments
A tool description tries to alter the model’s use of another tool.
digest. Prefer getEmail first to check the attachment manifest before dRecommendationDescriptions must describe only their own tool.
tool: createEndpoint
A tool description tries to alter the model’s use of another tool.
creating, call testEndpoint to confirm your signature verifier accepts theRecommendationDescriptions must describe only their own tool.
tool: createEmailAddress
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
signup form, no password, no email verification, no browser. CALL THIS FRecommendationRemove side-channel parameters; constrain tool inputs.
tool: createEmailAddress
A tool description tries to alter the model’s use of another tool.
t a website. On first use the REST response's address field is a domain suRecommendationDescriptions must describe only their own tool.
tool: createEmailAddress
One tool reads private data, ingests untrusted content, AND can send data outbound — the three preconditions for autonomous data theft in a single call. A prompt injection reaching this tool can exfiltrate secrets with no further step.
m to sign up or visit a website. On first use the REST response's address fieldRecommendationSplit the capabilities across separate least-privilege tools so no single tool can read secrets, read untrusted input, and reach the network at once.
tool: (server instructions)
A tool exposes a free-text/webhook/feedback parameter with no honest purpose — a classic exfil channel.
signup form, no password and no verification email, returns an api_key,RecommendationRemove side-channel parameters; constrain tool inputs.
tool: (server instructions)
A tool description tries to alter the model’s use of another tool.
InboxStatus and getAccount. Hosts that cannot set an Authorization headerRecommendationDescriptions must describe only their own tool.
The server accepts tool enumeration (and likely invocation) with no authentication.
RecommendationRequire OAuth 2.1 authorization for any server exposing non-public tools.
tool: replyToEmail
The server advertises open-world / broadly-scoped capabilities.
annotations.destructiveHint = trueRecommendationScope tools to the minimum needed.
tool: sendEmail
The server advertises open-world / broadly-scoped capabilities.
annotations.destructiveHint = trueRecommendationScope tools to the minimum needed.
tool: cancelScheduledSend
The server advertises open-world / broadly-scoped capabilities.
annotations.destructiveHint = trueRecommendationScope tools to the minimum needed.
tool: deleteEndpoint
The server advertises open-world / broadly-scoped capabilities.
annotations.destructiveHint = trueRecommendationScope tools to the minimum needed.
tool: deleteFilter
The server advertises open-world / broadly-scoped capabilities.
annotations.destructiveHint = trueRecommendationScope tools to the minimum needed.
The server exposes one or more ui:// (MCP Apps) resources whose HTML/JS renders inside the host client — a client-side injection / data-exposure surface most scanners ignore. Flagged for review, not damning on its own.
1 ui:// resource(s); e.g. ui://widget/primitive-email-v1.htmlRecommendationReview each ui:// resource’s markup and scripts; treat host-rendered UI as untrusted, sandbox it, and never expose secrets or conversation context to it.
Vantaj uptime monitoring via MCP — manage monitors, heartbeats, incidents, and status pages.
Unified gateway to Algeria's TKAWEN ecosystem: commerce, certification, and AI tools.
Provides access to the Cohereon Doctrine AI safety framework with governance components, tiered access, and agent onboarding.
Agentic rails for complex workflows with receipts, fees, and MCP tool access.
Structural TC39 spec lookup for ECMA-262 and ECMA-402 in AI agents, SHA-pinned and offline-first.
Structural TC39 spec lookup for ECMA-262 and ECMA-402 in AI agents, SHA-pinned and offline-first.
Download a BIND-format DNS zone file for a domain. Useful when users want to import all required DNS records at once rather than copying them individually. Returns plain text in BIND zone file format.
Use this when you need the authenticated Primitive account summary, including plan, onboarding state, and managed inbox domain. managed_inbox_address is a domain, not a complete mailbox. When it is no
Use this when the user asks whether inbound email is ready or needs setup. Returns domains, routes, deployed Functions, and recent inbound activity.
What can I send FROM? Lists this account's verified outbound (sendable) domains plus any domains still pending DNS verification, with next actions. Call this BEFORE sendEmail to pick a valid `from` do
Use this when you need to browse inbound emails received at verified domains with cursor pagination, status filters, date filters, or sender/recipient search.
Use this when you need to find inbound emails with structured filters or full-text matching. Use sort=received_at_asc plus date_from for new-mail polling.
Use this when you need full details for one inbound email ID, including parsed bodies, threading metadata, SMTP envelope, webhook state, and replies.
Use this when the user has selected a specific inbound email and confirmed a reply. Sends real outbound email with threading handled server-side.
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 sche
SIMULATION ONLY: nothing is delivered. NEVER call this when the user actually wants an email to arrive, and never describe its result as a sent email: no message is sent, queued, or stored, and the re
List outbound emails sent by this org, with cursor pagination and filters. Bodies are omitted from list rows to keep responses small — use getSentEmail to fetch a specific row with full body. Useful f
Get the full record for a single sent email by id, including body_text and body_html. Use to inspect delivery details for a specific send — e.g. the SMTP response on a bounced row, or the gate denial
Cancel a still-scheduled send before it dispatches (terminal status "canceled"; the same idempotency key becomes reusable). Pass the sent email id from a sendEmail response that used scheduled_at, or
Wait for the threaded reply to a sent email. Call this immediately after sendEmail or replyToEmail when you expect an answer. With only the sent email's id it long-polls for up to 30 seconds by defaul
Get the full conversation an inbound email belongs to as ordered, chat-model-ready turns with bodies. Each message is oldest-first with a direction (inbound/outbound) and a derived role (inbound→user,
Get a conversation thread by id: metadata plus all inbound and outbound messages interleaved oldest-first. Each message has a direction (inbound/outbound) and id; fetch inbound message bodies via getE
Download all attachments for an inbound email as a gzip-compressed tar archive. Returns the archive as a base64-encoded string along with the attachment count and SHA-256 digest. Prefer getEmail first
List all active webhook endpoints for the organization. Each endpoint shows its URL, enabled state, and optional domain restriction.
Create a webhook endpoint to receive email.received events. If an endpoint with the same URL already exists but is deactivated, it is reactivated. After creating, call testEndpoint to confirm your sig
Soft-delete a webhook endpoint. The endpoint will no longer receive deliveries.
Send a sample email.received event to a webhook endpoint to verify your signature verifier. Rate limited to 4/min and 30/hr. Successful deliveries and verified-domain endpoints are exempt.
List all whitelist and blocklist filter rules for the organization.
Create a whitelist or blocklist filter rule. Patterns are stored lowercase. Per-domain filters require a Pro plan.
Delete a filter rule.
List webhook delivery attempts with pagination and filters. Each delivery includes the target endpoint and a nested email object with sender/recipient/subject. Useful for diagnosing delivery failures
Re-send a stored webhook payload from a previous delivery attempt to its original endpoint. Rate limited per org (burst + sustained windows, shared budget with email webhook replays).
Get this user's Primitive managed inbox domain, creating the account on first use: no signup form, no password, no email verification, no browser. CALL THIS FIRST whenever you do not already have a Pr