Email Agent MCP
Conectividad de correo electrónico local para agentes de IA: leer, redactar, enviar y organizar correos de Outlook a través de MCP. Licencia Apache-2.0.
Documentación
Agent Email
English | Español | 简体中文 | Português (Brasil) | Deutsch
email-agent-mcp por UseJunior -- conectividad de correo local para agentes de IA.
Agent Email es un servidor MCP de TypeScript de código abierto que permite a Claude Code, Cursor, Gemini CLI, OpenClaw y otros runtimes compatibles con MCP leer correo, buscar hilos, redactar respuestas, etiquetar mensajes, cambiar el estado de lectura, mover mensajes y enviar correos a través de tu propia bandeja de entrada. Microsoft 365 / Outlook y Gmail son compatibles en la actualidad. Los valores predeterminados centrados en la seguridad implican que los agentes no pueden enviar correos hasta que configures explícitamente una lista de permitidos.
Inicio rápido
npx -y email-agent-mcp
El asistente de configuración interactivo te guía a través de la configuración OAuth y la selección de la bandeja de entrada.
Qué funciona hoy
- Acceso a la bandeja de entrada de Microsoft 365 / Outlook a través de MCP stdio
list_emails,read_email,search_emailsyget_threadcreate_draft,update_draft,send_draft,send_emailyreply_to_emaillabel_email,mark_readymove_to_folder- listas de permitidos de envío, eliminación deshabilitada por defecto y errores saneados
La pasada actual de preparación de lanzamiento se validó contra una bandeja de entrada real de Outlook para los flujos de lectura, borrador, envío, categorización, movimiento y estado de lectura.
Por qué existe esto
Los agentes de IA necesitan leer, responder y actuar sobre el correo, pero las API de correo son complejas. Los flujos OAuth, las consultas delta de Graph, las suscripciones push de Gmail, la conversión de HTML a markdown, la semántica de hilos -- cada proveedor tiene sus propias peculiaridades.
Agent Email envuelve esta complejidad en herramientas MCP deterministas con protecciones de seguridad:
- listas de permitidos de envío y recepción que controlan a quién pueden contactar los agentes
- eliminación deshabilitada por defecto (requiere aceptación explícita)
- saneamiento de errores que elimina claves de API, rutas de archivos y trazas de pila
- aislamiento de archivos de cuerpo con protección contra recorrido de rutas
Uso con Claude Code
Añade a ~/.claude/settings.json o a tu proyecto .claude/settings.json:
{
"mcpServers": {
"email-agent-mcp": {
"type": "stdio",
"command": "npx",
"args": ["-y", "email-agent-mcp"]
}
}
}
Uso con Cursor
// .cursor/mcp.json
{
"mcpServers": {
"email-agent-mcp": {
"command": "npx",
"args": ["-y", "email-agent-mcp"]
}
}
}
Uso con Gemini CLI
gemini extensions install https://github.com/UseJunior/email-agent-mcp
Uso con OpenClaw
Añade un bloque mcp a ~/.openclaw/openclaw.json:
{
// ... existing config ...
mcp: {
servers: {
email: {
command: "npx",
args: ["tsx", "/path/to/email-agent-mcp/packages/email-mcp/src/serve-entry.ts"],
transport: "stdio"
}
}
}
}
Nota de versión: La clave de configuración
mcprequiere OpenClaw app >= 2026.3.24. Si la CLI es más antigua que la app, puede rechazar esta clave durante la validación aunque la puerta de enlace la acepte. Actualiza la CLI connpm install openclaw@latesten tu directorio NemoClaw, o reinicia la puerta de enlace directamente conlaunchctl kickstart -k gui/501/ai.openclaw.gateway.
Vigilante de correo
El vigilante consulta tu bandeja de entrada y envía señales de activación a OpenClaw cuando llega correo nuevo:
# Set the hooks token (must match hooks.token in openclaw.json)
export OPENCLAW_HOOKS_TOKEN="your-hooks-token"
# Start the watcher (defaults to http://localhost:18789/hooks/wake)
npm run dev:watch
El vigilante requiere al menos una bandeja de entrada configurada. Ejecuta npx email-agent-mcp o npm run dev:configure primero para completar el flujo OAuth.
Prueba de humo de preparación de lanzamiento
Antes de grabar una demostración, ejecuta el script de humo en vivo contra una bandeja de entrada real y una lista de permitidos de envío segura. El script ejercita:
get_mailbox_statuslist_emails+read_emailmark_readno leído -> leído -> no leídolabel_emailen un candidato seguro de la bandeja de entradacreate_draftreply_to_emailsolo borradorsend_emailopcional
Ejemplo:
EMAIL_AGENT_MCP_HOME=/tmp/email-agent-mcp-live \
AGENT_EMAIL_SEND_ALLOWLIST=/tmp/email-agent-mcp-live/send-allowlist.json \
npm run launch:prep:smoke -- --live-write --send-to beta@usejunior.com
La selección predeterminada de candidatos seguros busca notifications@github.com en la bandeja de entrada para que puedas ensayar el flujo de grabación en un mensaje seguro públicamente en lugar de en el correo de un cliente.
Si el nombre de estado de tu bandeja de entrada no es una dirección de correo, pasa --reply-sender <email> o establece EMAIL_AGENT_MCP_REPLY_SENDER para que el script pueda encontrar un mensaje enviado por ti mismo para la comprobación de respuesta de borrador.
Referencia de herramientas
Perfiles de ámbito
Establece EMAIL_AGENT_MCP_SCOPE_PROFILE antes de configurar e iniciar el servidor para
elegir los permisos expuestos a un agente. El predeterminado es full por
compatibilidad con versiones anteriores.
| Perfil | Ámbitos delegados de Microsoft | Herramientas expuestas |
|---|---|---|
observe | Mail.Read, User.Read, offline_access | Herramientas de correo de solo lectura, menos list_inbox_rules (ver más abajo) |
full (predeterminado) | Mail.Read, Mail.ReadWrite, Mail.Send, MailboxSettings.ReadWrite, User.Read, offline_access | Todas las herramientas |
Para una implementación de solo observación, establece el perfil tanto para la configuración como para el tiempo de ejecución de modo que el consentimiento OAuth y la lista de herramientas MCP coincidan:
export EMAIL_AGENT_MCP_SCOPE_PROFILE=observe
npx email-agent-mcp configure
npx email-agent-mcp serve
Los ámbitos de observe son un subconjunto estricto deliberado de los de full. Eso es lo que
hace adoptable el perfil: un inquilino que ya ha consentido el conjunto completo
otorga observe silenciosamente, por lo que cambiar de full → observe no requiere nuevo consentimiento.
Cambiar de observe → full sí requiere un nuevo consentimiento interactivo, porque
solicita ámbitos que nunca fueron otorgados.
Por la misma razón, observe no expone list_inbox_rules. Graph restringe
/mailFolders/inbox/messageRules detrás de MailboxSettings, y Entra trata
MailboxSettings.Read como un ámbito distinto del full de
MailboxSettings.ReadWrite en lugar de deducirlo de él. Solicitarlo rompería
la propiedad del subconjunto y forzaría un consentimiento fresco en cada implementación observe -- una
solicitud de aprobación administrativa en inquilinos que restringen el consentimiento del usuario. Usa full si
necesitas visibilidad de reglas de bandeja de entrada.
Un valor de perfil no válido detiene el inicio en lugar de otorgar silenciosamente un acceso más amplio. Si las credenciales almacenadas en caché no cubren los ámbitos del perfil, el servidor falla rápidamente con un error accionable en lugar de bloquearse en un inicio de sesión interactivo.
Qué garantiza observe y qué no
observe siempre elimina las herramientas de escritura de la superficie de herramientas MCP, por lo que un agente
no puede invocarlas. Esa parte se cumple en todas partes.
Solo reduce el token OAuth en una bandeja de entrada que aún no ha consentido
los ámbitos de escritura. Entra emite un token de acceso que lleva todos los ámbitos a los que el usuario
o inquilino ya ha consentido para esa aplicación -- no solo el subconjunto
solicitado en el momento de la adquisición del token. Así que si apuntas observe a una bandeja de entrada
configurada previamente como full, el token subyacente aún lleva
Mail.ReadWrite y Mail.Send; solo se reduce la superficie de herramientas.
Para un token genuino de privilegio mínimo, otorga consentimiento a observe desde una bandeja de entrada que
nunca haya recibido los ámbitos de escritura -- un configure fresco contra un
registro de aplicación cuyos permisos delegados se detienen en Mail.Read/User.Read. Trata
la reducción de la superficie de herramientas como defensa en profundidad, no como un límite OAuth, a menos que
controles la concesión.
Herramientas
El perfil full expone 26 herramientas MCP; observe omite toda herramienta cuya acción
esté marcada como mutadora de bandeja de entrada:
| Herramienta | Descripción | Tipo |
|---|---|---|
list_emails | Lista los correos recientes con filtrado | lectura |
read_email | Lee el contenido completo del correo como markdown, o HTML sin procesar con format: "html" | lectura |
search_emails | Búsqueda de texto completo en las bandejas de entrada | lectura |
list_mailboxes | Enumera las bandejas de entrada configuradas, su estado y la predeterminada | lectura |
get_mailbox_status | Estado de conexión y advertencias | lectura |
get_thread | Contexto completo de la conversación | lectura |
list_attachments | Lista los metadatos de adjuntos de un correo | lectura |
download_attachment | Descarga un archivo adjunto como base64 | lectura |
send_email | Envía un correo nuevo (restringido por lista de permitidos) | escritura |
reply_to_email | Responde dentro del hilo (restringido por lista de permitidos en el envío) | escritura |
create_draft | Crea un borrador de correo | escritura |
update_draft | Actualiza el contenido del borrador | escritura |
send_draft | Envía un borrador guardado | escritura |
list_scheduled_sends | Lista los envíos programados pendientes retenidos por el proveedor (Microsoft 365) | lectura |
cancel_scheduled_send | Cancela un envío programado pendiente (Microsoft 365) | destructiva |
label_email | Aplica etiquetas/categorías | escritura |
flag_email | Marca/desmarca correos con bandera | escritura |
mark_read | Marca como leído/no leído | escritura |
move_to_folder | Mueve entre carpetas | escritura |
delete_email | Elimina (requiere entorno de operador + indicador de llamador) | destructiva |
list_folders | Lista recursivamente carpetas y rutas calculadas (Microsoft 365) | lectura |
create_folder | Crea una carpeta hija personalizada (Microsoft 365) | escritura |
delete_folder | Elimina una carpeta personalizada (requiere entorno de operador + indicador de llamador); las carpetas del sistema están protegidas (Microsoft 365) | destructiva |
list_inbox_rules | Lista las reglas de bandeja de entrada del lado del servidor (Microsoft 365) | lectura |
create_inbox_rule | Crea una regla de bandeja de entrada segura persistente; el reenvío, la redirección, la eliminación y el descarte a Elementos eliminados están bloqueados (Microsoft 365) | escritura |
delete_inbox_rule | Elimina una regla de bandeja de entrada del lado del servidor (requiere entorno de operador + indicador de llamador) (Microsoft 365) | destructiva |
Cada fila devuelta por list_emails, search_emails y get_thread, y la
respuesta de read_email, lleva un booleano isDraft siempre presente. isDraft: true
significa que el mensaje es un borrador no enviado: no ha sido enviado, y su receivedAt
es metadatos proporcionados por el proveedor en lugar de evidencia de entrega. El campo nunca se
omite, por lo que un agente consumidor puede distinguir "no es un borrador" de "estado de borrador no
informado" -- pero ten en cuenta que false solo afirma que el proveedor no marcó el mensaje
como borrador no enviado, no que el propietario de la bandeja de entrada lo envió (el correo recibido también es
false). Por lo demás, los borradores aparecen en los listados y resultados de búsqueda como antes.
La gestión de carpetas y reglas de bandeja de entrada requiere el consentimiento de Microsoft Graph MailboxSettings.ReadWrite. Las conexiones de bandeja de entrada de Microsoft existentes deben volver a consentir después de actualizar. Gmail usa etiquetas en lugar de carpetas jerárquicas/reglas de Exchange del lado del servidor, por lo que estas seis herramientas devuelven NOT_SUPPORTED para las bandejas de entrada de Gmail.
Formatos de cuerpo
Los cuerpos cruzan el cable como markdown por defecto en ambas direcciones. Ese predeterminado es deliberado -- el markdown es eficiente en tokens, y una lectura rutinaria debería ser barata. Ambas direcciones pueden optar por no usarlo.
Escritura -- send_email, reply_to_email, create_draft y update_draft
aceptan un format opcional:
format | Comportamiento |
|---|---|
markdown (predeterminado) | Renderizado a HTML mediante marked (GFM, breaks: true). El HTML sin procesar incrustado en el markdown se conserva. |
html | Paso directo -- tu HTML se envía tal cual. |
text | Sin renderizado; se envía como texto plano. |
html es paso directo sin saneamiento: sin saneador, sin lista de permitidos, sin reescritura de
tu marcado. El CSS en línea y las etiquetas arbitrarias sobreviven hasta el cable -- eso es lo
que hace posible el correo con estilo, y significa que eres dueño de lo que envías. La única
modificación predeterminada es el envoltorio negro forzado a continuación; con force_black: false el cuerpo pasa byte por byte.
Para markdown y html, el HTML renderizado se envuelve en un
<div style="color: #000000;"> para que el modo oscuro de Outlook no convierta el texto en
blanco sobre blanco.
Archivos de cuerpo -- send_email, create_draft y update_draft también aceptan
body_file: una ruta a un archivo .md, .html o .txt (leído relativo a
EMAIL_MCP_SAFE_DIR, por defecto el directorio de trabajo del proceso, más cualquier
raíz de AGENT_EMAIL_ALLOWED_DIRS) usado como cuerpo
en lugar de body. Un archivo de cuerpo .md puede
abrir con un bloque de frontmatter YAML:
Para update_draft, body y body_file solo se permiten en un borrador que no sea de respuesta y requieren replace_body: true; el cuerpo almacenado se reemplaza por completo. Los cuerpos de borradores de respuesta no se pueden editar de forma segura porque incluyen historial citado ensamblado por el proveedor, así que crea un borrador nuevo en su lugar. Las actualizaciones de asunto, destinatario y archivos adjuntos siguen disponibles en los borradores de respuesta.
---
to: alex@example.com
subject: Quarterly summary
format: html
force_black: false
---
<p>The body starts after the closing delimiter.</p>
Las claves reconocidas son to, cc, subject, reply_to, draft, format y force_black (draft: true convierte una llamada a send_email en un guardado de borrador). Un valor de frontmatter anula el parámetro de herramienta del mismo nombre. El frontmatter solo se analiza desde archivos .md, y la extensión del archivo nunca selecciona el formato: sin un parámetro de herramienta format explícito, incluso un archivo de cuerpo .html recibe el renderizado markdown predeterminado; pasa format: "html" para paso directo.
Lectura — read_email acepta un format opcional de markdown (predeterminado) o html:
{ "id": "AAMkAD...", "format": "html" }
format: "html" devuelve el HTML del cuerpo sin procesar del mensaje tal cual. Úsalo cuando necesites estilos que markdown no puede transportar — color, background-color, text-decoration, <u> — por ejemplo, para cambiar una frase de un cuerpo con formato y dejar el resto intacto. A través de la ruta markdown, ese estilo se destruye silenciosamente en el camino de salida.
Dos campos vuelven con él:
bodyFormat— siempre presente:markdown,htmlotext. Obtienestextcuando pedistehtmlpero el mensaje no tiene parte HTML, en cuyo caso se devuelve el cuerpo de texto plano. Comprueba esto antes de escribir un cuerpo de vuelta.bodyTruncated— presente ytruesolo si el cuerpo superó el presupuesto de respuesta de 256 KB paraformat: "html"(la ruta markdown no tiene límite, como antes). No escribas un cuerpo truncado de vuelta a un borrador.
El HTML sin procesar cuesta muchos más tokens que su reducción markdown, así que deja el valor predeterminado solo a menos que necesites el estilo. strip_quoted_history y strip_signatures son transformaciones de texto con forma markdown y no se aplican cuando format es html — el HTML sin procesar se devuelve sin tocar.
Escribirlo de vuelta. Pasa format: "html" y force_black: false:
{ "draft_id": "AAMkAD...", "body": "<edited html>", "format": "html", "force_black": false }
force_black tiene como valor predeterminado true, que envuelve cualquier HTML que envíes en un <div style="color: #000000;">. Eso es correcto para HTML que hayas creado tú mismo, pero en un cuerpo que acabas de leer de vuelta, anida un envoltorio más en cada ciclo: después de quince revisiones tienes quince divs anidados. Con force_black: false los bytes sobreviven al viaje de ida y vuelta sin cambios.
Envío programado
send_email y send_draft aceptan scheduled_send_at, una marca de tiempo futura ISO 8601 con una zona horaria explícita. Microsoft 365 retiene el mensaje en el servidor, por lo que la entrega sobrevive a la salida de este proceso. Usa el messageId devuelto con cancel_scheduled_send mientras esté pendiente, o inspecciona los elementos pendientes con list_scheduled_sends.
Microsoft Graph cambia el ID del mensaje cuando el borrador retenido se mueve a Elementos enviados, por lo que el ID devuelto es un identificador de gestión previo a la entrega, no un ID de mensaje enviado permanente. La API pública de Gmail no expone el envío programado; todas las superficies de envío programado devuelven NOT_SUPPORTED para Gmail mientras que los envíos inmediatos permanecen sin cambios.
Archivos adjuntos salientes
send_email, reply_to_email, create_draft y update_draft aceptan un array attachments opcional. Cada entrada toma un archivo path en sandbox (leído relativo a EMAIL_MCP_SAFE_DIR, por defecto el directorio de trabajo del proceso, más cualquier raíz AGENT_EMAIL_ALLOWED_DIRS — ver más abajo) o base64 en línea, más anulaciones opcionales de filename / mimeType:
{
"to": "alice@example.com",
"subject": "Signed agreement",
"body": "Attached as requested.",
"attachments": [
{ "path": "./out/agreement.pdf" },
{ "base64": "iVBORw0KGgo...", "filename": "screenshot.png" }
]
}
Los archivos tienen un límite de 25MB cada uno; Microsoft Graph además limita los envíos en línea a ~3MB en total (los archivos más grandes necesitan una sesión de carga — aún no soportada). Para update_draft, omitir attachments conserva los archivos existentes del borrador; pasar un array (incluso vacío) los reemplaza.
Adjuntar archivos desde fuera del directorio de trabajo — establece AGENT_EMAIL_ALLOWED_DIRS a una lista separada por delimitadores de directorios absolutos (: en macOS/Linux, ; en Windows; un ~ inicial se expande) que attachments[].path y body_file también pueden leer:
{
"mcpServers": {
"email-agent-mcp": {
"command": "npx",
"args": ["-y", "@usejunior/email-agent-mcp"],
"env": { "AGENT_EMAIL_ALLOWED_DIRS": "~/Downloads:/Volumes/Shared/Contracts" }
}
}
}
Una ruta relativa se resuelve solo contra EMAIL_MCP_SAFE_DIR — los directorios permitidos se alcanzan por ruta absoluta, por lo que un contract.pdf desnudo nunca puede recoger silenciosamente un archivo diferente de otra raíz. Cada raíz se canoniza con realpath antes de la comprobación de contención: una raíz en la lista de permitidos que es en sí misma un symlink se resuelve a su ubicación real, una raíz que no se puede canonizar no autoriza nada, y un symlink que escapa de todas las raíces sigue siendo rechazado. Sin establecer (el valor predeterminado) mantiene el directorio de trabajo como única raíz — por eso un agente que no puede alcanzar un archivo debería pedirte que añadas su directorio a la lista de permitidos en lugar de copiar documentos confidenciales en un árbol de trabajo git.
Añadir un directorio a la lista de permitidos confía en cualquiera que pueda escribir en él. La validación y la apertura son operaciones separadas en una ruta, por lo que un principal que pueda reemplazar un directorio dentro de una raíz permitida entre las dos aún puede redirigir la lectura; solo añade a la lista de permitidos raíces cuyos ancestros no sean escribibles por usuarios no confiables. El archivo final se abre con O_NOFOLLOW, por lo que el archivo en sí no puede ser intercambiado por un symlink después de la validación.
Soporte de proveedores
| Proveedor | Estado | Paquete |
|---|---|---|
| Microsoft 365 (Graph API) | Totalmente soportado | @usejunior/provider-microsoft |
| Gmail | Soportado mediante OAuth CLI interactivo (cliente predeterminado o el tuyo propio) o configuración manual de token de actualización | @usejunior/provider-gmail |
Usa email-agent-mcp configure --provider gmail para ejecutar el flujo OAuth del navegador local, o añade un archivo de token de buzón manual bajo ~/.email-agent-mcp/tokens/. Consulta Configuración de Gmail más abajo y packages/provider-gmail/README.md.
Configuración de Gmail
Gmail tiene dos rutas OAuth soportadas. Ambas terminan con el mismo resultado: un token de actualización en tu máquina, y llamadas a la API de Gmail yendo directamente desde tu máquina a Google.
| Ruta | Comando | ¿Se necesita proyecto de Google Cloud? |
|---|---|---|
| Cliente OAuth predeterminado | email-agent-mcp configure --provider gmail | No |
| Trae tu propia clave (BYOK) | mismo comando más --client-id / --client-secret | Sí, el tuyo |
Recomendado por ahora: BYOK. Nuestro cliente OAuth predeterminado sigue en el estado de publicación "Testing" de Google mientras la verificación está en curso, lo que lo limita a 100 usuarios de prueba registrados y muestra el intersticial "Google no ha verificado esta aplicación" durante el consentimiento. La verificación para el alcance restringido de Gmail requiere una evaluación de seguridad CASA y tarda varias semanas; el progreso se rastrea en issue #112. BYOK evita el límite compartido de 100 usuarios y pone el estado de publicación de la aplicación bajo tu control; tu propia aplicación aún tiene las restricciones de Testing de Google hasta que la publiques.
Otras razones para elegir BYOK: cuota de API dedicada, tu propia política de privacidad y estado de verificación, y ninguna dependencia del broker alojado en https://oauth.usejunior.com.
Alcance solicitado
Email Agent MCP solicita exactamente un alcance de Gmail:
https://www.googleapis.com/auth/gmail.modify
Este es el alcance de Gmail más restringido que cubre el comportamiento de lectura, redacción, envío, etiquetado y eliminación suave a la papelera de Email Agent MCP. No permite la eliminación inmediata y permanente. Es el único alcance que añades a tu propia pantalla de consentimiento OAuth.
BYOK: crea tu propio cliente OAuth de Google
- Crea un proyecto en la Consola de Google Cloud, o selecciona uno existente.
- Habilita la API de Gmail en APIs y servicios → Biblioteca → API de Gmail → Habilitar.
- Configura la pantalla de consentimiento OAuth en APIs y servicios → Pantalla de consentimiento OAuth:
- Tipo de usuario Externo para una cuenta personal
@gmail.com, o Interno si estás en Google Workspace y solo tu propia organización necesita acceso. - Añade el alcance
https://www.googleapis.com/auth/gmail.modify. - Mientras la aplicación esté en Testing, añade tu propia dirección de Gmail en Usuarios de prueba, o se rechazará el consentimiento.
- Tipo de usuario Externo para una cuenta personal
- Crea el cliente OAuth en APIs y servicios → Credenciales → Crear credenciales → ID de cliente OAuth. Elige el tipo de aplicación Aplicación de escritorio. El escritorio es obligatorio:
configureinicia un listener desechable en un puerto loopback efímero (http://127.0.0.1:<port>/oauth2callback), y solo los clientes de escritorio permiten que Google acepte un puerto loopback arbitrario sin pre-registrar la URI de redirección exacta. Un cliente de aplicación web fallará conredirect_uri_mismatch. - Copia el ID de cliente y el secreto de cliente.
BYOK: entrega las credenciales a email-agent-mcp
Pasa ambas mitades como banderas:
npx email-agent-mcp configure \
--provider gmail \
--mailbox personal \
--client-id YOUR_GOOGLE_CLIENT_ID \
--client-secret YOUR_GOOGLE_CLIENT_SECRET
O establece las dos variables de entorno con espacio de nombres y omite las banderas:
export AGENT_EMAIL_GMAIL_CLIENT_ID=YOUR_GOOGLE_CLIENT_ID
export AGENT_EMAIL_GMAIL_CLIENT_SECRET=YOUR_GOOGLE_CLIENT_SECRET
npx email-agent-mcp configure --provider gmail --mailbox personal
Ambas mitades son obligatorias. Proporcionar solo una sale con un error en lugar de volver silenciosamente al cliente predeterminado. No proporcionar ninguna selecciona el cliente OAuth predeterminado.
Tu navegador abre la pantalla de consentimiento de Google, el CLI captura la devolución de llamada en loopback, intercambia el código con PKCE, y escribe el buzón en ~/.email-agent-mcp/tokens/<safe-key>.json con "source": "byok" junto a tu clientId, clientSecret y el refreshToken resultante. Las actualizaciones de token van entonces directamente al endpoint de token de Google; no hay ningún broker involucrado.
Volver a ejecutar configure para un buzón que ya está guardado reutiliza las credenciales guardadas, por lo que solo pasas las banderas una vez. Pasar --client-id y --client-secret para un buzón configurado previamente contra el cliente predeterminado lo migra a BYOK.
BYOK: evita que la concesión expire después de 7 días
Google expira los tokens de actualización después de 7 días mientras tu aplicación OAuth esté en estado de publicación Testing, lo que aparece como un aviso de re-autenticación aproximadamente una vez por semana. email-agent-mcp status advierte cuando un buzón se acerca a esa ventana. Publicar tu aplicación (Pantalla de consentimiento OAuth → Publicar aplicación) elimina la expiración de 7 días. Dado que eres dueño de la aplicación y eres su único usuario, el límite de prueba de 100 usuarios no se aplica a ti de ninguna manera.
Desconectar Gmail y revocar el acceso
Desconectar tiene dos partes independientes:
- Detén cualquier proceso
email-agent-mcpen ejecución. En Finder, abre~/.email-agent-mcp/tokens/, identifica el único archivo JSON para el buzón que deseas desconectar, y mueve ese archivo exacto a la Papelera. No abras, pegues ni compartas su contenido, y no elimines todo el directorio~/.email-agent-mcpsi hay otros buzones configurados. Si establecisteEMAIL_AGENT_MCP_HOME, usa la carpetatokens/de ese directorio en su lugar. - Abre https://myaccount.google.com/connections, selecciona Email Agent MCP (o el nombre de tu aplicación BYOK), y elimina su acceso.
Eliminar el archivo local evita que esta instalación use la credencial guardada. Eliminar la conexión de la cuenta de Google revoca la concesión en Google. Ejecuta email-agent-mcp status después para confirmar que el buzón ya no está configurado.
Valores predeterminados de seguridad
Email Agent MCP viene con valores predeterminados restrictivos que puedes flexibilizar según sea necesario:
- Lista de permitidos de envío: vacía por defecto — los agentes no pueden enviar correo hasta que añadas destinatarios
- Lista de permitidos de recepción: acepta todo por defecto — controla qué remitentes activan el watcher
- Eliminación deshabilitada: los agentes no pueden eliminar correo por defecto. Dos compuertas deben satisfacerse ambas:
- el operador establece
AGENT_EMAIL_DELETE_ENABLED=trueen el entorno del proceso email-agent-mcp (yAGENT_EMAIL_HARD_DELETE_ENABLED=truepara eliminación permanente). Se requiere reinicio después del cambio. - el llamador pasa
user_explicitly_requested_deletion: trueen la llamada a la herramienta.
- el operador establece
- Saneamiento de errores: las claves de API, rutas de archivos y trazas de pila se redactan de las respuestas de error
- Sandbox de archivos de cuerpo: sin recorrido
../, sin symlinks, detección binaria
Paquetes
| Paquete | Descripción |
|---|---|
@usejunior/email-core | Acciones centrales de correo, motor de contenido, seguridad e interfaces de proveedor |
@usejunior/email-mcp | Adaptador del servidor MCP, CLI y watcher |
@usejunior/provider-microsoft | Proveedor de correo de Microsoft Graph API |
@usejunior/provider-gmail | Proveedor de correo de Gmail API |
email-agent-mcp | Wrapper de distribución (npx email-agent-mcp) |
@usejunior/email-agent-mcp | Wrapper de compatibilidad, publicado en sincronía; use email-agent-mcp para instalaciones nuevas |
Señales de Calidad y Confianza
- CI se ejecuta en cada pull request y push a main (lint, typecheck, pruebas en Node 20 y 22)
- Escaneo de seguridad con CodeQL y Semgrep
- Cobertura publicada en Codecov
- Cumplimiento de trazabilidad OpenSpec mediante
npm run check:spec-coverage - Más de 300 pruebas en todo el conjunto
- Mantenedor: Steven Obiajulu
Arquitectura
email-agent-mcp/
├── packages/
│ ├── email-core Core actions, content engine, security
│ ├── email-mcp MCP server adapter, CLI, watcher
│ ├── provider-microsoft Microsoft Graph provider
│ ├── provider-gmail Gmail API provider
│ └── email-agent-mcp Distribution wrapper (npx entry point)
├── openspec/ Spec-driven development
└── scripts/ CI and validation scripts
Publicación
Publicación basada en tags mediante GitHub Actions con npm OIDC trusted publishing. Los 6 paquetes se publican en orden de dependencias con --provenance, luego server.json se publica en el registro oficial de MCP con mcp-publisher.
Preguntas frecuentes
¿Funciona con Claude Code?
Sí. Ejecute npx email-agent-mcp para iniciar el servidor MCP y luego configúrelo en la configuración de Claude Code.
¿Pueden los agentes enviar correos sin mi permiso?
No. La lista de permitidos para envío está vacía por defecto. Los agentes no pueden enviar ningún correo hasta que usted configure explícitamente los destinatarios permitidos.
¿Almacena mis credenciales de correo?
Los tokens OAuth son gestionados por MSAL (Microsoft) y se almacenan en el llavero del sistema operativo o en archivos de configuración locales bajo ~/.email-agent-mcp/. Agent Email nunca almacena contraseñas en texto plano.
¿Puedo conectar múltiples buzones?
Sí. Puede configurar Microsoft 365 y Gmail simultáneamente. Las acciones de lectura usan su buzón principal por defecto; las acciones de escritura requieren especificar un buzón cuando hay varios configurados.
El CLI de OpenClaw rechaza mi configuración con "Unrecognized key: mcp"
El CLI de OpenClaw y la app de macOS pueden tener versiones diferentes. La app (que ejecuta la puerta de enlace) puede admitir claves de configuración que el CLI aún no reconoce. Actualice el CLI: cd ~/Projects/NemoClaw && npm install openclaw@latest. Alternativamente, reinicie la puerta de enlace directamente: launchctl kickstart -k gui/501/ai.openclaw.gateway.
El watcher se inicia pero no encuentra ningún buzón
Las credenciales de los buzones se guardan en ~/.email-agent-mcp/tokens/. Si este directorio está vacío, ejecute npx email-agent-mcp o npm run dev:configure para autenticarse mediante OAuth. El watcher cerrará sin buzones que consultar hasta que se configure al menos uno.
OpenClaw dice "Demo mode -- run email-agent-mcp configure to connect"
El servidor MCP está en ejecución pero no tiene credenciales reales de buzón. Ejecute npx email-agent-mcp para completar la configuración interactiva de OAuth y luego reinicie la puerta de enlace de OpenClaw para que el servidor MCP se reconecte con tokens válidos.
El token expiró después de una semana aunque acabo de autenticarme
Los tokens de actualización de Microsoft suelen durar 90 días, pero su inquilino de Azure AD puede imponer una vigencia más corta. El código usa MSAL con persistencia en el llavero del sistema (@azure/identity-cache-persistence), que gestiona la renovación silenciosa de tokens automáticamente. Si MSAL reporta interaction_required o invalid_grant, vuelva a ejecutar npx email-agent-mcp para reautenticarse. Causas comunes: políticas de acceso condicional, requisitos de reverificación MFA o políticas de duración de tokens configuradas por el administrador.
El bot de Telegram de OpenClaw recibe mensajes pero no responde
Verifique que el canal de Telegram esté en buen estado con openclaw status. Si el canal muestra OK pero no llegan respuestas, compruebe que: (1) su ID de usuario de Telegram esté en channels.telegram.allowFrom dentro de openclaw.json, (2) exista una vinculación que coincida con channel: "telegram" y (3) la puerta de enlace se haya reiniciado después de los cambios de configuración. Para bots de un solo propietario, use dmPolicy: "allowlist" con IDs explícitos de allowFrom en lugar de depender de aprobaciones de emparejamiento.
Desarrollo
npm ci
npm run build
npm run lint --workspaces --if-present
npm run test:run
npm run check:spec-coverage
Ver también
- Safe DOCX Suite -- edición quirúrgica de documentos de Word con agentes de codificación
- Open Agreements -- complete plantillas legales estándar con agentes de codificación
Privacidad
Agent Email se ejecuta íntegramente en su máquina local. Las credenciales de correo se almacenan en el llavero del sistema (MSAL) y en archivos de configuración locales. Agent Email no envía ningún contenido de correo a servidores externos.