Abrir un buzón

Agentes de IA y MCP

Buzón MCP: que tu agente de IA confirme su propio registro

Un agente autónomo llega hasta «revisa tu correo para ver el código» y se detiene ahí. Este es el arreglo completo: seis herramientas MCP, sin cuenta y sin clave, y una de ellas espera hasta que el mensaje realmente llega.

  • Intermedio
  • 13 min de lectura
Un pequeño robot gris que le tiende un sobre azul a un buzón abierto, con un cronómetro esperando entre los dos

Qué necesita un agente que una API REST no le da

En este sitio hay una API REST, y a un programador que la integre le irá bien. A un agente no: no puede abrir la referencia, decidir cuál de tres endpoints quiere, y montar a mano una petición con la cadena de consulta correcta. Le pregunta a un servidor qué puede hacer, recibe esquemas legibles por máquina, y llama a una.

Así que todo lo que hace el servicio se expone una segunda vez, como herramientas. Seis de ellas, y ningún estado que gestionar entre llamadas:

HerramientaPara qué sirve
create_inboxInventa una dirección nueva que el agente puede dar de inmediato. No se reserva nada en el servidor, así que no puede fallar. Admite un prefix legible opcional; un sufijo aleatorio la mantiene única.
list_domainsLos dominios públicos que cualquiera puede usar — útil cuando un formulario acaba de rechazar uno de ellos.
list_messagesTodo lo que espera en una dirección, lo más reciente primero. Responde al instante, incluso cuando no hay nada.
read_messageUn mensaje completo: remitente, asunto, texto plano, HTML, adjuntos. Aquí es donde está el código o el enlace de acceso.
wait_for_messageEspera hasta que llega algo, y luego lo devuelve completo. La herramienta que hay que llamar en el momento en que se envía un formulario.
delete_messageElimina uno ahora en lugar de esperar 5 días a que caduque. Es idempotente, así que a un agente reintentarlo no le cuesta nada.

El servidor también responde a initialize con un breve párrafo de instrucciones, que la mayoría de los clientes pasan directamente al modelo. Así, un agente llega ya sabiendo para qué sirve este servicio y cuál es su única advertencia real, sin que nadie tenga que escribirlo en un prompt.

Conectar un cliente en una línea

El endpoint es una sola URL, y no hay nada a lo que registrarse en los dominios públicos. Todos los clientes MCP usan el mismo tipo de configuración — Claude Desktop, Claude Code, Cursor, Continue, el OpenAI Agents SDK y cualquier otro que hable el protocolo:

mcp.json
{"mcpServers":{"grabmail":{"url":"https://grabmail.io/mcp"}}}

El transporte es Streamable HTTP: un POST que lleva JSON-RPC 2.0, una respuesta JSON, ningún flujo que se quede abierto. Así que puedes comprobar todo esto desde una terminal antes de que intervenga ningún agente:

listar las herramientas, desde una terminal
curl -sX POST https://grabmail.io/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Los clientes que buscan un servidor antes de preguntarle a un humano encontrarán /.well-known/mcp.json en el dominio, que indica ese mismo endpoint y su transporte.

Todo el flujo de registro, en cuatro llamadas a herramientas

Esta es la secuencia que necesita casi cualquier agente, y no hay nada más que añadir:

  1. Llama a create_inbox. Devuelve una dirección, un alias, el dominio, y una nota que le dice al agente cuál de los dos entregar. No se creó nada — el buzón empieza a existir cuando llega a él el primer mensaje.
  2. Pon el alias en el formulario. El servicio al que te registras recibe una dirección funcional que llega al buzón y no puede usarse para leerlo.
  3. Llama a wait_for_message con la dirección. Justo después de enviar el formulario, no con un temporizador. Espera; no consulta en un bucle que el agente tenga que escribir.
  4. Lee el código dentro del mensaje. El cuerpo completo llega junto con la espera, así que normalmente no hace falta una segunda llamada — read_message solo hace falta para algo que llegó antes.
Tu agentetoma una dirección y un aliasEl sitiorecibe el alias, envía el códigoGrabMailretiene lo que llegawait_for_message, hasta 25 sdevuelve el mensaje completo, o timed_out
Cuatro llamadas, y solo una de ellas espera. El alias sale hacia el sitio; la dirección se queda con el agente y es sobre la que escucha.

Por qué wait_for_message responde antes de que llegue el correo

Es la herramienta que hace que un agente funcione de verdad, y la que más sorprende por su comportamiento, así que merece un minuto. Una llamada tiene este aspecto:

esperar un mensaje con “code” en el asunto
curl -sX POST https://grabmail.io/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":
        {"name":"wait_for_message",
         "arguments":{"address":"demo.5kuqarzuch@grabmail.io",
                       "subject_contains":"code"}}}'

