sendhustle-mcp
# sendhustle-mcp
The official [SendHustle](https://www.sendhustle.com) MCP server. It gives your AI agent native access to the SendHustle email API over the [Model Context Protocol](https://modelcontextprotocol.io) — send and manage emails, domains, contacts, audiences, and campaigns using natural language.
Supports both **stdio** (default) and **HTTP** (Streamable HTTP) transports, and runs with `npx` in any MCP client.
## Install
No install needed — run it on demand with `npx`:
```bash
npx -y sendhustle-mcp
```
### Prerequisites
- [Create an API key](https://www.sendhustle.com/docs/api-keys/overview) (looks like `sh_xxxxxxxxx`).
- [Verify a domain](https://www.sendhustle.com/docs/domains/managing) to send from.
## Configuration
Set your API key via the `SENDHUSTLE_API_KEY` environment variable. Add the server to your MCP client of choice:
### Claude Code
```bash
claude mcp add sendhustle -e SENDHUSTLE_API_KEY=sh_xxxxxxxxx -- npx -y sendhustle-mcp
```
### Codex
```bash
codex mcp add sendhustle --env SENDHUSTLE_API_KEY=sh_xxxxxxxxx -- npx -y sendhustle-mcp
```
### Cursor / Claude Desktop / Windsurf / Gemini CLI
```json
{
"mcpServers": {
"sendhustle": {
"command": "npx",
"args": ["-y", "sendhustle-mcp"],
"env": {
"SENDHUSTLE_API_KEY": "sh_xxxxxxxxx"
}
}
}
}
```
### VS Code Copilot
Add to your VS Code `settings.json`:
```json
{
"mcp": {
"servers": {
"sendhustle": {
"command": "npx",
"args": ["-y", "sendhustle-mcp"],
"env": { "SENDHUSTLE_API_KEY": "sh_xxxxxxxxx" }
}
}
}
}
```
### OpenCode
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"sendhustle": {
"type": "local",
"command": ["npx", "-y", "sendhustle-mcp"],
"enabled": true,
"environment": { "SENDHUSTLE_API_KEY": "sh_xxxxxxxxx" }
}
}
}
```
## HTTP transport
Run the server over HTTP for remote or web-based integrations. In HTTP mode, each client authenticates by passing its SendHustle API key as a Bearer token.
```bash
npx -y sendhustle-mcp --http --port 3000
```
The server listens on `http://127.0.0.1:3000` and exposes the MCP endpoint at `POST /mcp` (one JSON-RPC request per POST). You can also set the port with `MCP_PORT`.
```bash
claude mcp add sendhustle --transport http http://127.0.0.1:3000/mcp \
--header "Authorization: Bearer sh_xxxxxxxxx"
```
```json
{
"mcpServers": {
"sendhustle": {
"url": "http://127.0.0.1:3000/mcp",
"headers": { "Authorization": "Bearer sh_xxxxxxxxx" }
}
}
}
```
## Options
| Flag | Description |
| --- | --- |
| `--http` | Use Streamable HTTP transport instead of stdio (default: stdio). |
| `--port <n>` | HTTP port when using `--http` (default: 3000, or `MCP_PORT`). |
| `--key <key>` | SendHustle API key (stdio mode; HTTP mode uses the client Bearer token). |
| `--sender <email>` | Default sender address from a verified domain. |
| `--reply-to <email>` | Default reply-to address (repeatable). |
| `-h, --help` | Show usage and the tool list. |
| `-v, --version` | Print the version. |
## Environment variables
| Variable | Description |
| --- | --- |
| `SENDHUSTLE_API_KEY` | Your API key. Required for stdio; optional for HTTP (clients pass it via Bearer token). |
| `SENDHUSTLE_BASE_URL` | API base URL (default: `https://api.sendhustle.com`). |
| `SENDER_EMAIL_ADDRESS` | Default sender address from a verified domain (optional). |
| `REPLY_TO_EMAIL_ADDRESSES` | Comma-separated default reply-to addresses (optional). |
| `MCP_PORT` | HTTP port when using `--http` (optional). |
If you do not provide a sender, the `send_email` and `create_campaign` tools require a `from` argument on each call.
## Tools
The server exposes 79 tools covering the full SendHustle API.
### Emails
| Tool | Description |
| --- | --- |
| `send_email` | Send a single email (HTML/text, CC/BCC, reply-to, scheduling, attachments, tags, idempotency key). |
| `send_batch_emails` | Send up to 100 emails in one request. |
| `retrieve_email` | Retrieve a sent email and its events by id. |
| `list_emails` | List sent emails with cursor pagination. |
| `update_email` | Reschedule a scheduled email. |
| `cancel_email` | Cancel a scheduled email before it sends. |
| `list_email_attachments` | List a sent email's attachments. |
| `get_email_attachment` | Retrieve metadata + download URL for one attachment. |
### Received (inbound) emails
| Tool | Description |
| --- | --- |
| `list_received_emails` | List inbound emails. |
| `get_received_email` | Retrieve a received email by id. |
| `forward_received_email` | Forward a received email to other recipients. |
### Domains
| Tool | Description |
| --- | --- |
| `create_domain` | Create a sender domain (returns DNS records to add). |
| `list_domains` | List sender domains. |
| `get_domain` | Retrieve a domain and its DNS/verification status. |
| `update_domain` | Update tracking / TLS / capabilities settings. |
| `verify_domain` | Trigger domain verification. |
| `delete_domain` | Delete a domain. |
| `claim_domain` | Claim a domain verified elsewhere. |
### Audiences
| Tool | Description |
| --- | --- |
| `create_audience` | Create an audience (a named contact list). |
| `list_audiences` | List audiences. |
| `get_audience` | Retrieve an audience by id. |
| `delete_audience` | Delete an audience and its contacts. |
### Contacts
| Tool | Description |
| --- | --- |
| `create_contact` | Create a contact within an audience. |
| `list_contacts` | List contacts in an audience. |
| `get_contact` | Retrieve a contact by id or email. |
| `update_contact` | Update a contact by id or email. |
| `delete_contact` | Delete a contact. |
| `add_contact_to_segment` | Add a contact to a segment. |
| `remove_contact_from_segment` | Remove a contact from a segment. |
| `get_contact_topics` | Get a contact's topic subscriptions. |
| `update_contact_topics` | Update a contact's topic subscriptions. |
### Contact properties
| Tool | Description |
| --- | --- |
| `create_contact_property` | Create a custom contact property / merge tag. |
| `list_contact_properties` | List contact properties. |
| `get_contact_property` | Retrieve a contact property by id. |
| `update_contact_property` | Update a contact property's fallback value. |
| `delete_contact_property` | Delete a contact property. |
### Segments
| Tool | Description |
| --- | --- |
| `create_segment` | Create a saved filter over an audience. |
| `list_segments` | List segments. |
| `get_segment` | Retrieve a segment by id. |
| `list_segment_contacts` | Preview the contacts a segment resolves to. |
| `update_segment` | Update a segment's name or filter. |
| `delete_segment` | Delete a segment. |
### Topics
| Tool | Description |
| --- | --- |
| `create_topic` | Create a subscription topic. |
| `list_topics` | List topics. |
| `get_topic` | Retrieve a topic by id. |
| `update_topic` | Update a topic. |
| `delete_topic` | Delete a topic. |
### Campaigns
| Tool | Description |
| --- | --- |
| `create_campaign` | Create a campaign. |
| `send_campaign` | Send a campaign now, or schedule it. |
| `get_campaign` | Retrieve a campaign by id. |
| `list_campaigns` | List campaigns. |
| `update_campaign` | Update a draft campaign's content/targeting. |
| `cancel_campaign` | Cancel a scheduled campaign (return to draft). |
| `delete_campaign` | Delete a campaign. |
### Templates
| Tool | Description |
| --- | --- |
| `create_template` | Create a reusable email template. |
| `list_templates` | List templates. |
| `get_template` | Retrieve a template by id. |
| `update_template` | Update a template. |
| `duplicate_template` | Duplicate a template. |
| `publish_template` | Publish a template's latest draft. |
| `delete_template` | Delete a template. |
### Automations
| Tool | Description |
| --- | --- |
| `create_automation` | Create an automation (optionally with an inline step graph). |
| `list_automations` | List automations. |
| `get_automation` | Retrieve an automation and its step graph. |
| `add_automation_step` | Append a step to an automation. |
| `list_automation_runs` | List an automation's runs. |
| `stop_automation` | Stop an automation (no new runs). |
| `delete_automation` | Delete an automation. |
### Webhooks
| Tool | Description |
| --- | --- |
| `create_webhook` | Create a webhook endpoint (signing secret returned once). |
| `list_webhooks` | List webhooks. |
| `get_webhook` | Retrieve a webhook by id. |
| `update_webhook` | Update a webhook's endpoint/events/status. |
| `delete_webhook` | Delete a webhook. |
### Logs, events & API keys
| Tool | Description |
| --- | --- |
| `list_logs` | List API request logs. |
| `get_log` | Retrieve a single log entry with request/response bodies. |
| `send_event` | Send a custom event automations can trigger on. |
| `create_api_key` | Create an API key (token returned once). |
| `list_api_keys` | List API keys. |
| `delete_api_key` | Delete (revoke) an API key. |
## Local development
```bash
git clone https://github.com/Achlesha/SendHustle.git
cd SendHustle/packages/sendhustle-mcp
npm install
npm run build
npm test
```
Then point your client at the built entry file:
```bash
claude mcp add sendhustle -e SENDHUSTLE_API_KEY=sh_xxxxxxxxx -- node /ABSOLUTE/PATH/dist/cli.js
```
### Testing with MCP Inspector
```bash
export SENDHUSTLE_API_KEY=mb_your_key_here
npm run inspector
```
## License
MIT
TDQS
Scored across 111 tools
Almost every tool maps to a distinct resource+action, and the descriptions are specific. A few pairs could be confused—create_event (definition) vs send_event, and get_email_attachment vs get_received_email_attachment—but the names plus descriptions largely disambiguate them.
Tools overwhelmingly follow a snake_case verb_noun pattern (create_domain, list_contacts, update_campaign). Minor inconsistency: retrieve_email instead of get_email, and several synonyms for similar actions (stop/cancel/delete, verify/check) slightly soften the pattern.
111 tools is an extreme count; even if each maps to a distinct endpoint, the set is far beyond the well-scoped range and will burden an agent's selection. This aligns with the 50+ overgrown category.
The surface covers full lifecycles for domains, audiences, contacts, properties, segments, topics, templates, campaigns, sent/received emails, automations, events, webhooks, API keys, logs, and polls. There are no obvious dead ends or missing CRUD operations for the apparent email-platform domain.