io.github.vaemail/vaemail

Official registry Productivity

Email infrastructure for AI agents: send, authenticate domains, track delivery, diagnose issues.

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

NPM package vaemail
Claude Code
claude mcp add vaemail -e 'VAEMAIL_API_KEY=<your vaemail_api_key>' -e 'VAEMAIL_BASE_URL=<VAEMAIL_BASE_URL>' -- npx -y vaemail@1.2.0 mcp
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "vaemail": {
            "command": "npx",
            "args": [
                "-y",
                "vaemail@1.2.0",
                "mcp"
            ],
            "env": {
                "VAEMAIL_API_KEY": "<your vaemail_api_key>",
                "VAEMAIL_BASE_URL": "<VAEMAIL_BASE_URL>"
            }
        }
    }
}

Environment variables

  • VAEMAIL_API_KEY required secret VaEmail API key (created in the dashboard, ideally scoped and capped for this agent). Required for every tool except vaemail_capabilities.
  • VAEMAIL_BASE_URL API base URL. Default https://app.vaemail.fr.

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. VaEmail — email infrastructure for AI agents
  2. Install
  3. Tools
  4. What this is built to prevent
  5. CLI
  6. Use it as a library
  7. Connecter Stripe
  8. Environment
  9. Also available
  10. Skill and examples
  11. Dependencies
  12. License

VaEmail — email infrastructure for AI agents

MCP server and CLI for VaEmail. Give an agent the ability to send email, authenticate a sending domain, track delivery and diagnose deliverability — without a human reading a dashboard in between.

European infrastructure: servers in Germany, sending through Amazon SES Europe.

Install

# Claude Code
claude mcp add vaemail --env VAEMAIL_API_KEY=swm_your_key -- npx -y vaemail mcp

# Any MCP client
npx -y vaemail mcp

Or as a config block:

{
  "mcpServers": {
    "vaemail": {
      "command": "npx",
      "args": ["-y", "vaemail", "mcp"],
      "env": { "VAEMAIL_API_KEY": "swm_your_key" }
    }
  }
}

GET /api/v1/me identifies the tenant, key prefix, scopes and mode without returning the secret. Contact operations accept a tenant-unique external_reference for CRM identifiers and upserts.

Use a sandbox API key for integration tests: reads work normally, while every write is validated in a transaction that is always rolled back. No row, job, email, SMS, webhook or outbound HTTP call is emitted, and idempotency keys are not stored. Sandbox write responses carry X-VaEmail-Sandbox: 1 and sandbox: true in JSON objects. A sandbox response is never evidence that an email was delivered.

Check everything is wired up:

npx vaemail init

Tools

ToolWhat it does
vaemail_preparer_envoiPrepares a newsletter draft, resolves the list, optionally sends a test, and returns a recap plus a one-use confirmation token. It never sends or schedules.
vaemail_confirmer_envoiExecutes the scheduled or immediate newsletter prepared with the token, after explicit human confirmation. This is destructive.
vaemail_ou_en_est_ma_campagneWhere a campaign stands, in plain sentences: scheduled, sending, sent, opens, clicks.
vaemail_qui_est_abonneLists by folder with subscriber counts, or the lists and status of one address.
vaemail_importer_contactsAdds contacts to a list (created if missing). Never re-subscribes an unsubscribed address.
vaemail_capabilitiesWhat the service supports. No API key needed.
vaemail_send_emailQueue a transactional email, return its id.
vaemail_validate_emailDry run: would this send go out, and what would block it.
vaemail_get_messageDelivery status and every event for one message.
vaemail_list_messagesRecent messages, filtered by status, tag or recipient.
vaemail_list_domainsSending domains with live SPF, DKIM and DMARC state.
vaemail_create_domainDeclare a domain, return the DNS records to publish.
vaemail_verify_domainRe-read the DNS and report what is authenticated.
vaemail_dns_requirementsThe records a declared domain still needs.
vaemail_diagnose_deliverabilityWhy mail is landing badly, with the actions that fix it.
vaemail_list_bouncesAddresses excluded from sending, and why.
vaemail_get_usageQuota, daily cap on the key, what is left.
vaemail_get_audit_logWhat this key has done, to report it accurately.

Both vaemail_confirmer_envoi and vaemail_send_email advertise destructiveHint: true: sending externally is irreversible. The newsletter confirmation guard applies to immediate sending; drafts and scheduled campaigns keep their existing behavior.

What this is built to prevent