Espera hasta 25 segundos. Si para entonces no ha llegado nada, no falla — vuelve con una respuesta clara y pide que se la llame de nuevo:

respuesta tras una espera sin novedades
{
  "timed_out": true,
  "waited_seconds": 25,
  "message": null,
  "note": "Nothing arrived yet. Call wait_for_message again ..."
}
Por qué tiene un límite
Cada segundo de espera es un worker del servidor que no hace más que dormir, y hay un número fijo de ellos. Una espera que pudiera durar cinco minutos sería un agente ocupando un puesto que necesitan otros cien. 25 segundos también cabe dentro del tiempo de espera por defecto de cualquier cliente, así que la llamada responde en vez de que el cliente se rinda antes.
Solo 8 esperas a la vez
Pasado ese número, la herramienta responde de inmediato con timed_out y una nota que lo explica. Que te digan que vuelvas es mejor que quedar en cola detrás de otros siete agentes sin ninguna forma de saberlo.
Filtrado, para que el correo equivocado no la interrumpa
from_contains y subject_contains hacen que la espera ignore cualquier otra cosa que llegue mientras tanto. since_id es el que hay que pasar cuando el buzón ya tenía algo dentro: dale el id más reciente ya visto y solo un correo genuinamente nuevo satisfará la llamada.

Da el alias, consulta la dirección

Cada buzón aquí tiene una segunda dirección, de doce caracteres, que entrega en el mismo buzón pero no puede leerlo. Esa distinción importa mucho más para un agente que para una persona, porque un agente pegará sin dudar lo que sea que se le dio en cualquier campo que encuentre.

Así que create_inbox no simplemente devuelve una dirección y confía en que salga bien. Devuelve las dos, y un next_step que dice cuál es cuál — el agente lee el resultado de su propia herramienta, así que la instrucción llega justo donde se necesita en lugar de quedarse en una página de documentación que nadie en el bucle puede leer.

Qué poner en las instrucciones del propio agente

Las herramientas se describen a sí mismas lo bastante bien como para que un modelo capaz lo haga bien sin que se le indique. Cinco líneas lo hacen fiable en vez de solo probable:

  • Una dirección por registro. No una dirección reutilizada en todas partes: un buzón con el correo de seis servicios son seis confirmaciones que el agente tiene que distinguir, y una sola fuga que las expone todas.
  • Da el alias, nunca la dirección. Merece la pena decirlo explícitamente, aunque el resultado de la herramienta ya lo diga.
  • Llama a wait_for_message justo después de enviar el formulario, y vuelve a llamarla si responde timed_out en lugar de tratarlo como un fallo. Dos o tres veces es normal.
  • Pasa since_id cuando el buzón no es nuevo, o un mensaje antiguo satisfará la espera y el agente leerá un código que caducó hace una hora.
  • Elimina el mensaje en cuanto se use el código. No es obligatorio — todo desaparece en 5 días de todas formas — pero cierra la ventana antes y cuesta una sola llamada idempotente.

Escrito como bloque de instrucciones, viene a ser tan largo como esto:

system prompt, o una línea en AGENTS.md
Cuando necesites una dirección de correo, llama a create_inbox y da el ALIAS
que devuelve, nunca la dirección. Justo después de enviar el formulario, llama a
wait_for_message con la dirección. Si responde timed_out, vuelve a llamarla —
eso es normal y no se ha perdido nada. Pasa since_id si el buzón ya tenía correo.
Elimina el mensaje en cuanto se haya usado el código.

Los límites que conviene conocer antes de construir sobre esto

Todos están publicados en lugar de tener que descubrirlos, y ninguno tiene un plan que los amplíe:

LímiteValorQué significa para un agente
Una espera25 segundosLuego timed_out. Vuelve a llamar; no lo trates como un error.
Esperas simultáneas8Pasado ese número, la herramienta responde al instante y lo indica. Recurre a list_messages.
LecturasUna por segundo, por direcciónMuy por encima de lo que hace un bucle de llamadas a herramientas. Una espera bloqueante es una sola solicitud, no sesenta.
Tamaño del mensaje5 MBSe rechaza durante la conversación SMTP, así que se avisa al remitente en lugar de dejar al agente esperando algo que nunca va a llegar.
Retención5 díasUn límite estricto que aplica un proceso automático. Cualquier cosa que el agente deba conservar, tiene que anotarla por su cuenta.

No hay ningún endpoint de envío ni ninguna herramienta para eso. Este servicio solo recibe, que es lo que evita que un buzón sin autenticación se convierta en un relay de spam — así que un agente que necesite responderle a un humano necesita un buzón real en otro lugar.

Cuando un formulario rechaza los dominios públicos

Muchos servicios mantienen listas de dominios de correo desechable, y los tres dominios públicos de aquí están en ellas. Un agente se encuentra esto como un formulario que rechaza la dirección que se le acaba de dar, o peor, la acepta y nunca envía nada.

