useSendEverJust

MCP Server

Run the useSend MCP server so AI agents like Claude Code, Claude Desktop, and Cursor can send email and manage domains, contacts, campaigns, and analytics on the EverJust instance.

The repo ships an MCP server under mcp/ — a Node/TypeScript server that speaks the Model Context Protocol over stdio. It exposes the useSend REST API as a set of tools so an AI agent can send transactional email, manage sending domains, maintain contact books, run campaigns, and read analytics against the EverJust instance at https://mail.everjust.app.

It is a thin wrapper over the REST API: every tool maps to one endpoint, authenticates with a us_ Bearer key, and returns the raw JSON envelope. Anything the API can do, the agent can do.

A useSend API key grants send access to a Team — anything holding it can send mail as your domains and read your contacts. Scope one key per product (one Team per product), pass it to the server through the environment only, and never commit it to the repo or an MCP config that lives in version control.

Build and run

The server has no runtime config file — it reads two environment variables and talks stdio. Build it once, then point your MCP client at the compiled entrypoint.

Install and build

cd mcp
npm install
npm run build

npm run build runs tsc and emits dist/index.js (the bin entrypoint usesend-mcp).

Provide credentials

The server reads its configuration from the environment:

VariableRequiredValue
USESEND_API_KEYyesYour Team's key, e.g. us_xxx. Sent as Authorization: Bearer us_xxx.
USESEND_BASE_URLyes (for self-hosted)https://mail.everjust.app/api/v1

If USESEND_BASE_URL is omitted the server defaults to the useSend cloud — always set it to the EverJust base URL. The base URL is normalized: a root without /api/v1 has it appended automatically.

Run

node dist/index.js

The process serves MCP over stdio and stays attached to the client that launched it. You normally do not run it by hand — your MCP client spawns it (see Client configuration). Run it directly only to confirm it starts without throwing USESEND_API_KEY is not set.

Rate limiting is disabled on the self-hosted instance, so the server does not back off or throttle. SES is currently in sandbox: sends only reach verified addresses or the SES mailbox simulator (success@simulator.amazonses.com, bounce@…, complaint@…) until AWS grants production access. See Sending email for details.

Client configuration

Register the server with your MCP client by pointing command/args at the built entrypoint and passing credentials via env. Use an absolute path to dist/index.js — the client sets no working directory.

Add to your MCP config (Claude Desktop: claude_desktop_config.json; Claude Code: .mcp.json or claude mcp add):

{
  "mcpServers": {
    "usesend": {
      "command": "node",
      "args": ["/abs/path/usesend-email/mcp/dist/index.js"],
      "env": {
        "USESEND_API_KEY": "us_...",
        "USESEND_BASE_URL": "https://mail.everjust.app/api/v1"
      }
    }
  }
}

Add to ~/.cursor/mcp.json (or .cursor/mcp.json in a project) — the shape is identical:

{
  "mcpServers": {
    "usesend": {
      "command": "node",
      "args": ["/abs/path/usesend-email/mcp/dist/index.js"],
      "env": {
        "USESEND_API_KEY": "us_...",
        "USESEND_BASE_URL": "https://mail.everjust.app/api/v1"
      }
    }
  }
}

Replace /abs/path/usesend-email with the real checkout location and us_... with the key for that product's Team. Restart the client after editing so it re-spawns the server.

Tools

Every tool corresponds to one REST endpoint. Fields, enums, and response shapes match the API reference exactly — the server neither adds nor renames fields.

Emails

ToolEndpointPurpose
send_emailPOST /emailsSend one email. to + from required; subject or templateId, and text or html. Accepts an optional idempotency key.
send_batchPOST /emails/batchSend an array of email objects (max 100) in one call.
get_emailGET /emails/{emailId}Fetch one email with its emailEvents status history.
list_emailsGET /emailsList emails with page, limit, startDate, endDate, domainId.
reschedule_emailPATCH /emails/{emailId}Change scheduledAt on a scheduled email.
cancel_emailPOST /emails/{emailId}/cancelCancel a scheduled email.

Domains

Domain path IDs are numbers.

ToolEndpointPurpose
create_domainPOST /domainsAdd a sending domain (name + region, e.g. us-east-1).
list_domainsGET /domainsList all domains for the Team.
get_domainGET /domains/{id}Fetch one domain, including dnsRecords.
verify_domainPUT /domains/{id}/verifyTrigger DNS/DKIM re-verification.
delete_domainDELETE /domains/{id}Delete a domain.

send.everjust.app is already created and fully verified (DKIM/SPF/DMARC/MAIL FROM). Use these tools to add domains for other products, not to re-provision the existing one.

Contact books and contacts

ToolEndpointPurpose
create_contact_bookPOST /contactBooksCreate a contact book (name required).
list_contact_booksGET /contactBooksList contact books.
get_contact_bookGET /contactBooks/{contactBookId}Fetch one contact book.
update_contact_bookPATCH /contactBooks/{contactBookId}Update a contact book.
delete_contact_bookDELETE /contactBooks/{contactBookId}Delete a contact book.
create_contactPOST /contactBooks/{contactBookId}/contactsAdd a contact (email required).
list_contactsGET /contactBooks/{contactBookId}/contactsList/filter contacts (emails, ids, page, limit).
get_contactGET …/contacts/{contactId}Fetch one contact.
update_contactPATCH …/contacts/{contactId}Update contact fields.
upsert_contactPUT …/contacts/{contactId}Upsert by email (email required).
delete_contactDELETE …/contacts/{contactId}Delete a contact.
bulk_create_contactsPOST …/contacts/bulkCreate many contacts from an array.
bulk_delete_contactsDELETE …/contacts/bulkDelete many by contactIds.

Campaigns

Campaigns are the "Broadcasts" feature — bulk sends to a contact book.

ToolEndpointPurpose
create_campaignPOST /campaignsCreate a campaign (name, from, subject, contactBookId required).
list_campaignsGET /campaignsList campaigns (page, status, search).
get_campaignGET /campaigns/{campaignId}Fetch one campaign.
delete_campaignDELETE /campaigns/{campaignId}Delete a campaign.
schedule_campaignPOST /campaigns/{id}/scheduleSchedule a send (scheduledAt, batchSize).
pause_campaignPOST /campaigns/{id}/pausePause a running campaign.
resume_campaignPOST /campaigns/{id}/resumeResume a paused campaign.

Analytics

ToolEndpointPurpose
email_time_seriesGET /analytics/email-time-seriesDaily sent/delivered/opened/clicked/bounced/complained (days = 7|30, domainId).
reputation_metricsGET /analytics/reputation-metricsdelivered, hardBounced, complained, bounceRate, complaintRate (domainId).

Templates, suppressions, webhooks, and API-key creation are dashboard/tRPC-only and have no REST endpoints, so the MCP server exposes no tools for them. Reference a template on a send with templateId + variables; manage webhooks and keys at mail.everjust.app.

Example agent prompt

With the server registered, an agent can act in natural language and the tools resolve to API calls:

Send a receipt to success@simulator.amazonses.com from EverJust <hello@send.everjust.app> with subject "Your receipt" and an HTML body listing one line item, $19.00. Then show me its delivery status.

The agent calls send_email, then get_email with the returned emailId to read the emailEvents history. Because SES is in sandbox, use a verified address or the simulator (as above) as the recipient until production access is granted.

Next steps