SendHQ
Envía y recibe correos electrónicos desde tus dominios verificados; gestiona dominios, plantillas y capacidad de entrega.
Documentación
Servidor MCP de SendHQ
Dale a un agente de IA control total y seguro de un espacio de trabajo de SendHQ mediante 59 herramientas MCP estrictamente tipadas. Servidor stdio local: sendhq mcp.
curl -fsSL https://downloads.sendhq.cc/install.sh | sh
claude mcp add sendhq --env SENDHQ_API_KEY=re_your_key -- sendhq mcp
Qué es este servidor
El servidor MCP de SendHQ permite que un agente de IA opere un espacio de trabajo de SendHQ a través del Protocolo de Contexto de Modelo: enviar correos electrónicos (individuales, masivos, con plantillas, respuestas, adjuntos, reintentos idempotentes), leer y buscar correos enviados y recibidos (asuntos, cuerpos y nombres de adjuntos) y sus eventos de entrega, organizar el correo en etiquetas con reglas de archivado automático, gestionar borradores y adjuntos privados, redactar y publicar plantillas alojadas, agregar y verificar dominios y su DNS, configurar la recepción de correo entrante y direcciones de entrada, inspeccionar la entregabilidad, rebotes, quejas y supresiones, y leer el uso de la cuenta, el estado de facturación, análisis y metadatos de claves API.
Es un servidor local stdio integrado en el binario CLI sendhq. Tu cliente MCP inicia sendhq mcp como un proceso hijo y habla JSON-RPC a través de stdin/stdout. Cada llamada a una herramienta se convierte en una solicitud documentada a la API REST de SendHQ en https://sendhq.cc/api/v1 autenticada con la clave API de tu espacio de trabajo, por lo que el servidor MCP tiene exactamente los permisos de esa clave y nada más.
- 59 herramientas en 8 grupos, generadas a partir de un catálogo que también se publica como tools.json.
- Esquemas JSON estrictos: argumentos desconocidos, tipos incorrectos y campos obligatorios faltantes se rechazan localmente antes de que algo llegue a SendHQ.
- Errores estructurados con un
codeestable, elstatusHTTP, unexplanation, unremedyconcreto y si reintentar puede ayudar. - Cada herramienta que envía correo real o destruye datos lo dice en las primeras palabras de su descripción y lleva anotaciones de seguridad MCP.
- El modo
--read-onlyoculta todas las herramientas de envío y mutación. - No se registra nada. stdout lleva solo mensajes de protocolo; la clave API y el contenido de los mensajes nunca llegan a un registro.
No es el endpoint MCP de documentación. SendHQ también aloja un pequeño endpoint MCP de documentación de solo lectura en
https://sendhq.cc/api/mcp(precios y consulta de documentación, sin acceso a la cuenta). El servidor en esta página es el completo, con alcance a la cuenta; se ejecuta localmente o como el conector alojado a continuación.
Usar SendHQ en Claude y ChatGPT
No se necesita instalación: SendHQ también ejecuta este servidor como un conector alojado en https://mcp.sendhq.cc/mcp con las mismas herramientas. Inicias sesión con tu cuenta de SendHQ en lugar de pegar una clave.
Claude
- Abre Configuración → Conectores y busca SendHQ en el directorio, o elige Agregar conector personalizado y pega
https://mcp.sendhq.cc/mcp. - Haz clic en Conectar, inicia sesión en SendHQ, revisa el acceso y haz clic en Permitir.
- Pídele a Claude que revise tu bandeja de entrada, envíe un correo desde tu dominio verificado o explique un rebote.
ChatGPT
- Abre Configuración → Seguridad e inicio de sesión y activa Modo desarrollador.
- Ve a chatgpt.com/plugins, haz clic en Crear aplicación MCP, nómbrala SendHQ e ingresa
https://mcp.sendhq.cc/mcp. - Inicia sesión en SendHQ y haz clic en Permitir, luego elige SendHQ desde el menú de herramientas en un nuevo chat.
Muse de Meta
En Muse, abre Conectores y busca SendHQ. Haz clic en Conectar, inicia sesión en SendHQ y haz clic en Permitir.
Aprobación y desconexión
- La herramienta
request_featureenvía una solicitud de función al equipo de SendHQ con los detalles de tu cuenta, para que podamos hacer un seguimiento por correo electrónico. - Las herramientas que envían correo real o eliminan datos están etiquetadas como tales. Si el asistente te pregunta primero se configura por herramienta en el asistente: en Claude, elige Requiere aprobación para esas herramientas en Configuración → Conectores → SendHQ.
- El conector obtiene su propia clave API, nombrada según el asistente (por ejemplo, "Claude (conector de IA)"). Elimínala en Claves API para desconectarte de inmediato.
- No puede crear ni revocar claves API ni cambiar la facturación. Los adjuntos se envían y devuelven como base64; no hay acceso a archivos locales.
- Los espacios de trabajo no pagados (prueba de integración) solo pueden entregar al correo de la cuenta o a una dirección de simulador de AWS SES.
Preguntas: postmaster@sendhq.cc. Privacidad: sendhq.cc/privacy.
Instalación
Instala el binario sendhq (Linux, macOS y Windows en x86-64 y arm64). El instalador verifica la suma de verificación de la versión y coloca el binario en ~/.local/bin de forma predeterminada.
macOS y Linux:
curl -fsSL https://downloads.sendhq.cc/install.sh | sh
Windows PowerShell:
irm https://downloads.sendhq.cc/install.ps1 | iex
Verifica la instalación:
sendhq version
SENDHQ_API_KEY=re_your_key sendhq doctor
Crea una clave API en el panel de control en https://sendhq.cc/app#/keys. El servidor MCP no puede crear claves. El único comando que ejecuta el servidor es:
Ejecuta el servidor stdio:
SENDHQ_API_KEY=re_your_key sendhq mcp
Normalmente nunca lo ejecutas manualmente: el cliente MCP lo inicia. Cuando se ejecuta en una terminal, espera JSON-RPC en stdin.
Configurar tu cliente
Claude Code
claude mcp add:
claude mcp add sendhq --env SENDHQ_API_KEY=re_your_key -- sendhq mcp
# read-only variant
claude mcp add sendhq-readonly --env SENDHQ_API_KEY=re_your_key -- sendhq mcp --read-only
Agrega --scope user para que esté disponible en todos los proyectos, o --scope project para escribirlo en el .mcp.json del proyecto. Para un .mcp.json compartido, referencia la clave desde el entorno en lugar de comprometerla; Claude Code expande ${VAR} en .mcp.json.
.mcp.json:
{
"mcpServers": {
"sendhq": {
"command": "sendhq",
"args": [
"mcp"
],
"env": {
"SENDHQ_API_KEY": "${SENDHQ_API_KEY}"
}
}
}
}
OpenAI Codex
~/.codex/config.toml:
[mcp_servers.sendhq]
command = "sendhq"
args = ["mcp"]
env = { SENDHQ_API_KEY = "re_your_key" }
O desde la línea de comandos: codex mcp add sendhq --env SENDHQ_API_KEY=re_your_key -- sendhq mcp.
Claude Desktop
Edita claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\) y reinicia la aplicación. Las aplicaciones de escritorio no heredan tu PATH de shell, así que usa la ruta absoluta del binario (which sendhq).
claude_desktop_config.json:
{
"mcpServers": {
"sendhq": {
"command": "/Users/you/.local/bin/sendhq",
"args": [
"mcp"
],
"env": {
"SENDHQ_API_KEY": "re_your_key"
}
}
}
}
Cualquier otro cliente MCP
Configura un servidor stdio con el comando sendhq, los argumentos ["mcp"] (opcionalmente "--read-only") y las variables de entorno a continuación. El servidor admite las versiones de protocolo MCP 2024-11-05, 2025-03-26, 2025-06-18 y 2025-11-25, e implementa initialize, ping, tools/list y tools/call. Los resultados de las herramientas llevan tanto un bloque de texto JSON como structuredContent.
Prueba de humo stdio sin procesar (canaliza a sendhq mcp):
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"1"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_service_health","arguments":{}}}
No hay transporte HTTP alojado para el servidor con alcance a la cuenta. Un endpoint MCP remoto con capacidad de escritura necesitaría OAuth por usuario, que SendHQ no ofrece; el binario local mantiene la clave en la máquina que ya la tiene.
Entorno y banderas
| Variable o bandera | Requerida | Significado |
|---|---|---|
SENDHQ_API_KEY | sí | Clave API del espacio de trabajo (re_…). Cada herramienta excepto get_service_health la necesita. Sin ella, el servidor aún se inicia y cada llamada devuelve un auth_error estructurado que explica cómo solucionarlo. |
SENDHQ_API_BASE_URL | no | URL base de la API. Predeterminado https://sendhq.cc/api/v1. Úsala solo para una implementación local o de prueba. SENDHQ_BASE_URL se acepta como un alias más antiguo. |
SENDHQ_MCP_READ_ONLY | no | 1, true o yes se comporta como --read-only. |
--read-only | no | Expone solo herramientas que ni envían correo ni cambian el estado. Las herramientas ocultas también se rechazan si se llaman por nombre. |
SENDHQ_PROFILE / --profile | no | Usa una clave almacenada por sendhq auth login en el llavero del sistema operativo en lugar de SENDHQ_API_KEY. La variable de entorno gana cuando ambas existen. |
La clave se envía solo como el encabezado Authorization: Bearer a la URL base configurada. Nunca se imprime, registra, repite en errores ni se incluye en los resultados de las herramientas.
Modelo de seguridad para agentes
- Envía correo real.
send_email,send_batchysend_template_testentregan correo a personas reales y consumen créditos de entrega. Sus descripciones comienzan conSENDS REAL EMAIL. Llámalas solo cuando el usuario haya pedido explícitamente que se envíe ese mensaje específico, con los destinatarios, el remitente y el contenido confirmados. - Destructivo.
delete_email,delete_draft,delete_attachment,delete_domain,delete_inboxyremove_suppressionestán marcados comodestructiveHint: truey sus descripciones comienzan conDESTRUCTIVE. Confirma con el usuario primero.remove_suppressiondebilita un bloqueo de seguridad y es apropiado solo cuando un humano confirma que la dirección vuelve a funcionar. - Cambia el estado. Crear o actualizar borradores, plantillas, dominios y bandejas de entrada, publicar plantillas e iniciar la verificación cambian el espacio de trabajo pero no envían correo.
- Solo lectura. Todo lo demás es
readOnlyHint: truey es seguro llamarlo libremente. - El DNS nunca se cambia con este servidor.
add_domaindevuelve registros para que un humano los publique;get_domain_connect_linkdevuelve una URL de consentimiento que una persona debe abrir y aprobar en su proveedor de DNS. - La facturación nunca se cambia con este servidor.
get_accountsolo lee el plan, el uso y el estado de la suscripción. - Espacios de trabajo no pagados (prueba de integración) solo pueden entregar al correo del propietario de la cuenta (
get_account→user.email) o a una dirección de simulador de AWS SES comosuccess@simulator.amazonses.com, y no pueden enviar adjuntos. - Aceptado no es entregado. Un envío exitoso devuelve un ID; la evidencia de entrega, rebote y queja llega más tarde en
list_email_events. Nunca afirmes la colocación en la bandeja de entrada ni que una persona leyó un mensaje. - No cambies a una dirección De diferente para evitar una pausa de
423, y nunca vuelvas a agregar destinatarios que se hayan dado de baja o hayan presentado quejas.
Las claves API están fuera de alcance
Por diseño, no hay herramientas que creen, modifiquen, roten, revoquen o eliminen claves API. Un agente no debe acuñar ni destruir credenciales. list_api_keys devuelve solo nombres, prefijos no secretos y horas de último uso. La gestión de claves permanece en el panel de control con un humano con sesión iniciada.
Flujos de trabajo
1. Primer envío
get_service_healthconfirma que la API es accesible (funciona sin clave).get_accountmuestra el plan (access.tier), la cuota restante yuser.email. En la prueba, ese correo es el único destinatario real permitido.list_sending_identitiesenumera las direcciones De que puedes usar. Si está vacío, haz primero el flujo de dominio.- Confirma remitente, destinatario, asunto y cuerpo con el usuario, luego
send_emailcon unidempotency_key. list_email_eventscon eliddevuelto muestradelivery,bounce,complaintorejectuna vez que el proveedor lo informe (generalmente de segundos a minutos).
Primer envío:
{
"name": "send_email",
"arguments": {
"from": "Acme <hello@example.com>",
"to": [
"owner@example.com"
],
"subject": "SendHQ is connected",
"text": "It works.",
"idempotency_key": "first-send-2026-09-26"
}
}
2. Verificación de dominio de extremo a extremo
add_domainconname: "example.com". El resultado incluye los registros DNS (CNAME de DKIM, verificación de SES, SPF, DMARC recomendado).get_dns_providercon eldomain_iddetecta el proveedor de DNS autoritativo y devuelve el host relativo exacto para ingresar cada registro en ese proveedor.- Si
providers.domainConnect.availablees verdadero,get_domain_connect_linkdevuelve una URL de consentimiento. Entrégasela al humano; nada cambia hasta que apruebe en el proveedor. De lo contrario, dale al humano los registros para publicar. Nunca publiques un segundo registro SPF: fusionainclude:amazonses.comen el valor existente dev=spf1. verify_domainvuelve a verificar DNS y SES. El estado avanza a través depending,checkingypropagatinghastaverified. Consultaverify_domainoget_domaincada 30–60 segundos; el DNS puede tardar de minutos a horas.- Cuando
statusseaverified, las direcciones del dominio aparecen enlist_sending_identities.
3. Rebotes, quejas y supresiones
list_blocked_recipientsdevuelve cada dirección bloqueada con su motivo (bounce,complaint,unsubscribe) y un recuento resumido.list_suppressionsdevuelve supresiones por rebote duro y queja;deliverability_statsda tasas de entrega, rebote y queja de 30 días;list_sender_reputationmuestra qué direcciones De están limitadas o en pausa.- Un envío que contiene un destinatario suprimido falla con
422 recipient_suppressed. Elimina ese destinatario y envía de nuevo. - Solo cuando un humano confirme que un buzón rebotado ahora funciona, llama a
remove_suppression. Las supresiones por queja son permanentes (409 complaint_suppression_locked).
4. Recibir correo entrante
- El dominio (a menudo un subdominio como
inbound.example.com) debe estar verificado. setup_inboundaprovisiona la recepción y devuelve un registro MX. Una persona lo publica.verify_inboundhasta questatusseaready.create_inboxcondomain_idylocal_part(por ejemplosupport) creasupport@inbound.example.com.- Consulta
list_emailscondirection: "in"yunread: true(opcionalmenteinbox_id). Lee un mensaje conget_email, su conversación conget_thread, los adjuntos condownload_attachmenty márcalo como gestionado conmark_email(read: true). - Responde en el hilo con
send_emailyreply_to_email_id; SendHQ establece In-Reply-To, References y el hilo.
5. Webhooks y notificaciones de eventos
SendHQ actualmente no ofrece webhooks configurables por el cliente, por lo que no existe una herramienta de webhook. Las notificaciones del proveedor se procesan dentro de SendHQ y se exponen mediante lecturas. Consulta en su lugar: list_email_events para el resultado de un mensaje, list_emails con status (por ejemplo bounced) o after para cambios recientes, list_emails con direction: "in" y unread: true para nuevo correo entrante, y list_blocked_recipients para nuevos bloqueos. No consultes más de una vez por minuto por pregunta.
6. Diagnosticar un fallo de entrega
- Encuentra el mensaje:
list_emailscondirection: "out"ytooquery, oget_emailsi tienes el ID.status: failedsignifica que SendHQ o el proveedor lo rechazó al enviarlo; el error del correo explica por qué. list_email_events:bounce(permanente o transitorio, con el diagnóstico del proveedor),complaint,rejectodelivery. Aún no hay eventos significa que el proveedor no ha informado; espera y vuelve a comprobar.- Si la llamada de envío en sí falló, lee el error
code:sender_domain_unverified→ completa la verificación del dominio;recipient_suppressed→ la dirección rebotó de forma permanente o se quejó antes;sender_paused→ inspeccionalist_sender_reputationy corrige la fuente de la lista;trial_recipient_restricted→ límites de prueba;quota_exhausted→ uso deget_account. get_domaincomprueba que DKIM, SPF y DMARC sigan publicados;deliverability_statsmuestra si el problema es un mensaje o una tendencia.- Informa lo que muestran las evidencias. Un evento
deliverysignifica que el servidor del destinatario aceptó el mensaje, no que llegó a la bandeja de entrada o fue leído.
7. Poseer un bucket de tareas (etiquetas)
create_labelconname(por ejemploAgent/Orders) yskip_inbox: true. Eso convierte la etiqueta en un bucket: el correo recibido que la obtiene se archiva, por lo que solo aparece en la etiqueta, nunca en la bandeja de entrada de la persona.- Envía correo de tareas con
send_email(osend_batch) ylabels: ["Agent/Orders"]. Las respuestas a esa conversación heredan la etiqueta automáticamente y omiten la bandeja de entrada. - Para correo que comienza fuera de tus conversaciones, añade una regla de archivado:
create_label_ruleconinbox_id(una dirección dedicada comoorders@…),from,toosubject. Pasaapply_to_existing: truepara archivar correo ya recibido. - Trabaja el bucket:
list_emailsconlabel: "Agent/Orders",direction: "in"yunread: true; lee conget_emailoget_thread, responde consend_emailyreply_to_email_id, ymark_emailread: truecuando esté gestionado. - Mueve un mensaje suelto hacia dentro o fuera con
label_email(add/remove). Añadir una etiqueta de bucket a un mensaje recibido también lo archiva. - Opcionalmente
set_inbox_forwardingenvía una copia de todo lo que una dirección receptora recibe a otro buzón (el destino confirma por correo primero).
Enviar a un bucket:
{
"name": "send_email",
"arguments": {
"from": "Orders <orders@example.com>",
"to": [
"customer@example.net"
],
"subject": "Order 1042: confirm delivery window",
"text": "Reply with a time that works.",
"labels": [
"Agent/Orders"
],
"idempotency_key": "order-1042-window"
}
}
8. Adjuntos y plantillas
Adjunta hasta 10 archivos con send_email attachments (cada uno necesita content_base64 o un file_path local; filename usa por defecto el nombre base del archivo) en un plan de pago. Para plantillas alojadas: create_template → update_template_draft → render_template para previsualizar con datos de muestra → send_template_test (envía una prueba real) → publish_template, luego envía con send_email o send_batch usando template: {key, data} y exactamente un destinatario to.
Resultados, paginación y errores
Una llamada exitosa devuelve el objeto JSON de la API como structuredContent y como un bloque de texto JSON. Cada herramienta list_* acepta limit (1–200, por defecto 50) y offset, y añade un objeto pagination. Sigue llamando con offset: pagination.next_offset mientras has_more sea verdadero.
Resultado paginado:
{
"data": [
"…"
],
"count": 50,
"pagination": {
"offset": 0,
"limit": 50,
"returned": 50,
"total": 180,
"has_more": true,
"next_offset": 50
}
}
Una llamada fallida devuelve isError: true con un error estructurado. Sigue remedy en lugar de reintentar a ciegas; solo reintenta cuando retryable sea verdadero.
Error estructurado de herramienta:
{
"error": {
"code": "trial_recipient_restricted",
"status": 402,
"message": "The integration trial can deliver only to your account email or an AWS SES simulator address",
"retryable": false,
"explanation": "This workspace is on the unpaid integration trial. Trial sends can be delivered only to the account owner's email address or an AWS SES simulator address.",
"remedy": "Send to the account email (get_account -> user.email) or a simulator address such as success@simulator.amazonses.com to test. To email anyone else, the account owner must activate a paid plan in the dashboard (Profile & Billing). Do not retry the same recipients."
}
}
Campos de error opcionales: request_id (cítalo para soporte), retry_after_seconds, problems (lista de violaciones de esquema para invalid_arguments) y idempotent_replayed (ver Idempotencia).
Idempotencia
send_email y send_batch aceptan idempotency_key (máximo 200 caracteres), enviado como el encabezado Idempotency-Key. Genera una clave estable por mensaje lógico, por ejemplo invoice-4812-receipt.
- Un reintento debe reutilizar la misma clave Y un cuerpo de solicitud idéntico. La misma clave con cualquier cambio (destinatario, asunto, cuerpo, encabezado, datos de plantilla, incluso valores de argumentos) devuelve
409 idempotency_conflict. - Misma clave, mismo cuerpo, original terminado: SendHQ devuelve el resultado almacenado sin enviar de nuevo. Así es como se reintenta de forma segura después de un tiempo de espera o
network_error. - Misma clave mientras el original aún se ejecuta:
409 idempotency_in_progress, reintentable después de una breve espera. - Un nuevo mensaje lógico necesita una nueva clave.
- Los fallos almacenados también se reproducen. Si el primer intento falló, reintentar con la misma clave devuelve ese mismo fallo con
idempotent_replayed: trueyretryable: false. Compruebalist_emails(direction: out) para confirmar que nada salió, corrige la causa y luego envía con una clave nueva. - El servidor nunca reintenta un POST por sí mismo. Solo las llamadas GET de solo lectura se reintentan automáticamente (hasta 3 intentos en errores de red, 429 y 5xx).
send_emailconattachmentsen línea no puede tomar unidempotency_key, porque ejecuta varias solicitudes. Para envíos con adjuntos seguros ante reintentos:create_draft→upload_attachment→send_emailcondraft_idyidempotency_key.
Envío seguro ante reintentos (repite exactamente en tiempo de espera):
{
"name": "send_email",
"arguments": {
"from": "Acme <billing@example.com>",
"to": [
"owner@example.com"
],
"subject": "Receipt #4812",
"text": "Thanks for your payment.",
"idempotency_key": "receipt-4812"
}
}
Límites de velocidad y cuotas
SendHQ no publica un límite fijo de solicitudes por segundo para la API. Los límites que un agente realmente encuentra son límites de uso, devueltos como 429:
- Entregas mensuales a destinatarios por plan. Cada dirección Para, CC y CCO cuenta como una entrega. Ver
get_account→usage.recipientDeliveriesfrente ausage.emailQuotaMonth. - Destinatarios diarios por dirección De exacta, establecidos por el estado de reputación de ese remitente (
list_sender_reputation→dailyLimit, 2,000 por defecto en planes de pago). - Prueba de integración: 100 destinatarios en total, solo a la cuenta de correo o direcciones del simulador de SES.
- Adjuntos: como máximo 10 archivos y 10 MB por mensaje; 10 GB de transferencia de adjuntos ponderada por destinatario al mes en planes de pago.
- Por solicitud: Para + CC + CCO hasta 100 direcciones;
send_batchhasta 100 mensajes. - Disyuntor de reputación: en una ventana móvil de 7 días, rebotes o quejas por encima del umbral pausan o limitan una dirección De (
423 sender_paused). Se recupera automáticamente una vez que las tasas bajan.
quota_exhausted no es reintentable hasta que el período se restablezca o el plan cambie. rate_limited es reintentable después de retry_after_seconds; para envíos, reintenta con el mismo idempotency_key y cuerpo idéntico.
Catálogo de errores
code es estable; ramifica en él en lugar de en message.
| código | HTTP | ¿Reintentar? | Qué significa y qué hacer |
|---|---|---|---|
invalid_arguments | — | no | Los argumentos fallaron el esquema JSON de la herramienta localmente; nada llegó a SendHQ. Corrige los campos listados en problems. |
auth_error | 401 | no | Clave API faltante, revocada o incorrecta. Establece SENDHQ_API_KEY para el proceso del servidor; una persona crea claves en el panel. |
trial_recipient_restricted | 402 | no | La prueba de integración solo puede entregar a la cuenta de correo o una dirección del simulador de SES. Envía allí, o el propietario activa un plan de pago. |
payment_required | 402 | no | La función necesita un plan de pago (por ejemplo, adjuntos). Envía sin ella o mejora el plan. |
sender_domain_not_owned | 403 | no | El dominio De no está en este espacio de trabajo. Usa list_sending_identities o add_domain. |
sender_domain_unverified | 403 | no | El dominio De aún no está verificado. get_domain, publica los registros faltantes, verify_domain. |
domain_limit_reached | 403 | no | Límite de dominios del plan alcanzado. Elimina un dominio no utilizado (con aprobación) o mejora el plan. |
marketing_not_enabled | 403 | no | La clase de marketing no está habilitada para este dominio o plan. Usa transactional solo si el mensaje realmente lo es. |
forbidden | 403 | no | La política no permite la operación. Ajusta la solicitud. |
not_found | 404 | no | El ID no está en este espacio de trabajo. Lista el recurso para encontrar el ID correcto; restaura plantillas archivadas primero. |
idempotency_conflict | 409 | no | Clave reutilizada con un cuerpo diferente. Reenvía el original exacto, o usa una nueva clave para un nuevo mensaje. |
idempotency_in_progress | 409 | sí | La solicitud original aún se ejecuta. Espera, luego reintenta con la misma clave y cuerpo. |
revision_conflict | 409 | no | El borrador de la plantilla cambió desde que lo leíste. get_template, fusiona, guarda de nuevo. |
complaint_suppression_locked | 409 | no | El destinatario se quejó. Nunca le envíes correo de nuevo. |
inbound_not_ready | 409 | no | La recepción entrante no está lista. setup_inbound, publica MX, verify_inbound. |
conflict | 409 | no | El recurso ya existe o está en un estado incorrecto. Léelo y ajusta. |
attachments_too_large | 413 | no | Más de 10 archivos o 10 MB. Elimina o reduce los adjuntos. |
recipient_suppressed | 422 | no | Un destinatario rebotó de forma permanente o se quejó antes. Elimínalo; ver list_blocked_recipients. |
recipient_unsubscribed | 422 | no | Un destinatario optó por no recibir correo de marketing. Elimínalo permanentemente. |
validation_failed | 422 | no | Contenido rechazado, por ejemplo, datos de plantilla que rompen el contrato de variables. Corrige la entrada. |
sender_paused | 423 | no | Esta dirección De está pausada por el disyuntor de rebotes/quejas de 7 días. Detente, corrige la lista, espera la recuperación automática. |
quota_exhausted | 429 | no | Límite mensual, diario por remitente, de adjuntos o de prueba alcanzado. Comprueba get_account; espera el restablecimiento o mejora el plan. |
rate_limited | 429 | sí | Reduce la velocidad; espera retry_after_seconds. Envíos: misma clave, mismo cuerpo. |
server_error | 5xx | sí | Fallo temporal de SendHQ o del proveedor. Retrocede y reintenta; envíos con la misma clave y cuerpo. Si idempotent_replayed es verdadero, usa una nueva clave después de confirmar que nada se envió. |
network_error | — | sí | Solicitud o respuesta perdida. Reintenta; para envíos, el mismo idempotency_key lo hace seguro. |
invalid_request | 400 | no | Solicitud mal formada. Lee message y corrígela. |
tool_error | — | no | Fallo local dentro del servidor MCP (por ejemplo, un file_path ilegible). Lee message. |
Referencia de herramientas
Cada herramienta con su clase de seguridad, el endpoint REST que llama, sus parámetros, la forma de retorno y un ejemplo de objeto de parámetros tools/call. Los parámetros son exactos: el servidor rechaza cualquier cosa no listada.
Correos e hilos
send_email
Enviar un correo · Envía correo real · POST /emails
ENVÍA CORREO REAL. Envía un mensaje desde un dominio verificado: HTML/texto sin formato, una plantilla alojada publicada, una respuesta en un hilo existente o un mensaje con archivos adjuntos. Pasa idempotency_key para que un reintento no pueda enviar dos veces; un reintento debe reutilizar la misma clave Y una solicitud idéntica, de lo contrario SendHQ devuelve 409. attachments es una conveniencia que crea un borrador, sube cada archivo y envía con ese borrador; no se puede combinar con idempotency_key o draft_id (usa create_draft + upload_attachment + send_email con draft_id para envíos con archivos adjuntos seguros ante reintentos). Los espacios de trabajo no pagados (prueba de integración) solo pueden entregar a la cuenta de correo o a una dirección de simulador de AWS SES, y no pueden enviar archivos adjuntos.
Proporciona al menos uno de: html, text, template.
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
from | string | sí | Remitente, p. ej. Acme <hello@example.com>. El dominio debe estar verificado en este espacio de trabajo (consulta list_sending_identities). (máx. 998 caracteres) |
to | string[] | sí | Destinatarios. Cada entrada es una dirección, opcionalmente con un nombre para mostrar. Para+CC+CCO pueden sumar como máximo 100; cada destino consume un crédito de entrega. (1–100 elementos) |
cc | string[] | no | Destinatarios en copia carbón. (0–100 elementos) |
bcc | string[] | no | Destinatarios en copia oculta. (0–100 elementos) |
subject | string | no | Línea de asunto. Omítela al enviar una plantilla. (máx. 998 caracteres) |
text | string | no | Cuerpo en texto sin formato. Proporciona texto, HTML o plantilla. |
html | string | no | Cuerpo en HTML. SendHQ lo sanitiza y deriva el texto cuando se omite text. |
reply_to | string | no | Dirección de respuesta (Reply-To). |
headers | object | no | Encabezados personalizados seguros adicionales (valores de cadena), p. ej. {"X-Entity-Ref-ID": "123"}. Los encabezados de enrutamiento como From/To/Message-ID están controlados por SendHQ. |
message_class | string | no | transactional (predeterminado) o marketing. Marketing requiere un plan o dominio habilitado para marketing y añade manejo de cancelación de suscripción. (uno de transactional, marketing) |
reply_to_email_id | string | no | Responder dentro de una conversación existente: el ID em_… del mensaje que se responde. SendHQ establece In-Reply-To/References y el hilo. |
thread_id | string | no | ID de hilo explícito para archivar el mensaje. |
draft_id | string | no | Envía los archivos adjuntos de un borrador almacenado con este mensaje (dr_…). El borrador se elimina después de un envío exitoso. |
template | object | no | Envía una plantilla alojada publicada en lugar de HTML/texto sin formato. Requiere exactamente un destinatario to y sin CC/CCO; la plantilla proporciona el asunto. Proporciona al menos uno de: id, key. |
template.id | string | no | ID de plantilla (tmpl_…). Proporciona id o key. |
template.key | string | no | Clave de plantilla como account-welcome. Proporciona id o key. |
template.version_id | string | no | ID de versión publicada opcional (tmplv_…). El valor predeterminado es la versión publicada actual. |
template.data | object | no | Valores para las variables tipadas de la plantilla. |
labels | string[] | no | Nombres de etiquetas o IDs lbl_… para archivar este mensaje. Los nombres desconocidos se crean. Las respuestas en la conversación heredan las etiquetas, y una etiqueta de cubo (skip_inbox) mantiene esas respuestas fuera de la bandeja de entrada. Máx. 10. (0–10 elementos) |
idempotency_key | string | no | Encabezado Idempotency-Key (máx. 200 caracteres). Reutilízalo solo para reintentar esta solicitud exacta. (máx. 200 caracteres) |
attachments | object[] | no | Archivos para adjuntar (máx. 10 archivos, 10 MB en total). Cada uno necesita content_base64 (más filename) o un file_path local. (0–10 elementos) Proporciona al menos uno de: content_base64, file_path. |
attachments[].filename | string | no | Nombre de archivo mostrado al destinatario. Obligatorio con content_base64; el valor predeterminado es el nombre base de file_path. (máx. 255 caracteres) |
attachments[].content_type | string | no | Tipo MIME, p. ej. application/pdf. El valor predeterminado es application/octet-stream. |
attachments[].content_base64 | string | no | Contenido de archivo en base64 estándar. |
attachments[].file_path | string | no | Ruta absoluta de un archivo local legible por el proceso del servidor MCP. |
Devuelve: {id: em_…, providerMessageId, threadId, templateId, templateVersionId, isTest}. La aceptación no es entrega: haz un seguimiento con list_email_events.
Ejemplo:
{
"name": "send_email",
"arguments": {
"from": "Acme <hello@example.com>",
"to": [
"owner@example.com"
],
"subject": "Your export is ready",
"text": "Download it from your dashboard.",
"idempotency_key": "export-ready-42"
}
}
send_batch
Envía un lote de correos individualizados · Envía correo real · POST /emails/batch
ENVÍA CORREO REAL. Envía de 1 a 100 mensajes independientes en una sola solicitud (úsalo para personalización de plantillas por destinatario). Cada elemento tiene la misma forma que send_email (sin archivos adjuntos/idempotency_key). Los elementos tienen éxito o fallan individualmente: HTTP 207 significa éxito parcial; inspecciona cada data[i].ok y data[i].error. Un idempotency_key cubre todo el cuerpo del lote.
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
emails | object[] | sí | Mensajes para enviar. (1–100 elementos) Proporciona al menos uno de: html, text, template. |
idempotency_key | string | no | Idempotency-Key para todo el lote (máx. 200 caracteres). (máx. 200 caracteres) |
Devuelve: {data: [{index, ok, id?, error?: {message, status}}], count, successful, failed}.
Ejemplo:
{
"name": "send_batch",
"arguments": {
"emails": [
{
"from": "Acme <hello@example.com>",
"to": [
"owner@example.com"
],
"template": {
"key": "account-welcome",
"data": {
"first_name": "Asha"
}
}
}
],
"idempotency_key": "welcome-batch-2026-09-26"
}
}
list_emails
Lista y busca correos · Solo lectura · GET /emails
Lista correos enviados (direction: out) y recibidos (direction: in) del más reciente al más antiguo con filtros. El correo recibido se clasifica: lee la bandeja de entrada humana con direction: in, archived: false, category: primary; haz triaje con important: true; el spam está oculto a menos que se use category: spam o include_spam: true. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
direction | string | no | in para recibidos, out para enviados. (uno de in, out) |
status | string | no | Filtro de estado, p. ej. queued, sent, delivered, bounced, complained, failed. |
domain | string | no | Solo mensajes para este dominio, o una lista separada por comas de dominios (coincide con cualquiera). |
inbox_id | string | no | Solo mensajes recibidos por esta bandeja de entrada (inb_…). |
label | string | no | Solo mensajes con esta etiqueta: un ID de etiqueta lbl_… o nombre exacto, o una lista separada por comas (coincide con cualquiera). Usa list_labels para ver carpetas. |
archived | boolean | no | false = vista de bandeja de entrada (correo recibido no archivado), true = solo archivado. Omítelo para todo el correo. |
category | string | no | primary (personas), updates (boletines, masivo, automatizado) o spam; o una lista separada por comas. El spam está oculto a menos que se solicite. |
important | boolean | no | true = solo mensajes marcados como importantes (respuestas a conversaciones que iniciaste y remitentes marcados como importantes). |
include_spam | boolean | no | Incluye spam en los resultados (para búsquedas en todas las carpetas). |
from | string | no | La dirección del remitente contiene este valor. |
to | string | no | La dirección del destinatario contiene este valor. |
unread | boolean | no | true = solo no leídos, false = solo leídos. |
after | string | no | Marca de tiempo ISO-8601; solo mensajes creados después de ella. (fecha-hora) |
before | string | no | Marca de tiempo ISO-8601; solo mensajes creados antes de ella. (fecha-hora) |
query | string | no | Búsqueda de texto libre sobre asuntos, cuerpos, direcciones de remitente/destinatario y nombres de archivos adjuntos. (máx. 200 caracteres) |
limit | integer | no | Tamaño de página. El valor predeterminado es 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros para omitir. Usa pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [resúmenes de correo], count, pagination}.
Ejemplo:
{
"name": "list_emails",
"arguments": {
"direction": "in",
"unread": true,
"limit": 25
}
}
get_email
Obtén un correo · Solo lectura · GET /emails/:email_id
Recupera un mensaje con encabezados, cuerpo html/texto, estado, metadatos del hilo y metadatos de archivos adjuntos (descarga los bytes con download_attachment).
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
email_id | string | sí | ID del correo (comienza con em_), como lo devuelve una herramienta de lista o creación. (máx. 128 caracteres) |
Devuelve: Objeto de correo: {id, direction, status, from, to, cc, bcc, subject, html, text, threadId, messageId, providerMessageId, readAt, createdAt, attachments: [{id, filename, contentType, sizeBytes, available}]}.
Ejemplo:
{
"name": "get_email",
"arguments": {
"email_id": "em_123"
}
}
mark_email
Marca como leído, archivado, spam o importante · Cambia el estado · PATCH /emails/:email_id
Actualiza un mensaje: read, archived, category (primary, updates, spam; solo correo recibido) y important. Reportar spam o marcar como importante enseña a SendHQ sobre ese remitente para correos futuros; pasa learn: false para cambiar solo este mensaje. Pasa al menos un campo.
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
email_id | string | sí | ID del correo (comienza con em_), como lo devuelve una herramienta de lista o creación. (máx. 128 caracteres) |
read | boolean | no | true = leído, false = no leído. |
archived | boolean | no | true = archivar (omitir la bandeja de entrada), false = mover de vuelta a la bandeja de entrada. |
category | string | no | Mueve un mensaje recibido a principal, actualizaciones o spam. (uno de primary, updates, spam) |
important | boolean | no | Marca o desmarca el mensaje como importante. |
learn | boolean | no | false = no recordar este veredicto para el remitente (predeterminado true). |
Devuelve: El objeto de correo actualizado.
Ejemplo:
{
"name": "mark_email",
"arguments": {
"email_id": "em_123",
"read": true
}
}
delete_email
Elimina un correo · Destructivo · DELETE /emails/:email_id
DESTRUCTIVO: elimina permanentemente un mensaje retenido y sus archivos adjuntos almacenados de SendHQ. No recupera un mensaje que ya fue entregado.
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
email_id | string | sí | ID del correo (comienza con em_), como lo devuelve una herramienta de lista o creación. (máx. 128 caracteres) |
Devuelve: {ok: true}.
Ejemplo:
{
"name": "delete_email",
"arguments": {
"email_id": "em_123"
}
}
list_email_events
Lista eventos de entrega de un correo · Solo lectura · GET /emails/:email_id/events
Eventos del proveedor para un mensaje enviado: entrega, rebote, queja, rechazo, apertura, clic. Esta es la evidencia de si un mensaje fue entregado o por qué falló. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
email_id | string | sí | ID del correo (comienza con em_), como lo devuelve una herramienta de lista o creación. (máx. 128 caracteres) |
limit | integer | no | Tamaño de página. El valor predeterminado es 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros para omitir. Usa pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [{event_type, recipient, reason, created_at, …}], count, pagination}.
Ejemplo:
{
"name": "list_email_events",
"arguments": {
"email_id": "em_123"
}
}
get_thread
Obtén una conversación · Solo lectura · GET /threads/:thread_id
Recupera cada mensaje en una conversación en orden cronológico (enviados y recibidos), cada uno con metadatos de archivos adjuntos.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
thread_id | string | sí | ID del hilo (normalmente el ID em_… del primer mensaje; ver threadId en cualquier correo). (máx. 128 caracteres) |
Devuelve: {id, subject, data: [emails]}.
Ejemplo:
{
"name": "get_thread",
"arguments": {
"thread_id": "em_123"
}
}
Etiquetas y reglas de archivado automático
list_labels
Listar etiquetas · Solo lectura · GET /labels
Lista las etiquetas (carpetas) del espacio de trabajo con recuentos totales y no leídos, y sus reglas de archivado automático. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
limit | integer | no | Tamaño de página. Por defecto 50. (por defecto 50; 1–200) |
offset | integer | no | Número de registros a omitir. Usa pagination.next_offset de la página anterior. (por defecto 0; 0–…) |
Devuelve: {data: [{id, name, color, totalCount, unreadCount, rules: [...]}], count, pagination}.
Ejemplo:
{
"name": "list_labels",
"arguments": {}
}
get_label
Obtener una etiqueta · Solo lectura · GET /labels/:label_id
Recupera una etiqueta con recuentos y reglas de archivado automático.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
label_id | string | sí | ID de la etiqueta (empieza con lbl_) o el nombre exacto de la etiqueta. (máx. 128 caracteres) |
Devuelve: Objeto de etiqueta.
Ejemplo:
{
"name": "get_label",
"arguments": {
"label_id": "Billing"
}
}
create_label
Crear una etiqueta · Cambia el estado · POST /labels
Crea una etiqueta tipo carpeta. Establece skip_inbox: true para convertirla en un bucket que un agente posee: envía con labels: [name] y las respuestas se archivan en la etiqueta y se mantienen fuera de la Bandeja de entrada. Las reglas opcionales de archivado automático archivan correos nuevos enviados/recibidos (cada condición de una regla debe coincidir). Establece apply_to_existing para archivar también el correo retenido.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
name | string | sí | Nombre de la etiqueta, p. ej. Billing o Clients/Acme. Único por espacio de trabajo (sin distinción de mayúsculas). (máx. 64 caracteres) |
color | string | no | Color hexadecimal como #1a73e8. Opcional. |
skip_inbox | boolean | no | Modo bucket: el correo recibido que obtiene esta etiqueta (por regla, al responder a una conversación enviada con esta etiqueta, o manualmente) se archiva para que aparezca solo en la etiqueta, no en la Bandeja de entrada. |
rules | object[] | no | Reglas opcionales de archivado automático (máx. 20). Cada una necesita al menos uno de inbox_id, from, to, subject. (0–20 elementos) |
rules[].direction | string | no | Solo correo in (recibido) o out (enviado). Omitir para ambos. (uno de in, out) |
rules[].inbox_id | string | no | Solo correo recibido por esta bandeja de entrada (inb_…). Archiva cada dirección receptora en su propia carpeta. |
rules[].from | string | no | El remitente contiene este texto (sin distinción de mayúsculas), p. ej. @stripe.com. (máx. 200 caracteres) |
rules[].to | string | no | Para/Cc contiene este texto (sin distinción de mayúsculas). (máx. 200 caracteres) |
rules[].subject | string | no | El asunto contiene este texto (sin distinción de mayúsculas). (máx. 200 caracteres) |
rules[].skip_inbox | boolean | no | Archiva el correo recibido que coincida para que aparezca solo en la carpeta de la etiqueta, no en la Bandeja de entrada. |
apply_to_existing | boolean | no | También archiva el correo ya retenido que coincida con las reglas. |
Devuelve: La etiqueta creada con sus reglas.
Ejemplo:
{
"name": "create_label",
"arguments": {
"name": "Agent/Orders",
"skip_inbox": true,
"rules": [
{
"from": "@stripe.com"
}
]
}
}
update_label
Renombrar, recolorar o convertir en bucket una etiqueta · Cambia el estado · PATCH /labels/:label_id
Renombra una etiqueta, cambia su color o alterna el modo bucket (skip_inbox). Activar el modo bucket archiva el correo recibido que ya está en la etiqueta.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
label_id | string | sí | ID de la etiqueta (empieza con lbl_) o el nombre exacto de la etiqueta. (máx. 128 caracteres) |
name | string | no | Nuevo nombre. (máx. 64 caracteres) |
color | string | no | Nuevo color hexadecimal. |
skip_inbox | boolean | no | Modo bucket: el correo recibido que obtiene esta etiqueta (por regla, al responder a una conversación enviada con esta etiqueta, o manualmente) se archiva para que aparezca solo en la etiqueta, no en la Bandeja de entrada. |
Devuelve: Etiqueta actualizada.
Ejemplo:
{
"name": "update_label",
"arguments": {
"label_id": "lbl_123",
"name": "Finance/Billing"
}
}
delete_label
Eliminar una etiqueta · Destructivo · DELETE /labels/:label_id
DESTRUCTIVO: elimina una etiqueta y sus reglas. El correo en sí se conserva; solo pierde esta etiqueta.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
label_id | string | sí | ID de la etiqueta (empieza con lbl_) o el nombre exacto de la etiqueta. (máx. 128 caracteres) |
Devuelve: {ok: true}.
Ejemplo:
{
"name": "delete_label",
"arguments": {
"label_id": "lbl_123"
}
}
create_label_rule
Añadir una regla de archivado automático · Cambia el estado · POST /labels/:label_id/rules
Añade una regla a una etiqueta para que el correo nuevo que coincida se archive automáticamente. Cada condición que establezcas debe coincidir. Usa inbox_id para dar a una dirección receptora su propia carpeta; añade skip_inbox para mantenerla fuera de la Bandeja de entrada.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
label_id | string | sí | ID de la etiqueta (empieza con lbl_) o el nombre exacto de la etiqueta. (máx. 128 caracteres) |
direction | string | no | Solo correo in (recibido) o out (enviado). Omitir para ambos. (uno de in, out) |
inbox_id | string | no | Solo correo recibido por esta bandeja de entrada (inb_…). Archiva cada dirección receptora en su propia carpeta. |
from | string | no | El remitente contiene este texto (sin distinción de mayúsculas), p. ej. @stripe.com. (máx. 200 caracteres) |
to | string | no | Para/Cc contiene este texto (sin distinción de mayúsculas). (máx. 200 caracteres) |
subject | string | no | El asunto contiene este texto (sin distinción de mayúsculas). (máx. 200 caracteres) |
skip_inbox | boolean | no | Archiva el correo recibido que coincida para que aparezca solo en la carpeta de la etiqueta, no en la Bandeja de entrada. |
apply_to_existing | boolean | no | También archiva el correo ya retenido que coincida. |
Devuelve: {id: lrule_…, labelId, direction, inboxId, from, to, subject, skipInbox}.
Ejemplo:
{
"name": "create_label_rule",
"arguments": {
"label_id": "Billing",
"inbox_id": "inb_123",
"skip_inbox": true
}
}
delete_label_rule
Eliminar una regla de archivado automático · Destructivo · DELETE /labels/:label_id/rules/:rule_id
DESTRUCTIVO: elimina una regla de archivado automático. El correo ya archivado conserva su etiqueta.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
label_id | string | sí | ID de la etiqueta (empieza con lbl_) o el nombre exacto de la etiqueta. (máx. 128 caracteres) |
rule_id | string | sí | ID de la regla (empieza con lrule_), de get_label. (máx. 128 caracteres) |
Devuelve: {ok: true}.
Ejemplo:
{
"name": "delete_label_rule",
"arguments": {
"label_id": "lbl_123",
"rule_id": "lrule_123"
}
}
label_email
Añadir o eliminar etiquetas en un correo · Cambia el estado · POST /emails/:email_id/labels
Mueve un mensaje entre carpetas: añade y/o elimina etiquetas por nombre o ID lbl_…. Los nombres desconocidos en add se crean a menos que create sea false.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
email_id | string | sí | ID del correo (empieza con em_), tal como lo devuelve una herramienta de listado o creación. (máx. 128 caracteres) |
add | string[] | no | Etiquetas a añadir. (0–10 elementos) |
remove | string[] | no | Etiquetas a eliminar. (0–10 elementos) |
create | boolean | no | Crear etiquetas desconocidas en add (por defecto true). |
Devuelve: El correo actualizado con labels.
Ejemplo:
{
"name": "label_email",
"arguments": {
"email_id": "em_123",
"add": [
"Billing"
],
"remove": [
"Support"
]
}
}
Borradores, adjuntos e identidades de remitente
list_sending_identities
Listar identidades de remitente verificadas · Solo lectura · GET /sending-identities
Direcciones y dominios desde los que este espacio de trabajo puede enviar ahora mismo (dominios verificados, su From predeterminado y direcciones de bandeja de entrada activas). Llama antes de send_email para elegir un from válido.
Sin parámetros.
Devuelve: {domains: [nombres de dominio verificados], addresses: [direcciones de remitente], localParts: [...]}.
Ejemplo:
{
"name": "list_sending_identities",
"arguments": {}
}
create_draft
Crear un borrador · Cambia el estado · POST /drafts
Crea un borrador de redactor. Los borradores admiten adjuntos: crea un borrador, upload_attachment y luego send_email con draft_id. No envía nada.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
from | string | no | Dirección de remitente en un dominio verificado (puede estar vacía mientras se redacta). |
to | string[] | no | Destinatarios. (0–100 elementos) |
cc | string[] | no | Destinatarios en copia. (0–100 elementos) |
bcc | string[] | no | Destinatarios en copia oculta. (0–100 elementos) |
subject | string | no | Línea de asunto. (máx. 998 caracteres) |
html | string | no | Cuerpo HTML. |
text | string | no | Cuerpo de texto plano. |
reply_to_email_id | string | no | ID del correo al que responde este borrador. |
thread_id | string | no | ID del hilo al que pertenece este borrador. |
Devuelve: Objeto de borrador {id: dr_…, from, to, cc, bcc, subject, html, text, attachments: []}.
Ejemplo:
{
"name": "create_draft",
"arguments": {
"from": "hello@example.com",
"to": [
"owner@example.com"
],
"subject": "Invoice"
}
}
list_drafts
Listar borradores · Solo lectura · GET /drafts
Lista los borradores del redactor, primero los más recientemente actualizados. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
limit | integer | no | Tamaño de página. Por defecto 50. (por defecto 50; 1–200) |
offset | integer | no | Número de registros a omitir. Usa pagination.next_offset de la página anterior. (por defecto 0; 0–…) |
Devuelve: {data: [borradores], count, pagination}.
Ejemplo:
{
"name": "list_drafts",
"arguments": {}
}
get_draft
Obtener un borrador · Solo lectura · GET /drafts/:draft_id
Recupera un borrador con sus metadatos de adjuntos.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
draft_id | string | sí | ID del borrador (empieza con dr_), tal como lo devuelve una herramienta de listado o creación. (máx. 128 caracteres) |
Devuelve: Objeto de borrador con attachments.
Ejemplo:
{
"name": "get_draft",
"arguments": {
"draft_id": "dr_123"
}
}
update_draft
Reemplazar contenido del borrador · Cambia el estado · PUT /drafts/:draft_id
Reemplaza el contenido y los destinatarios de un borrador. Esto es un reemplazo completo: los campos que omitas se borran, así que lee get_draft primero y envía cada campo que quieras conservar. Los adjuntos no se ven afectados.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
draft_id | string | sí | ID del borrador (empieza con dr_), tal como lo devuelve una herramienta de listado o creación. (máx. 128 caracteres) |
from | string | no | Dirección de remitente en un dominio verificado (puede estar vacía mientras se redacta). |
to | string[] | no | Destinatarios. (0–100 elementos) |
cc | string[] | no | Destinatarios en copia. (0–100 elementos) |
bcc | string[] | no | Destinatarios en copia oculta. (0–100 elementos) |
subject | string | no | Línea de asunto. (máx. 998 caracteres) |
html | string | no | Cuerpo HTML. |
text | string | no | Cuerpo de texto plano. |
reply_to_email_id | string | no | ID del correo al que responde este borrador. |
thread_id | string | no | ID del hilo al que pertenece este borrador. |
Devuelve: Objeto de borrador actualizado.
Ejemplo:
{
"name": "update_draft",
"arguments": {
"draft_id": "dr_123",
"from": "hello@example.com",
"to": [
"owner@example.com"
],
"subject": "Invoice (updated)",
"text": "Attached."
}
}
delete_draft
Descartar un borrador · Destructivo · DELETE /drafts/:draft_id
DESTRUCTIVO: descarta un borrador y elimina permanentemente sus adjuntos almacenados.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
draft_id | string | sí | ID del borrador (empieza con dr_), tal como lo devuelve una herramienta de listado o creación. (máx. 128 caracteres) |
Devuelve: {ok: true}.
Ejemplo:
{
"name": "delete_draft",
"arguments": {
"draft_id": "dr_123"
}
}
upload_attachment
Subir un adjunto a un borrador · Cambia el estado · POST /drafts/:draft_id/attachments
Sube un archivo a un borrador (máx. 10 archivos y 10 MB en total por mensaje). Proporciona content_base64 o un file_path local. Los adjuntos requieren un plan de pago al momento del envío.
Proporciona al menos uno de: content_base64, file_path.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
draft_id | string | sí | ID del borrador (comienza con dr_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
filename | string | no | Nombre de archivo mostrado al destinatario. Por defecto, el nombre base de file_path. (máx. 255 caracteres) |
content_type | string | no | Tipo MIME, p. ej. application/pdf. Por defecto, application/octet-stream. |
content_base64 | string | no | Contenido de archivo estándar en base64. |
file_path | string | no | Ruta absoluta de un archivo local legible por el proceso del servidor MCP. |
Devuelve: {id: att_…, filename, contentType, sizeBytes, available}.
Ejemplo:
{
"name": "upload_attachment",
"arguments": {
"draft_id": "dr_123",
"filename": "invoice.pdf",
"content_type": "application/pdf",
"file_path": "/tmp/invoice.pdf"
}
}
download_attachment
Descargar un adjunto · Solo lectura · GET /attachments/:attachment_id
Descarga un adjunto privado (enviado, recibido o borrador). Devuelve el contenido en base64, o escribe el archivo cuando save_to_path está configurado (se niega a sobrescribir a menos que overwrite sea verdadero).
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
attachment_id | string | sí | ID del adjunto (comienza con att_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
save_to_path | string | no | Ruta local absoluta opcional para escribir el archivo en lugar de devolver base64. |
overwrite | boolean | no | Permitir reemplazar un archivo existente en save_to_path. Por defecto, false. |
Devuelve: {attachment_id, filename, content_type, size_bytes, content_base64} o {attachment_id, filename, content_type, size_bytes, saved_to}.
Ejemplo:
{
"name": "download_attachment",
"arguments": {
"attachment_id": "att_123",
"save_to_path": "/tmp/invoice.pdf"
}
}
delete_attachment
Eliminar un adjunto · Destructivo · DELETE /attachments/:attachment_id
DESTRUCTIVO: elimina permanentemente un adjunto almacenado (por ejemplo, quitar un archivo de un borrador antes de enviarlo).
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
attachment_id | string | sí | ID del adjunto (comienza con att_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {ok: true}.
Ejemplo:
{
"name": "delete_attachment",
"arguments": {
"attachment_id": "att_123"
}
}
Plantillas alojadas
list_templates
Listar plantillas alojadas · Solo lectura · GET /templates
Lista plantillas de correo alojadas con estado de publicación y uso. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
lifecycle | string | no | active (predeterminado), archived o all. (uno de active, archived, all) |
query | string | no | Buscar por nombre o clave. (máx. 120 caracteres) |
limit | integer | no | Tamaño de página. Por defecto, 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros a omitir. Usa pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [templates], count, pagination}.
Ejemplo:
{
"name": "list_templates",
"arguments": {
"lifecycle": "active"
}
}
create_template
Crear una plantilla alojada · Cambia el estado · POST /templates
Crea una plantilla con un borrador editable, opcionalmente desde un iniciador (welcome, reset, receipt o blank). Publícala antes de enviar por clave.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
name | string | sí | Nombre legible. (máx. 120 caracteres) |
key | string | no | Clave de envío estable: letras minúsculas, números, guiones; comienza con una letra (2–64 caracteres). Derivada del nombre cuando se omite. |
starter | string | no | Contenido inicial. (uno de blank, welcome, reset, receipt) |
Devuelve: {template, draft, activeVersion, versions, usage}.
Ejemplo:
{
"name": "create_template",
"arguments": {
"name": "Account welcome",
"key": "account-welcome",
"starter": "welcome"
}
}
get_template
Obtener una plantilla · Solo lectura · GET /templates/:template_id
Recupera el borrador actual de una plantilla (con revision), la versión publicada activa, el historial de versiones y el uso. Acepta ID o clave.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
template_id | string | sí | ID de plantilla (tmpl_…) o clave. (máx. 128 caracteres) |
Devuelve: {template, draft: {id, revision, subjectTemplate, htmlTemplate, textTemplate, variables, sampleData, …} | null, activeVersion, versions, usage}.
Ejemplo:
{
"name": "get_template",
"arguments": {
"template_id": "account-welcome"
}
}
update_template_draft
Guardar un borrador de plantilla · Cambia el estado · PUT /templates/:template_id/draft
Guarda el borrador editable de la plantilla usando concurrencia optimista: pasa el revision actual de get_template (409 significa que otra persona guardó primero; vuelve a leer y reintenta). Esto es un reemplazo completo del contenido del borrador: los campos omitidos se borran, así que envía cada campo que quieras conservar. Usa marcadores de posición {{variable}}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
template_id | string | sí | ID de plantilla o clave. (máx. 128 caracteres) |
revision | integer | sí | Revisión actual del borrador desde get_template. (1–…) |
name | string | no | Nombre de la plantilla. (máx. 120 caracteres) |
subject_template | string | no | Asunto con marcadores de posición. (máx. 998 caracteres) |
preheader_template | string | no | Texto de vista previa. (máx. 240 caracteres) |
html_template | string | no | Cuerpo HTML con marcadores de posición. |
text_template | string | no | Cuerpo de texto plano con marcadores de posición. |
from | string | no | Remitente predeterminado para envíos de esta plantilla. |
reply_to | string | no | Responder a (Reply-To) predeterminado. |
variables | object[] | no | Contrato de variables tipadas. Cada elemento: {key (minúsculas/guiones bajos), label, type: text|number|url|boolean, required (predeterminado true), fallback, description}. |
variables[].key | string | sí | |
variables[].label | string | no | |
variables[].type | string | no | (uno de text, number, url, boolean) |
variables[].required | boolean | no | |
variables[].fallback | any | no | |
variables[].description | string | no | |
sample_data | object | no | Valores de muestra usados para vistas previas y pruebas. |
Devuelve: {template, draft: {revision: next}, validation: {valid, findings}}.
Ejemplo:
{
"name": "update_template_draft",
"arguments": {
"template_id": "account-welcome",
"revision": 3,
"name": "Account welcome",
"subject_template": "Welcome, {{first_name}}",
"text_template": "Hi {{first_name}}",
"variables": [
{
"key": "first_name",
"type": "text",
"required": true
}
],
"sample_data": {
"first_name": "Asha"
}
}
}
create_template_draft
Iniciar un nuevo borrador desde la versión publicada · Cambia el estado · POST /templates/:template_id/draft
Crea un nuevo borrador editable copiado de la versión publicada actual (409 si ya existe un borrador o no hay nada publicado).
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
template_id | string | sí | ID de plantilla o clave. (máx. 128 caracteres) |
Devuelve: {draft}.
Ejemplo:
{
"name": "create_template_draft",
"arguments": {
"template_id": "account-welcome"
}
}
render_template
Renderizar una vista previa de plantilla · Solo lectura · POST /templates/:template_id/render
Renderiza la salida exacta del servidor (asunto, html, texto) para el borrador, la versión publicada o una versión específica con los datos dados. No envía. Devuelve 422 con findings cuando los datos violan el contrato de variables.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
template_id | string | sí | ID de plantilla o clave. (máx. 128 caracteres) |
version_id | string | no | ID de versión opcional; por defecto, el borrador y luego la versión publicada. |
data | object | no | Valores de variables; por defecto, los datos de muestra de la versión. |
Devuelve: {subject, html, text, preheader, versionId, versionNumber, isDraft, findings}.
Ejemplo:
{
"name": "render_template",
"arguments": {
"template_id": "account-welcome",
"data": {
"first_name": "Asha"
}
}
}
send_template_test
Enviar un correo de prueba de plantilla · Envía correo real · POST /templates/:template_id/test
ENVÍA CORREO REAL. Envía una instantánea con prefijo [Test] del borrador (o de una versión dada) a los destinatarios indicados. Cuenta para el uso; los espacios de trabajo de prueba solo pueden enviar al correo de la cuenta o a una dirección de simulador de SES.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
template_id | string | sí | ID de plantilla o clave. (máx. 128 caracteres) |
to | string[] | sí | Destinatarios de prueba. (1–100 elementos) |
from | string | no | Remitente en un dominio verificado; por defecto, el De (From) de la plantilla. |
version_id | string | no | ID de versión opcional. |
data | object | no | Valores de variables; por defecto, datos de muestra. |
Devuelve: {id: em_…, providerMessageId, threadId, isTest: true}.
Ejemplo:
{
"name": "send_template_test",
"arguments": {
"template_id": "account-welcome",
"to": [
"owner@example.com"
]
}
}
publish_template
Publicar una versión de plantilla · Cambia el estado · POST /templates/:template_id/publish
Publica el borrador actual como una versión inmutable que send_email con template.key usará. Falla con hallazgos 422 en errores de validación, o 409 si rompería el contrato de variables en vivo de una plantilla ya usada en producción.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
template_id | string | sí | ID de plantilla o clave. (máx. 128 caracteres) |
Devuelve: {template, published}.
Ejemplo:
{
"name": "publish_template",
"arguments": {
"template_id": "account-welcome"
}
}
archive_template
Archivar una plantilla · Cambia el estado · POST /templates/:template_id/archive
Detén nuevos envíos que usen esta plantilla (el historial se conserva; reversible con restore_template). Cualquier integración que envíe esta clave comenzará a fallar con 404.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
template_id | string | sí | ID de plantilla o clave. (máx. 128 caracteres) |
Devuelve: {template}.
Ejemplo:
{
"name": "archive_template",
"arguments": {
"template_id": "account-welcome"
}
}
restore_template
Restaurar una plantilla archivada · Cambia el estado · POST /templates/:template_id/restore
Haz que una plantilla archivada vuelva a estar activa.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
template_id | string | sí | ID de plantilla o clave. (máx. 128 caracteres) |
Devuelve: {template}.
Ejemplo:
{
"name": "restore_template",
"arguments": {
"template_id": "account-welcome"
}
}
Dominios y DNS
list_domains
Listar dominios · Solo lectura · GET /domains
Lista dominios de envío con setup_status agregado (verified | checking | pending), estado DNS por registro y estado de entrada. Puede ser lento: los dominios no verificados se vuelven a comprobar en vivo. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
limit | integer | no | Tamaño de página. Por defecto, 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros a omitir. Usa pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [domains with records], count, pagination}.
Ejemplo:
{
"name": "list_domains",
"arguments": {}
}
get_domain
Obtener detalles de configuración del dominio · Solo lectura · GET /domains/:domain_id
Recupera un dominio con los registros DNS exactos a publicar (tipo, nombre, valor), el estado en vivo de cada registro desde dos resolutores públicos, dns_issues con correcciones y estado de entrada.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | sí | ID del dominio (comienza con dom_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {id, name, status, setup_status, dns_propagating, records: [{type, name, value, verified, dns_state}], dns_issues: [{code, message, …}], inbound_domain, inbound_status}.
Ejemplo:
{
"name": "get_domain",
"arguments": {
"domain_id": "dom_123"
}
}
add_domain
Agregar un dominio de envío · Cambia el estado · POST /domains
Registra un dominio que controlas para enviar. Devuelve los registros DNS (CNAMEs de SES Easy DKIM) que el propietario debe publicar. No cambia el DNS en sí. Cuenta para el límite de dominios del plan.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
name | string | sí | Nombre de dominio simple, p. ej. example.com o mail.example.com. (máx. 253 caracteres) |
default_from | string | no | Dirección de remitente predeterminada opcional en este dominio. |
Devuelve: {id: dom_…, name, status: pending, records: [...], ses: {configured}}.
Ejemplo:
{
"name": "add_domain",
"arguments": {
"name": "example.com"
}
}
verify_domain
Verificar un dominio · Cambia el estado · POST /domains/:domain_id/verify
Ejecuta una verificación en vivo de SES/DNS ahora. Es seguro repetirla; consulta cada 30–60 s después de cambios de DNS (la propagación puede tardar de minutos a horas). El envío está permitido una vez que el estado sea verified.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | sí | ID de dominio (comienza con dom_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {domain, checks: {ses, dkim, dkim_status}, status: verified|pending}.
Ejemplo:
{
"name": "verify_domain",
"arguments": {
"domain_id": "dom_123"
}
}
delete_domain
Eliminar un dominio · Destructivo · DELETE /domains/:domain_id
DESTRUCTIVO: elimina el dominio del espacio de trabajo, incluida su ruta de recepción entrante. Los envíos desde él fallan inmediatamente después. No elimina los registros DNS en tu proveedor de DNS.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | sí | ID de dominio (comienza con dom_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {ok: true}.
Ejemplo:
{
"name": "delete_domain",
"arguments": {
"domain_id": "dom_123"
}
}
get_dns_provider
Detectar proveedor de DNS y hosts de registros · Solo lectura · GET /dns/provider
Detecta el proveedor de DNS autoritativo del dominio y devuelve el host relativo que se debe escribir en ese proveedor para cada registro, el registro DMARC recomendado, la guía de MX entrante y si la configuración de un clic (Domain Connect) está disponible.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | sí | ID de dominio (comienza con dom_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {detectionStatus, detected, zone, nameservers, recordHosts: {recordId: host}, inbound, recommendations, authentication, providers: {domainConnect: {available, providerName}}}.
Ejemplo:
{
"name": "get_dns_provider",
"arguments": {
"domain_id": "dom_123"
}
}
get_domain_connect_link
Obtener un enlace de configuración de DNS de un clic · Solo lectura · GET /dns/domain-connect/connect
Cuando get_dns_provider informe providers.domainConnect.available, crea una URL de consentimiento firmada. Entrégasela al humano: la abre y aprueba el cambio de DNS en su proveedor. Nada cambia hasta que la apruebe. 409 si no es compatible.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | sí | ID de dominio (comienza con dom_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {url, providerName}.
Ejemplo:
{
"name": "get_domain_connect_link",
"arguments": {
"domain_id": "dom_123"
}
}
Correo entrante
setup_inbound
Habilitar la recepción entrante para un dominio · Cambia el estado · POST /domains/:domain_id/inbound/setup
Aprovisiona la recepción entrante de SES para un dominio verificado. Usa el dominio raíz cuando no tiene un MX conflictivo; de lo contrario, inbound.<domain>. Devuelve el registro MX que el propietario debe publicar; no edita el DNS.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | sí | ID de dominio (comienza con dom_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {domain: receiving domain, status: dns_pending|ready, record: {type: MX, name, value}}.
Ejemplo:
{
"name": "setup_inbound",
"arguments": {
"domain_id": "dom_123"
}
}
verify_inbound
Verificar MX entrante · Cambia el estado · POST /domains/:domain_id/inbound/verify
Vuelve a comprobar el registro MX entrante. El estado se convierte en ready cuando ambos resolutores públicos lo ven.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | sí | ID de dominio (comienza con dom_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {domain, status: ready|dns_pending|propagating|checking, record}.
Ejemplo:
{
"name": "verify_inbound",
"arguments": {
"domain_id": "dom_123"
}
}
list_inboxes
Listar direcciones entrantes · Solo lectura · GET /inboxes
Lista las direcciones de recepción, opcionalmente para un dominio. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | no | Filtro opcional por ID de dominio. |
limit | integer | no | Tamaño de página. El valor predeterminado es 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros a omitir. Usa pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [{id, address, name, status, domainId}], count, pagination}.
Ejemplo:
{
"name": "list_inboxes",
"arguments": {
"domain_id": "dom_123"
}
}
get_inbox
Obtener una bandeja de entrada · Solo lectura · GET /inboxes/:inbox_id
Recupera una dirección entrante.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
inbox_id | string | sí | ID de bandeja de entrada (comienza con inb_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: Objeto de bandeja de entrada.
Ejemplo:
{
"name": "get_inbox",
"arguments": {
"inbox_id": "inb_123"
}
}
create_inbox
Crear una dirección entrante · Cambia el estado · POST /inboxes
Crea una dirección como support@<receiving domain> en un dominio cuyo estado entrante sea ready (ejecuta setup_inbound y verify_inbound primero). El correo recibido aparece en list_emails con la dirección in.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
domain_id | string | sí | ID de dominio (comienza con dom_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
local_part | string | sí | Parte antes de @, p. ej. support. (máx. 64 caracteres) |
name | string | no | Nombre para mostrar opcional. |
Devuelve: {id: inb_…, address, name, status: active}.
Ejemplo:
{
"name": "create_inbox",
"arguments": {
"domain_id": "dom_123",
"local_part": "support",
"name": "Support"
}
}
update_inbox
Renombrar, habilitar o deshabilitar una bandeja de entrada · Cambia el estado · PATCH /inboxes/:inbox_id
Renombra una bandeja de entrada o establece su estado en active / disabled.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
inbox_id | string | sí | ID de bandeja de entrada (comienza con inb_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
name | string | no | Nuevo nombre para mostrar. |
status | string | no | Nuevo estado. (uno de active, disabled) |
Devuelve: Bandeja de entrada actualizada.
Ejemplo:
{
"name": "update_inbox",
"arguments": {
"inbox_id": "inb_123",
"status": "disabled"
}
}
set_inbox_forwarding
Reenviar una bandeja de entrada a otra dirección · Envía correo real · PUT /inboxes/:inbox_id/forwarding
ENVÍA CORREO REAL cuando se reenvía a alguien que no sea el propietario de la cuenta: establece a dónde se reenvía el correo recibido de una bandeja de entrada. La dirección del propio propietario se activa de inmediato; cualquier otra dirección recibe un correo de confirmación y el reenvío permanece en pending hasta que alguien allí confirme. Pasa forward_to: null para desactivar el reenvío. Las copias reenviadas provienen de la dirección de la bandeja de entrada con el remitente original como Reply-To.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
inbox_id | string | sí | ID de bandeja de entrada (comienza con inb_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
forward_to | string,null | sí | Dirección de correo de destino del reenvío, o null para desactivar el reenvío. (máx. 254 caracteres) |
Devuelve: Bandeja de entrada con forwardTo y forwardStatus (off, pending o active).
Ejemplo:
{
"name": "set_inbox_forwarding",
"arguments": {
"inbox_id": "inb_123",
"forward_to": "team@example.net"
}
}
delete_inbox
Eliminar una bandeja de entrada · Destructivo · DELETE /inboxes/:inbox_id
DESTRUCTIVO: elimina una dirección entrante. El correo ya recibido se conserva; el correo nuevo a la dirección ya no se archiva en ella.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
inbox_id | string | sí | ID de bandeja de entrada (comienza con inb_), tal como lo devuelve una herramienta de listar o crear. (máx. 128 caracteres) |
Devuelve: {ok: true}.
Ejemplo:
{
"name": "delete_inbox",
"arguments": {
"inbox_id": "inb_123"
}
}
Entregabilidad, rebotes y supresiones
deliverability_stats
Obtener estadísticas de entrega de 30 días · Solo lectura · GET /deliverability/stats
Totales de 30 días en todo el espacio de trabajo: enviados, entregados, rebotados, quejas, rechazados, abiertos, clics y deliveryRate (%).
Sin parámetros.
Devuelve: {window: 30d, sent, delivery, bounce, complaint, reject, open, click, deliveryRate}.
Ejemplo:
{
"name": "deliverability_stats",
"arguments": {}
}
list_sender_reputation
Listar reputación del remitente · Solo lectura · GET /deliverability/reputation
Estado de reputación por dirección From exacta: active, throttled (límite diario más bajo) o paused (los envíos devuelven 423), con el motivo y el límite diario. Verifica esto cuando los envíos fallen con 423 o 429. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
limit | integer | no | Tamaño de página. El valor predeterminado es 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros a omitir. Usa pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [{sender, status, dailyLimit, reason, cleanSince, warnedAt, pausedAt, evaluatedAt}], count, pagination}.
Ejemplo:
{
"name": "list_sender_reputation",
"arguments": {}
}
list_suppressions
Listar supresiones · Solo lectura · GET /suppressions
Lista de supresiones del espacio de trabajo: destinatarios bloqueados después de un rebote permanente o una queja de spam. Los envíos a ellos fallan con 422. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
limit | integer | no | Tamaño de página. El valor predeterminado es 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros a omitir. Usa pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [{email, reason, detail, created_at}], count, pagination}.
Ejemplo:
{
"name": "list_suppressions",
"arguments": {}
}
remove_suppression
Eliminar una supresión por rebote · Destructivo · DELETE /suppressions/:email
DESTRUCTIVO (debilitar un bloqueo de seguridad): elimina una supresión por rebote para que la dirección pueda recibir correo nuevamente. Solo hazlo cuando el humano confirme que la dirección ahora es válida. Las supresiones por queja no se pueden eliminar (409).
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
email | string | sí | Dirección de destinatario suprimida. (máx. 320 caracteres) |
Devuelve: {ok: true}.
Ejemplo:
{
"name": "remove_suppression",
"arguments": {
"email": "fixed-mailbox@example.net"
}
}
list_blocked_recipients
Listar destinatarios bloqueados · Solo lectura · GET /blocked-recipients
Cada destinatario que SendHQ rechazará: rebotes, quejas y bajas de marketing por dominio, con un resumen por tipo. Lee hasta los 500 más recientes. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
limit | integer | no | Tamaño de página. El valor predeterminado es 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros a omitir. Usa pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [{email, domain, kind: bounce|complaint|unsubscribe, reason, detail, source, status, created_at}], count, summary: {total, bounce, complaint, unsubscribe}, pagination}.
Ejemplo:
{
"name": "list_blocked_recipients",
"arguments": {}
}
Cuenta, uso, analíticas y claves
get_account
Obtener cuenta, uso y facturación · Solo lectura · GET /account
Correo del propietario de la cuenta, plan/nivel de acceso, entregas a destinatarios del período actual usadas frente a la cuota, dominios usados frente al límite, transferencia de archivos adjuntos, resumen de reputación, estado de la suscripción, planes publicados y recuentos del espacio de trabajo. Úsalo para verificar la cuota restante o a quién puede entregar la prueba (el correo de la cuenta).
Sin parámetros.
Devuelve: {user: {email, …}, usage: {domainsUsed, domainLimit, recipientDeliveries, emailQuotaMonth, attachmentBytes, attachmentByteLimit, periodKey}, access: {tier, planCode}, reputation, infrastructure, billing: {status, subscriptions, …}, plans, workspace: {mailer, stats}}.
Ejemplo:
{
"name": "get_account",
"arguments": {}
}
get_analytics
Obtener analíticas de envío · Solo lectura · GET /analytics
Analíticas del panel para los últimos 7, 30 o 90 días: totales de enviados/recibidos/entregados/rebotados/bloqueados/abiertos/clicados/quejas, una línea de tiempo diaria, dominios de envío principales y asuntos principales.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
days | integer | no | Ventana en días: 7, 30 (predeterminado) o 90. (uno de 7, 30, 90) |
Devuelve: {window, days, metrics, timeline: [{day, sent, received}], domains, topContent}.
Ejemplo:
{
"name": "get_analytics",
"arguments": {
"days": 30
}
}
list_api_keys
Listar metadatos de claves API · Solo lectura · GET /keys
Lista los nombres de las claves API, los prefijos no secretos y las horas de último uso. Solo lectura: este servidor MCP no puede crear, rotar ni revocar claves; eso lo hace una persona en el panel de control. Paginado: el resultado incluye pagination {offset, limit, returned, total?, has_more, next_offset}.
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
limit | integer | no | Tamaño de página. Predeterminado: 50. (predeterminado 50; 1–200) |
offset | integer | no | Número de registros a omitir. Use pagination.next_offset de la página anterior. (predeterminado 0; 0–…) |
Devuelve: {data: [{id, name, prefix, lastUsedAt, createdAt}], count, pagination}.
Ejemplo:
{
"name": "list_api_keys",
"arguments": {}
}
get_service_health
Verificar el estado del servicio SendHQ · Solo lectura · GET /health
Verifica que la API de SendHQ esté activa y qué proveedor de correo está activo. No requiere una clave API válida.
Sin parámetros.
Devuelve: {ok, service, mailer}.
Ejemplo:
{
"name": "get_service_health",
"arguments": {}
}
Inventario de cobertura de API
Cada operación en la API pública y la herramienta que la cubre. Todo lo que un usuario puede hacer en el panel de control que tenga API está cubierto; las exclusiones a continuación son deliberadas.
| Endpoint | Herramienta | Notas |
|---|---|---|
| POST /emails | send_email | Enviar un correo |
| POST /emails/batch | send_batch | Enviar hasta 100 mensajes individualizados |
| GET /emails | list_emails | Listar correos enviados y recibidos |
| GET /emails/:id | get_email | Recuperar un correo y sus adjuntos |
| PATCH /emails/:id | mark_email | Actualizar leído, archivo, spam, categoría o importancia |
| POST /emails/:id/labels | label_email | Agregar o quitar etiquetas en un correo |
| DELETE /emails/:id | delete_email | Eliminar un correo retenido |
| GET /emails/:id/events | list_email_events | Listar eventos de entrega de un correo |
| GET /threads/:id | get_thread | Recuperar una conversación cronológicamente |
| GET /labels | list_labels | Listar etiquetas con conteos de mensajes y reglas de archivado |
| POST /labels | create_label | Crear una etiqueta, opcionalmente con reglas de archivado automático |
| GET /labels/:id | get_label | Recuperar una etiqueta por ID o nombre |
| PATCH /labels/:id | update_label | Renombrar, recolorar o convertir una etiqueta en un contenedor |
| DELETE /labels/:id | delete_label | Eliminar una etiqueta sin eliminar sus correos |
| POST /labels/:id/rules | create_label_rule | Agregar una regla de archivado automático a una etiqueta |
| DELETE /labels/:id/rules/:rule_id | delete_label_rule | Eliminar una regla de archivado automático |
| POST /drafts | create_draft | Crear un borrador del editor |
| GET /drafts | list_drafts | Listar borradores del editor |
| GET /drafts/:id | get_draft | Recuperar un borrador y adjuntos |
| PUT /drafts/:id | update_draft | Reemplazar el contenido del borrador |
| DELETE /drafts/:id | delete_draft | Descartar un borrador |
| POST /drafts/:id/attachments | upload_attachment | Subir un adjunto a un borrador |
| GET /attachments/:id | download_attachment | Descargar un adjunto privado |
| DELETE /attachments/:id | delete_attachment | Eliminar un adjunto privado |
| GET /sending-identities | list_sending_identities | Listar identidades de remitente verificadas |
| GET /templates | list_templates | Listar plantillas alojadas |
| POST /templates | create_template | Crear una plantilla alojada |
| GET /templates/:id | get_template | Recuperar borradores, versiones publicadas y uso |
| PUT /templates/:id/draft | update_template_draft | Guardar automáticamente un borrador de plantilla |
| POST /templates/:id/draft | create_template_draft | Crear un nuevo borrador a partir de la versión publicada |
| POST /templates/:id/render | render_template | Renderizar la salida exacta del servidor |
| POST /templates/:id/test | send_template_test | Enviar una vista previa de prueba |
| POST /templates/:id/publish | publish_template | Publicar una versión de plantilla inmutable |
| POST /templates/:id/archive | archive_template | Archivar una plantilla |
| POST /templates/:id/restore | restore_template | Restaurar una plantilla archivada |
| POST /domains | add_domain | Agregar un dominio de envío |
| GET /domains | list_domains | Listar dominios y estado de DNS en caché |
| GET /domains/:id | get_domain | Recuperar detalles de configuración del dominio |
| POST /domains/:id/verify | verify_domain | Actualizar la verificación de SES y DNS |
| POST /domains/:id/inbound/setup | setup_inbound | Aprovisionar recepción entrante de SES |
| POST /domains/:id/inbound/verify | verify_inbound | Verificar el enrutamiento MX entrante |
| DELETE /domains/:id | delete_domain | Eliminar un dominio |
| GET /dns/provider | get_dns_provider | Detectar el proveedor de DNS autoritativo y los hosts de registros relativos |
| GET /dns/domain-connect/connect | get_domain_connect_link | Crear un enlace de consentimiento de Domain Connect para configuración de DNS en un clic |
| POST /inboxes | create_inbox | Crear una dirección entrante |
| GET /inboxes | list_inboxes | Listar direcciones entrantes |
| GET /inboxes/:id | get_inbox | Recuperar una dirección entrante |
| PATCH /inboxes/:id | update_inbox | Renombrar, habilitar o deshabilitar una bandeja de entrada |
| PUT /inboxes/:id/forwarding | set_inbox_forwarding | Reenviar el correo recibido de una bandeja de entrada a otra dirección |
| DELETE /inboxes/:id | delete_inbox | Eliminar una bandeja de entrada conservando los mensajes |
| GET /deliverability/stats | deliverability_stats | Recuperar estadísticas de entrega de 30 días |
| GET /deliverability/reputation | list_sender_reputation | Listar el estado de reputación por identidad de remitente exacta |
| GET /suppressions | list_suppressions | Listar supresiones del espacio de trabajo |
| DELETE /suppressions/:email | remove_suppression | Eliminar una supresión de rebote elegible |
| GET /blocked-recipients | list_blocked_recipients | Listar rebotes, quejas y cancelaciones de suscripción |
| GET /account | get_account | Recuperar cuenta, uso, estado de facturación y conteos del espacio de trabajo con una clave API |
| GET /analytics | get_analytics | Recuperar análisis de envío del panel de control para 7, 30 o 90 días |
| GET /profile | get_account | Gemelo solo de sesión de GET /account; el servidor MCP lee la ruta de clave API. |
| POST /billing/checkout | no expuesto | Los cambios de facturación son solo de sesión por diseño y requieren al propietario de la cuenta en el panel de control. El estado de facturación es legible con get_account. |
| POST /billing/cancel | no expuesto | Los cambios de facturación son solo de sesión por diseño y requieren al propietario de la cuenta en el panel de control. El estado de facturación es legible con get_account. |
| POST /keys | no expuesto | Excluido deliberadamente: un agente no debe crear ni destruir credenciales. Las claves son gestionadas por una persona en el panel de control. |
| GET /keys | list_api_keys | Listar metadatos de claves API |
| DELETE /keys/:id | no expuesto | Excluido deliberadamente: un agente no debe crear ni destruir credenciales. Las claves son gestionadas por una persona en el panel de control. |
Deliberadamente no disponible
| Capacidad | Endpoints | Razón |
|---|---|---|
| Crear, rotar, revocar o eliminar claves API | POST /keys, DELETE /keys/:id | Excluido deliberadamente: un agente no debe crear ni destruir credenciales. Las claves son gestionadas por una persona en el panel de control. |
| Iniciar un pago o cancelar una suscripción | POST /billing/checkout, POST /billing/cancel | Los cambios de facturación son solo de sesión por diseño y requieren al propietario de la cuenta en el panel de control. El estado de facturación es legible con get_account. |
| DNS de un clic de Cloudflare (OAuth) | GET /api/dns/cloudflare/connect | Requiere una sesión de navegador interactiva y consentimiento OAuth de Cloudflare. Use get_domain records, get_dns_provider hosts o get_domain_connect_link en su lugar. |
| Registrarse, iniciar sesión, cerrar sesión, vinculación de cuenta de Google | /api/auth/* | Autenticación humana en navegador; el servidor MCP se autentica con una clave API. |
| Formulario de contacto de soporte | POST /api/contact | Formulario público del sitio de marketing para personas, no una operación del espacio de trabajo. |
Catálogo legible por máquina: /docs/mcp/tools.json (esquemas, anotaciones, mapeo de endpoints, exclusiones). Versión Markdown de esta página: /docs/mcp.md. Con la CLI instalada, sendhq commands --format json imprime el mismo catálogo.