AI · Skills

The SendNeo skill for agents

One file in the Agent Skills format that teaches an agent the safe way to send: MCP when it is connected, REST when not, verified domains, test keys, idempotency keys, batches of 100 and reading events.

Install it

  1. Claude Code: save the file as ~/.claude/skills/sendneo/SKILL.md (every project) or .claude/skills/sendneo/SKILL.md (this project). Claude Code picks it up when a task involves sending email.
  2. Other agents: put the file where your agent reads skills, or paste its contents into the agent's instructions.
  3. Connect the MCP server or set SENDNEO_API_KEY so the agent can act on what it learned.
SKILL.md
---
name: sendneo
description: Send transactional email (receipts, password resets, one-time codes, alerts) through SendNeo and confirm delivery. Use when a task needs to send an email from an app, check whether an email arrived, or set up a sending domain.
---

# Sending email with SendNeo

SendNeo is a Resend-compatible transactional email API at https://sendneo.yorkermedia.com/api, with an MCP server at https://sendneo.yorkermedia.com/mcp.

## Choose the interface

- If the `sendneo` MCP server is connected, use its tools: `send_email`, `send_batch`, `get_email`, `list_events`,
  `list_domains`, `add_domain`, `verify_domain`, `validate_email`, `get_usage`.
- Otherwise call the REST API with `Authorization: Bearer $SENDNEO_API_KEY` and `Content-Type: application/json`.
  Never print the key, commit it, or send it to a browser.

## Before the first live send

1. Check the sending domain: `list_domains` (or `GET /api/domains`). The `from` address must be on a domain whose status
   is `verified`.
2. If it is missing, `add_domain` (or `POST /api/domains` with `{"name": "mail.example.com"}`) returns DNS records.
   Ask the human to publish them, then `verify_domain` (or `POST /api/domains/{id}/verify`).
3. In development use a test key (`sn_test_…`). Test sends never reach an inbox: `delivered@test.sendneo.dev`,
   `bounced@test.sendneo.dev` and `complained@test.sendneo.dev` simulate those outcomes.

## Sending

- One email: `send_email` or `POST /api/emails` with `from`, `to`, `subject` and `html` and/or `text`. Optional: `cc`,
  `bcc`, `reply_to`, `tags`, `attachments` (base64, 10 MB total), `scheduled_at` (ISO 8601, at most 30 days ahead),
  `template_id` + `variables`.
- Always send an idempotency key when a retry is possible: the `idempotency_key` tool argument, or the `Idempotency-Key`
  header. Build it from the record and purpose, e.g. `order-4821-receipt`. A repeat returns the first email's id.
- Many emails: `send_batch` or `POST /api/emails/batch` with 1–100 email objects. It is all or nothing; split larger
  sets into chunks of 100.
- At most 50 recipients per email (to + cc + bcc) and 10 requests per second per key.

## Confirming delivery

- `get_email` / `GET /api/emails/{id}` shows `last_event`: `queued`, `sent`, `delivered`, `delivery_delayed`,
  `bounced`, `complained`, `failed`, `suppressed`.
- `list_events` / `GET /api/events?email_id={id}` lists each event in order; page with `after` = `next_after`.
- Do not send again because a status is still `queued` or `sent`; wait and read the events.

## Errors

Errors look like `{"statusCode": 403, "name": "domain_not_verified", "message": "…"}`. Retry only `429` and `5xx`, with
a backoff and the same idempotency key. Report other errors to the human with the message; do not work around a
`domain_not_verified`, `account_in_review` or quota error.