# Cursor, Claude Code: free email, SMS and WhatsApp in one prompt?

> Connect one MCP server, paste one prompt: Cursor, Claude Code or Windsurf adds email, SMS and WhatsApp to your app. Free plan, no credit card.

Source: https://unlimitedmessaging.app/articles/cursor-claude-code-messaging

Cursor + Claude Code guide

# Let your coding agent  
_wire email, SMS and WhatsApp._

Connect the Unlimited Messaging MCP server to Cursor, Claude Code or Windsurf, paste one prompt, and the agent writes a notify module, sends a real test from your own accounts and checks that it arrived.

[Get a free API key](https://app.unlimitedmessaging.app)[MCP server guide](https://unlimitedmessaging.app/articles/mcp)

The short answer

## How do Cursor and Claude Code add email, SMS and WhatsApp to an app?

Give the agent two things: the Unlimited Messaging [MCP server](https://modelcontextprotocol.io) at https://mcp.unlimitedmessaging.app, so it can see your accounts and send a test message, and an API key in your .env, which the code it writes reads to call POST /message. One request then sends email, WhatsApp and SMS from your own accounts, on a free plan.

Coding agents are good at writing a fetch call and bad at guessing whether it worked. The MCP connection closes that gap: while it builds, the agent can list the mailboxes, WhatsApp numbers and Android phones you connected, send a test after you confirm, and read the delivery status, all through OAuth with no key pasted into the chat.

In your app itself, the code uses the REST API or the TypeScript and Python SDKs with an API key from the environment. Unlimited Messaging sends from accounts you already own: email from your Gmail or domain mailbox over IMAP/SMTP, WhatsApp from your number linked like WhatsApp Web, SMS from your Android phone's SIM. The free plan has no per-message fee; messages end with a short "Sent with UnlimitedMessaging.app" line.

It works the same in Cursor, Claude Code and Windsurf, and in any MCP client that supports remote servers with OAuth. None of them has an official partnership with Unlimited Messaging: they speak the open MCP protocol, and that is enough.

The MCP server in detail: [MCP guide](https://unlimitedmessaging.app/articles/mcp). In the Claude apps: [Claude setup](https://unlimitedmessaging.app/articles/mcp-claude). Typed client for your code: [the TypeScript SDK](https://unlimitedmessaging.app/articles/typescript-sdk).

![Illustration: an AI assistant wired to chat, email, calendar and contacts, with the headline “Your coding agent wires the messages”.](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fcursor-claude-code-messaging-en.png&w=3840&q=75)

Definition
MCP (Model Context Protocol)

An open protocol that lets an AI assistant call tools on an outside service. Cursor, Claude Code and Windsurf all connect to remote MCP servers over HTTP, with OAuth sign-in.

The Unlimited Messaging server exposes list-accounts, list-messages and send-message.

[Source: modelcontextprotocol.io↗](https://modelcontextprotocol.io)

Why not hand-code it

## Why is it slow to let an agent hand-code SMTP, Twilio and Meta?

The agent writes the integration in a minute. Then the real work starts: accounts, verification, platform rules and silent failures it cannot see.

1. 01  
### Email: the SMTP snippet breaks in production  
Agents love nodemailer, but Vercel blocks outgoing SMTP on port 25 and Supabase Edge Functions refuse ports 25 and 587\. Switching to an email API means a verified domain and DNS records before anyone but you gets mail.
2. 02  
### SMS: a number, a registration, a fee per segment  
Twilio bills $0.0083 per segment in the US plus carrier fees, on a number you rent. Sending to US numbers from a regular long code also requires A2P 10DLC registration, with a $4.50 brand fee and vetting.
3. 03  
### WhatsApp: templates and a review queue  
Meta's Cloud API needs an approved template for any message outside the 24-hour customer service window, with review taking up to 24 hours and a price per template message. New accounts start at 250 unique recipients per 24 hours.
4. 04  
### The agent cannot check its own work  
Without a way to see the provider's side, the agent declares victory when the code compiles. Three providers also mean three keys in .env, three error formats and three webhook handlers to review.

Two ways in

## MCP or API: which does the agent use, and when?

The MCP server is for the agent while it builds. The API key is for your app once it runs. Most projects use both.

__MCP or API: which does the agent use, and when?__
| Hand-coded providersSMTP, Twilio, Meta | [Unlimited Messaging MCP](https://github.com/UnlimitedMessaging/unlimited-messaging-mcp)In the coding agent | Unlimited Messaging APIIn your app's code |                                              |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------- | -------------------------------------------- |
| Who sends                              | Your app, through three providers                                                                           | The agent, after you confirm              | Your app, through one endpoint               |
| Authentication                         | Three sets of credentials                                                                                   | OAuth in the browser, no key in files     | One API key from the environment             |
| Channels                               | One provider per channel                                                                                    | Email, WhatsApp and SMS                   | Email, WhatsApp and SMS in one request       |
| Can check delivery                     | Only through each provider's dashboard                                                                      | Yes, list-messages with statuses          | Yes, GET /message and webhooks on paid plans |
| Cost to test                           | Trials, then per message                                                                                    | Free plan                                 | Free plan, footer line on messages           |

Provider fees from Twilio's and Meta's own pages, checked on 9 November 2026.

Step by step

## From zero to a tested integration in five steps

1. 01  
### Connect the MCP server  
Claude Code: run the one-line claude mcp add command below. Cursor: add the block to .cursor/mcp.json. Windsurf: add it to mcp\_config.json with serverUrl.
2. 02  
### Sign in through OAuth  
On the first tool call, your browser opens the Unlimited Messaging sign-in. No account yet? It is created on the free plan, with no credit card. In Claude Code, /mcp starts the sign-in.
3. 03  
### Connect your channels  
Ask the agent to connect your mailbox or your WhatsApp (it shows the QR code), and install the Android app on a phone with a SIM for SMS.
4. 04  
### Create an API key for the app  
In the dashboard's API section, create a key and put it in .env as UM\_API\_KEY yourself. The agent only needs the variable name.
5. 05  
### Paste the prompt  
The agent writes the module, wires it to your trigger, then sends a test to you through MCP and confirms the status.

Copy, paste

## What prompt do you paste into Cursor or Claude Code?

Paste this into the agent chat, in Agent mode. It works in Cursor, Claude Code and Windsurf. Name the event that should trigger the message.

Prompt for Cursor, Claude Code or WindsurfPrompt

```
Add Unlimited Messaging to this project so it can send email, WhatsApp and SMS (docs: https://docs.unlimitedmessaging.app).

1. Create a server-side module, src/lib/notify.ts (or notify.py), that calls POST https://api.unlimitedmessaging.app/message with "Authorization: Bearer ${UM_API_KEY}" and the body { "to": { "phone": "<E.164>", "email": "<email>" }, "subject": "...", "text": "...", "channels": [{ "channel": "EMAIL" }, { "channel": "WHATSAPP" }, { "channel": "SMS" }] }. Throw on a non-2xx response with the body in the error.
2. Read UM_API_KEY from the environment. Add it to .env.example with an empty value, check that .env is in .gitignore, and never read, print or hardcode the real key.
3. Call notify() when <your event: signup, new order, failed payment...>, only from server code.
4. Use the unlimited-messaging MCP tools: list-accounts to see which channels I connected (drop the others from the call), then, after asking me, send-message to my own contact as a test, and list-messages to confirm its status.
```

Step 4 is what MCP adds: the agent checks your connected channels and verifies a real delivery instead of assuming the code works.

MCPClaude Code / Cursor / Windsurf

```
# Claude Code
claude mcp add --transport http unlimited-messaging https://mcp.unlimitedmessaging.app

# Cursor: ~/.cursor/mcp.json or .cursor/mcp.json
{ "mcpServers": { "unlimited-messaging": { "url": "https://mcp.unlimitedmessaging.app" } } }

# Windsurf: mcp_config.json
{ "mcpServers": { "unlimited-messaging": { "serverUrl": "https://mcp.unlimitedmessaging.app" } } }
```

Connecting the hosted server in each tool. All three sign in with OAuth on first use, so no key goes into these files.

notify.tsTypeScript

```
// src/lib/notify.ts (server-side only)
type Channel = 'EMAIL' | 'WHATSAPP' | 'SMS';

export async function notify(
  to: { phone?: string; email?: string },
  text: string,
  channels: Channel[],
  subject?: string,
) {
  const res = await fetch('https://api.unlimitedmessaging.app/message', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.UM_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      to, text, subject,
      channels: channels.map((channel) => ({ channel })),
    }),
  });
  if (!res.ok) throw new Error(`notify failed: ${res.status} ${await res.text()}`);
  return res.json(); // one message per channel, sharing a dispatchId
}
```

The kind of module the agent should write: server-side, one request, the key from the environment, errors surfaced.

Safety

## How do you keep the API key away from the agent and the repo?

The key belongs in .env, read by server code. Each tool gives you a way to keep the agent out of that file.

1. 01  
### MCP needs no key at all  
The agent's connection uses OAuth: tokens are stored by the client and can be revoked, in Claude Code from the /mcp menu. Nothing secret goes into .cursor/mcp.json or .mcp.json, so those files are safe to commit.
2. 02  
### Claude Code: deny reading .env  
Anthropic's settings docs show permission rules such as Read(./.env) and Read(./.env.\*) under deny. Add them to .claude/settings.json and Claude Code cannot open the file.
3. 03  
### Cursor: .cursorignore, with its limits  
Files listed in .cursorignore are blocked from Agent, Tab, Inline Edit and @ mentions. Cursor's docs warn that terminal and MCP tools used by the agent are not covered, so do not rely on it alone.
4. 04  
### Server code only  
Never prefix the key with NEXT\_PUBLIC\_ or VITE\_, and never import the notify module from client components. Review the agent's diff for that before you commit.
5. 05  
### Keep the confirmation on  
send-message sends real messages from your accounts. The server tells assistants to confirm each send, and your editor can ask before each tool call: do not auto-approve this one.

Replies

## How does your app receive replies?

Replies always show up in the Unlimited Messaging inbox, and the agent can read them through list-messages while you build. For your app to react to them in production, you need webhooks, which come with the paid plans: Medium at €19 a month and Max at €29 a month.

Ask the agent for a webhook route, register its public URL on the Webhooks page of the dashboard, and subscribe to message.received (an inbound message) and message.status (sent, delivered, read, failed). Store the whsec\_ secret as UM\_WEBHOOK\_SECRET in .env.

Deliveries are signed per the Standard Webhooks spec, with an HMAC-SHA256 over the raw body in the webhook-signature header. Answer 2xx within 10 seconds and process afterwards. Retries run for a little more than 3 days, so deduplicate on eventId.

message.receivedJSON

```
{
  "type": "message.received",
  "eventId": "whd_...",
  "occurredAt": "2026-11-09T10:00:01.000Z",
  "data": {
    "channel": "WHATSAPP",
    "message": {
      "text": "Yes, see you Monday!"
    }
  }
}
```

A message.received event, shortened. data.message carries the sender and the text, plus subject and attachments for an email.

verify-webhook.tsTypeScript

```
import { createHmac } from 'node:crypto';
import { Buffer } from 'node:buffer';

// Standard Webhooks signature check, before trusting the body.
export function isValid(rawBody: string, h: Headers, secret: string) {
  const id = h.get('webhook-id');
  const ts = h.get('webhook-timestamp');
  const sig = h.get('webhook-signature') ?? '';
  if (!id || !ts || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const key = Buffer.from(secret.replace(/^whsec_/, ''), 'base64');
  const expected = createHmac('sha256', key)
    .update(`${id}.${ts}.${rawBody}`)
    .digest('base64');
  return sig.split(' ').some((s) => s === `v1,${expected}`);
}
```

The signature check to ask for. Read the raw body first, verify, and only then parse the JSON.

Limits

## What are the limits, honestly?

Unlimited Messaging sends from personal accounts at a human pace: right for notifications and conversations, wrong for blasts.

1. 01  
### WhatsApp is unofficial  
Your number is linked as a device, like WhatsApp Web, outside Meta's Business Platform. Unsolicited messages get numbers banned. For official WhatsApp at scale, use Meta's Cloud API.
2. 02  
### Email follows your mailbox  
A personal Gmail account sends up to 500 emails a day. Newsletters and large volumes belong with an email service provider.
3. 03  
### SMS at Android's pace  
Android asks for confirmation beyond 30 SMS in 30 minutes, so the app spaces messages out. Texts count against your carrier plan, and the sending phone must be an Android.
4. 04  
### Free plan trade-offs  
Messages on Free end with "Sent with UnlimitedMessaging.app". Media, voice messages and webhooks need Medium or Max, which also remove the footer.

Key takeaway

### MCP for the agent, an API key for the app.

Connect https://mcp.unlimitedmessaging.app so the agent can see your channels and verify a real send, keep UM\_API\_KEY in .env where the agent cannot read it, and ship one POST /message call that covers email, WhatsApp and SMS. Free until you need webhooks, media or no footer.

FAQ

## Questions about messaging with coding agents

Cursor writes the code that sends them, and with the Unlimited Messaging MCP server connected, its agent can also send a test email itself after you approve the tool call. Your app then sends from your own mailbox through POST /message, on the free plan.

Yes. Run claude mcp add --transport http unlimited-messaging https://mcp.unlimitedmessaging.app, sign in with /mcp, and install the free Android app on a phone with a SIM. Claude Code can then send an SMS from that number after asking you, and wire the same call into your code.

Yes. Add the server to mcp\_config.json with "serverUrl": "https://mcp.unlimitedmessaging.app". Windsurf's Cascade supports OAuth for remote HTTP servers.

No. The MCP connection uses OAuth, so the agent never needs the key. Put UM\_API\_KEY in .env yourself, deny reads of .env in Claude Code, list it in .cursorignore in Cursor, and give the agent only the variable name.

No. Unlimited Messaging has no partnership with Cursor, Anthropic or Windsurf. It is a standard remote MCP server and a REST API that these tools can use like any other.

Same prompt. The agent can call the REST endpoint with httpx or requests, or install the SDK with pip install unlimited-messaging and use UnlimitedMessagingApi with messages.message\_send.

Sources

## Sources & references

To check the information in this article for yourself:

1. [01Model Context Protocol - official documentation↗Model Context Protocol](https://modelcontextprotocol.io)
2. [02Connect Claude Code to tools via MCP (claude mcp add --transport http, /mcp OAuth)↗Claude Code documentation - Anthropic](https://code.claude.com/docs/en/mcp)
3. [03Settings (permissions deny Read(./.env))↗Claude Code documentation - Anthropic](https://code.claude.com/docs/en/settings)
4. [04Model Context Protocol (mcp.json, remote url, OAuth)↗Cursor documentation](https://cursor.com/docs/context/mcp)
5. [05Ignore files (.cursorignore and what it does not cover)↗Cursor documentation](https://cursor.com/docs/context/ignore-files)
6. [06Cascade MCP integration (serverUrl, OAuth for remote servers)↗Windsurf documentation](https://docs.devin.ai/windsurf/plugins/cascade/mcp)
7. [07Unlimited Messaging MCP server - client configs↗GitHub - UnlimitedMessaging](https://github.com/UnlimitedMessaging/unlimited-messaging-mcp)
8. [08Can I use SMTP with Vercel? (port 25 blocked)↗Vercel Knowledge Base](https://vercel.com/kb/guide/serverless-functions-and-smtp)
9. [09Edge Function limits (ports 25 and 587 not allowed)↗Supabase documentation](https://supabase.com/docs/guides/functions/limits)
10. [10SMS pricing in the United States ($0.0083 per segment)↗Twilio](https://www.twilio.com/en-us/sms/pricing/us)
11. [11A2P 10DLC Brand Registration ($4.50 brand fee)↗Twilio](https://www.twilio.com/docs/trust-hub/registrations/a2p-10dlc-brand)
12. [12Message template review (decision within 24 hours)↗Meta for Developers](https://developers.facebook.com/documentation/business-messaging/whatsapp/templates/template-review)
13. [13WhatsApp messaging limits (250 unique recipients per 24 hours to start)↗Meta for Developers](https://developers.facebook.com/documentation/business-messaging/whatsapp/messaging-limits)
14. [14Limits for sending and getting mail (500 emails a day)↗Gmail Help](https://support.google.com/mail/answer/22839)
15. [15SmsUsageMonitor (30 SMS in 30 minutes threshold)↗Android Open Source Project](https://android.googlesource.com/platform/frameworks/opt/telephony/+/refs/heads/main/src/java/com/android/internal/telephony/SmsUsageMonitor.java)
16. [16Standard Webhooks specification↗Standard Webhooks](https://www.standardwebhooks.com)

![Ilian, senior software engineer](https://ilianazz.com/images/iliazz.png)

Written by

[Ilian](https://unlimitedmessaging.app/authors/ilian) · Senior Software Engineer

A senior software engineer, he founds and runs several tech companies. He builds products around messaging APIs, automation and AI integration, and shares here what he learns while building.

[View LinkedIn profile↗](https://www.linkedin.com/in/ilianAzz/)Updated November 9, 2026

![](https://unlimitedmessaging.app/assets/logos/whatsapp.svg)![](https://unlimitedmessaging.app/assets/logos/email.svg)![](https://unlimitedmessaging.app/assets/logos/sms.svg)

## Give your agent a mailbox, a number and a phone.

Create a free account, connect the MCP server in your editor, and paste the prompt.

[Get a free API key→](https://app.unlimitedmessaging.app)

Similar articles
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fmcp-en.png&w=3840&q=75)What is a WhatsApp MCP server? The 2026 guideConnect any MCP-compatible AI assistant to WhatsApp via OAuth 2.0.](https://unlimitedmessaging.app/articles/mcp)
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Ftypescript-sdk-en.png&w=3840&q=75)Send WhatsApp from Node.js with a fully typed SDKFully typed npm package for Node.js, Next.js, and any JS environment.](https://unlimitedmessaging.app/articles/typescript-sdk)
* [![](https://unlimitedmessaging.app/_next/image?url=%2Fassets%2Farticles%2Fcovers%2Fai-agent-send-sms-en.png&w=3840&q=75)Can Claude or ChatGPT send SMS for you? Yes, here is howSMSAn AI assistant texts from your own Android phone and number over MCP, and asks before each send.](https://unlimitedmessaging.app/articles/ai-agent-send-sms)
