Send email and SMS from an n8n AI agent with MCP
Unitpost has no native n8n node, so there are two routes. Attach an MCP Client Tool to the AI Agent with the endpoint https://mcp.unitpost.com/mcp?toolsets=sending,sms, Server Transport set to HTTP Streamable and a Bearer Auth credential holding a scoped API key, then include only email_send and sms_send. Or attach an HTTP Request node as a tool that posts to /api/v1/email, and let the model fill only the fields you leave open.
Unitpost ·
n8n's AI Agent node decides which tools to call. Unitpost doesn't ship an n8n node, but an n8n agent can use the same tools Claude or Cursor use, through Unitpost's hosted MCP server, or call the REST API through the HTTP Request node. Both routes end in the same API call, with the same scopes, rate limits and verified-domain gate.
MCP Client Tool or HTTP Request: which one?
n8n's MCP servers page states the trade-off well: a built-in tool gives you tighter control, because you fix the operation and pin parameters so the model fills only what you leave open, while an MCP server gives the agent more room, at the cost of control and more context per call.
- MCP Client Tool. The agent gets Unitpost's tools with their descriptions and input schemas, can read a send back with
email_get, and gets a hint with each error. Use it when the agent should decide what to send, inside a list of tools you allow. - HTTP Request tool. You fix the URL, the From address and, if you like, the recipient. The model writes only the subject and the text. Use it when the agent drafts and your workflow decides who gets it.
Create a key for the workflow
In Unitpost, open Settings → API keys. The Sending only preset works on every plan. On a paid plan, open Advanced and keep only emails:send, plus sms:send if the agent texts. Give each workflow its own key, so you can revoke one without stopping the others.
The key goes into an n8n credential, not into a node, so it never appears in the workflow's JSON.
n8n's MCP OAuth2 credential is the other option. By default it registers itself with the server through Dynamic Client Registration, which Unitpost's authorization server accepts for an https callback, or a localhost one. Unitpost's consent screen marks a self-registered client's name as unverified. For a workflow on a server with nobody at a browser, a key is simpler: you choose its exact scopes and revoke it in one place.
How do I connect the MCP Client Tool?
- Add an AI Agent node. Per n8n's AI Agent docs, it needs a chat model and at least one tool sub-node.
- On its Tools connector, add an MCP Client Tool.
- Endpoint:
https://mcp.unitpost.com/mcp?toolsets=sending,sms, or?toolsets=sendingfor email only. Thetoolsetsparameter lists those groups instead of the full default set, which keeps tool definitions out of the model's context. - Server Transport: HTTP Streamable. Unitpost's server answers POST and keeps no SSE stream, so the Server Sent Events option won't connect.
- Authentication: Bearer Auth. In the credential's Bearer Token field, paste only the
pk_live_…value. n8n sends it asAuthorization: Bearer <token>. - Tools to Include: Selected, then
email_sendandsms_send, plusemail_getif the agent should check a send.
One naming wrinkle: n8n's page for this node still calls the URL field SSE Endpoint. That is the node's first version. In the node's source, versions 1.1 and later show Endpoint and Server Transport, and HTTP Streamable is the default from 1.2.
email_send takes the API's body fields and an idempotency_key. Have the agent derive the key from the thing it is working on, such as an order or ticket id: the same key within 24 hours returns the first result instead of sending twice, and the same key with a different body is refused with a 409. When a call fails, the agent gets the API's { error: { code, message, details } } and a hint with the next move.
How do I call the API with the HTTP Request node instead?
The HTTP Request node can run as a regular step or attached to an AI Agent as a tool. Attach it, choose Import cURL, and paste Unitpost's send example:
curl https://www.unitpost.com/api/v1/email \
-H "Authorization: Bearer $UNITPOST_API_KEY" \
-H "Content-Type: application/json" \
-H "User-Agent: my-app/1.0" \
-d '{
"from": "Acme <you@yourdomain.com>",
"to": "customer@acme.com",
"subject": "Welcome aboard",
"html": "<p>Thanks for signing up.</p>"
}'Then adjust what the import filled in:
- Delete the Authorization header and set Authentication to a Generic Credential Type, Bearer Auth, with the key's credential.
- Keep
fromfixed. Fixtotoo, from the item the workflow is handling, unless the agent must choose the recipient. - Replace the subject with
{{ $fromAI('subject') }}and swaphtmlfortextwith{{ $fromAI('body', 'Plain-text email body') }}.$fromAI()works only in tools connected to the AI Agent, and its arguments are hints to the model, not references to existing values. - Add an
Idempotency-Keyheader built from the same stable id.
For a text, post to https://www.unitpost.com/api/v1/sms with to in E.164 format and body. Without a paid plan, it answers 403 limit_reached.
How do I keep the agent inside a lane?
Put a person in front of the sends that matter. n8n can require human review for a tool: the workflow pauses, a reviewer sees the tool and its parameters in Chat, Slack, Gmail, Teams or another channel, and approves or denies. A denied call doesn't run, and the agent is told. Use it for sms_send, for anything to a new recipient, and for anything one-to-many. How to make an AI agent ask before it sends email covers which sends deserve it.
Unitpost holds its side whatever the workflow does:
- A From address on a domain that isn't verified in the key's workspace gets
403 domain_not_verified. - An address that hard bounced or complained is on the suppression list, and every send skips it.
- A key without
sms:sendcan't text, however the agent asks.
One rule no setting enforces for you: send only transactional mail and mail to people who opted in. An agent that finds addresses on the web and writes to them is cold outreach, and Unitpost's Acceptable Use Policy prohibits it on every plan, B2B included.