La solución duradera es un dominio propio. Un registro MX convierte cada dirección de ese dominio en un buzón aquí, no está en ninguna lista porque no aparece impreso en ninguna parte de este sitio, y las mismas seis herramientas funcionan en él sin cambioscreate_inbox es la única que no, ya que esa inventa direcciones en los dominios públicos. El agente simplemente usa you-pick-it@your-domain y llama a wait_for_message sobre esa dirección.

Registro MX para tu dominio10 smtp.grabmail.io

Aquí está la guía completa paso a paso: el registro, qué demuestra publicarlo, y los límites de un buzón sin contraseña.

Qué no dejar que un agente haga con esto

La parte honesta, y la que te ahorra una tarde:

  • Nada que necesites poder recuperar. Nada que contenga dinero, identidad o trabajo. El buzón vuelve a estar vacío en 5 días y puede leerlo quien conozca la dirección, así que un restablecimiento de contraseña enviado ahí el año que viene no llega a nadie — o le llega a otra persona.
  • No como segundo factor. Un buzón sin contraseña no es un factor.
  • No para nada privado. No porque lo leamos nosotros, sino porque la dirección es el único secreto en juego y es bastante posible que un agente la haya escrito en un log, una transcripción o un mensaje de commit.
  • No para volumen. Un agente que abre cuentas por centenares es exactamente el comportamiento para el que existe cada lista de bloqueo, y es la forma más rápida de conseguir que los dominios públicos queden rechazados para todos los demás.

Usado para lo que es — el paso de confirmación que se interpone entre un agente y lo que de verdad se le pidió hacer — elimina el único paso que lo detiene de forma fiable.

Preguntas

¿Necesito una clave de API o una cuenta?

No. Los dominios públicos, las herramientas y un dominio propio son todos gratuitos y sin autenticación. El único caso que lleva clave es un dominio que se ha cerrado a petición, que entonces exige una cabecera Authorization.

¿Con qué clientes funciona esto?

Cualquier cliente que hable el Model Context Protocol — Claude Desktop, Claude Code, Cursor, Continue, el OpenAI Agents SDK y los demás. El transporte es Streamable HTTP, que es lo que usan por defecto los clientes actuales, y se aceptan tres versiones del protocolo para que uno más antiguo también pueda conectarse.

¿Por qué wait_for_message devuelve timed_out?

Porque una sola espera tiene un tope de 25 segundos, a propósito. No es un error y no se ha perdido nada: vuelve a llamarla. El correo tarda a menudo más de lo que sugiere la página que lo prometió, y dos o tres esperas seguidas son un registro normal.

¿Puede el agente usar mi propio dominio en su lugar?

Sí, y no cambia nada salvo la dirección. Apunta un registro MX a smtp.grabmail.io y cada dirección de ese dominio se vuelve legible a través de las mismas herramientas. Solo create_inbox funciona exclusivamente en los dominios públicos, porque es la que inventa un nombre por ti.

¿Puede un agente enviar correo con esto?

No. No hay ninguna herramienta de envío ni ningún endpoint de envío, por diseño: un servicio sin autenticación que pudiera enviar correo sería un relay de spam en menos de un día. Nuestro SPF es v=spf1 -all y nuestro DMARC es p=reject, así que cualquier cosa que diga venir de una dirección de aquí está falsificada.

¿Es privado el buzón?

No, y esta es la única advertencia que hay que darle a un agente de forma explícita. En un dominio público, cualquiera que conozca o adivine la dirección puede leerlo. Usa una dirección difícil de adivinar, da el alias en lugar de la dirección, y no dejes que nada privado se le acerque.

¿Pueden dos agentes esperar a la vez en la misma dirección?

Sí, y a los dos se les entregará el mensaje cuando llegue. Lo que tiene un tope es el número de esperas que ocurren a la vez en todo el servicio, 8; pasado ese número, la herramienta responde de inmediato y lo indica, y list_messages sigue funcionando.

¿Cuánto duran los mensajes?

5 días desde que llegan, leídos o no, y no hay ningún ajuste que lo extienda. Cada mensaje lleva expires_at, así que un agente nunca tiene que calcular esa fecha por su cuenta.

¿En qué se diferencia esto de llamar a la API REST desde un script?

Para un script no es diferente, y la API REST es la opción más adecuada — la guía para probar flujos de verificación cubre esa forma de trabajar, plazos y ayudantes incluidos. MCP es para el caso en que nadie ha escrito el bucle: el modelo decide abrir un buzón, y necesita que las herramientas se puedan descubrir, no que estén documentadas.

Pruébalo mientras está reciente

Una dirección lleva un clic, sin cuenta y sin tarjeta. Todo lo de esta guía funciona con ella de inmediato.

Bienvenido de nuevo

Tus buzones y tus dominios, en un solo lugar.