An agent fails differently from a person. It retries, it does not read a dashboard, and it reports success from a 200. The API is shaped around that:

  • A send is accepted, not delivered. vaemail_send_email returns 202 and an id. Only vaemail_get_message says what became of it. The tool descriptions say so, so an agent does not announce a delivery it cannot know about.
  • Retries do not duplicate. Pass idempotency_key and a repeat call replays the first response for 24 hours instead of sending twice.
  • Errors say what to do. Every failure carries a stable code, whether it is retryable, and the corrective action with the endpoint that performs it.
  • Keys are bounded. Scopes, a daily send cap, a cap on recipients per email and an allow-list of sender domains. An agent cannot spend more than the key allows.
  • Every call is logged. Which key, which operation, which parameters, which result — message bodies excluded. Autonomous, but accountable.
  • Human steps are named as such. Publishing DNS records is one. A record whose value still contains a placeholder is flagged publishable: false, because publishing it would break the domain's authentication.

CLI

vaemail init                          # check config, print the MCP snippet
vaemail capabilities                  # what the service can do (no key needed)
vaemail send --to a@b.fr --subject Hi --html '<p>Hello</p>'
vaemail status 42                     # delivery status of a message
vaemail domains:add exemple.fr        # declare a domain, print DNS records
vaemail doctor                        # why is my email not arriving?
vaemail usage                         # quota and remaining allowance
vaemail mcp                           # run the MCP server on stdio

Add --json to any command for machine-readable output.

Use it as a library

The same client the MCP server and the CLI run on is exported, so an application can call VaEmail directly. No dependencies.

import { VaEmail } from 'vaemail';

const client = new VaEmail({ apiKey: process.env.VAEMAIL_API_KEY });

await client.send(
  {
    to: 'customer@example.com',
    subject: 'Your order is on its way',
    html: '<p>Tracking number: 1Z999</p>',
  },
  'order-4711', // idempotency key: safe to replay for 24 hours
);

Errors carry what to do next, not just a status code:

try {
  await client.send({ to: 'customer@example.com' });
} catch (error) {
  error.code;        // DOMAIN_NOT_VERIFIED
  error.retryable;   // false
  error.pourAgent(); // reason, corrective action, whether to retry
}

Also: capabilities(), health(), validate(), getMessage(), listMessages(), listDomains(), addDomain(), verifyDomain(), dnsRecords(), diagnoseDeliverability(), listSuppressions(), removeSuppression(), usage(), auditLogs().

Connecter Stripe

Utilise une clé Stripe restreinte rk_live_ ou rk_test_, avec Customers en lecture et Webhook Endpoints en écriture. Une clé secrète sk_ est refusée. VaEmail ne renvoie aucun secret Stripe : l'état de la connexion expose uniquement les quatre derniers caractères de la clé et du token du webhook.

Routes REST :

  • GET /api/v1/integrations/stripe : lire l'état de la connexion ;
  • POST /api/v1/integrations/stripe : créer ou réconcilier le webhook, avec {"api_key":"rk_live_..."} et la portée settings.write ;
  • DELETE /api/v1/integrations/stripe : supprimer le webhook Stripe puis la connexion locale. Action irréversible, à confirmer explicitement par un humain.

Stripe appelle POST /api/v1/webhooks/stripe/{token}. Cette route publique vérifie Stripe-Signature et ne reçoit pas la clé API VaEmail.

Événements pris en charge et déclencheurs d'automatisation :

Événement StripeDéclencheur VaEmail
invoice.payment_failedstripe_payment_failed (payment_failed)
customer.subscription.createdstripe_subscription_created (subscription_created)
customer.subscription.deletedstripe_subscription_deleted (subscription_deleted)
checkout.session.completedstripe_checkout_completed (checkout_completed)

A Python SDK with the same surface is available: pip install vaemail (https://github.com/vaemail/vaemail-python).

Environment

VariableMeaning
VAEMAIL_API_KEYAccount API key. Created from the dashboard, under « Clés API ».
VAEMAIL_BASE_URLAPI base URL. Defaults to https://app.vaemail.fr.

Also available

Skill and examples

Dependencies

None. Node 18+ for the built-in fetch, and nothing else — a package an agent installs on its own should not pull a dependency tree behind it.

License

MIT

Frequently asked questions

What is io.github.vaemail/vaemail?

Email infrastructure for AI agents: send, authenticate domains, track delivery, diagnose issues.

How do I install io.github.vaemail/vaemail?

It runs on your machine. In Claude Code: claude mcp add vaemail -e 'VAEMAIL_API_KEY=<your vaemail_api_key>' -e 'VAEMAIL_BASE_URL=<VAEMAIL_BASE_URL>' -- npx -y vaemail@1.2.0 mcp. For other clients, paste the JSON configuration from this page into their MCP settings.

Does io.github.vaemail/vaemail need an API key?

Yes. It expects VAEMAIL_API_KEY, which you set in its configuration.

Is io.github.vaemail/vaemail open source?

Yes. Its code is on GitHub under the MIT license.

Who maintains io.github.vaemail/vaemail?

It is published by vaemail. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.