gmail-mcp
Gmail para tu asistente de IA — varias cuentas a la vez, en un servidor que te pertenece.
gmail-mcp conecta Gmail con Claude y con cualquier otro cliente MCP. Puede buscar y leer correo, enviar y responder a todos con el historial citado, reenviar, gestionar adjuntos e imágenes incrustadas, y administrar borradores, etiquetas e hilos — en varias cuentas de Google a la vez.
Se ejecuta como un servidor remoto en tu propio Cloudflare Worker, de modo que la misma conexión responde desde Claude Code en un portátil, claude.ai en un navegador y Claude en un teléfono. Cada conexión inicia sesión en una cuenta de Google, y el refresh token de Google permanece en tu cuenta de Cloudflare.
Hay dos motivos que traen a la gente hasta aquí. Los conectores de Gmail integrados en Claude y en Google leen el correo y escriben borradores, pero no pueden enviar, y mantienen una cuenta de Google por cuenta de asistente. Los servidores que sí pueden enviar suelen ser procesos locales — perfectos en un escritorio, invisibles desde un teléfono.
Cómo se compara
gmail-mcp | ||||||
Dónde se ejecuta | Cloudflare Workers | alojado por el proveedor | tu servidor o local | local | local | local |
Accesible desde un teléfono | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
Varios buzones a la vez | ✅ vinculado por conexión | ❌ | ✅ elegido por llamada | ❌ solo alias | ❌ | ✅ elegido por llamada |
Enviar correo | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
Adjuntos · imágenes incrustadas | ✅ | sin documentar | ✅ | ✅ | ❌ | ✅ |
Responder a todos con el historial citado | ✅ | ❌ | solo borradores | sin citar | ❌ | ✅ |
Reenviar | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ |
Respeta el charset de cada parte | ✅ | — | ❌ asume UTF-8 | ❌ asume UTF-8 | ❌ | ❌ |
Rechaza la inyección de cabeceras CRLF | ✅ | — | ✅ el framework | ✅ lo elimina | ❌ ninguna | ✅ |
Configuración del buzón (filtros, respuesta de vacaciones) | ❌ fuera de alcance | ❌ | filtros | filtros | ✅ | ❌ |
Número de herramientas | 24 | 11–16 | 14 (Gmail) | 30 | 64 | 11 |
Quién custodia tu refresh token | tú | el proveedor | tú | tú | tú | tú |
google_workspace_mcp es el proyecto más completo de esta lista. Abarca todo Workspace, no solo Gmail, y añade tu firma de Gmail y extrae los adjuntos directamente desde una URL, cosas que gmail-mcp no hace. shinzo-labs/gmail-mcp llega a los respondedores de vacaciones, delegados y S/MIME a través de sus 64 herramientas; estas se encuentran bajo gmail.settings.*, un scope que gmail-mcp nunca solicita, por lo que quedan fuera de su alcance pase lo que pase con la concesión.
Dos diferencias de diseño deciden la mayor parte del resto. Enrutar las cuentas mediante un argumento de la llamada permite que una sola concesión acceda a todos los buzones conectados, mientras que vincular el buzón a la conexión hace que un argumento equivocado no alcance nada. Y al leer, los servidores locales decodifican cada parte como UTF-8: el correo en ISO-2022-JP y Shift_JIS llega distorsionado, y los mensajes largos que Gmail guarda como blobs adjuntos vuelven con el cuerpo vacío.
Related MCP server: littlebird-mail
Despliégalo
Unos diez minutos. Necesitas una cuenta de Cloudflare, bun y una cuenta de Google. Un dominio en la cuenta de Cloudflare es opcional — sin él, el Worker responde en workers.dev.
1 · Crea un cliente OAuth de Google
PROJECT="gmail-mcp-$(openssl rand -hex 3)"
gcloud auth login
gcloud projects create "$PROJECT" --name="gmail-mcp"
gcloud config set project "$PROJECT"
gcloud services enable gmail.googleapis.comGoogle no expone ninguna API para los dos pasos siguientes, por lo que se realizan en la Cloud console:
Pantalla de consentimiento de OAuth → Externa, y luego, en Audiencia, pulsa Publicar aplicación. Si se deja en Pruebas, Google caduca cada token de actualización a los 7 días y cada conexión muere con su token. Publicada, la aplicación muestra una advertencia de aplicación no verificada al iniciar sesión y admite hasta 100 cuentas.
Credenciales → Crear credenciales → ID de cliente de OAuth → Aplicación web, con
https://<your-host>/callbackcomo URI de redirección autorizada. Guarda el ID de cliente y el secreto.
<your-host> es el dominio que apuntas al Worker, o el nombre de host workers.dev que recibe en caso contrario. Desplegar primero y volver después para rellenar esto funciona: la guía que el Worker sirve en / muestra el valor exacto.
2 · Despliega el Worker
El botón copia el repositorio en tu cuenta de GitHub, crea el espacio de nombres KV y el Durable Object, y pide los cuatro secretos. Despliega en workers.dev; un dominio personalizado se adjunta después en Configuración → Dominios y rutas.
En su lugar, desde una terminal:
git clone https://github.com/mkpoli/gmail-mcp && cd gmail-mcp
bun install
bun run setupbun run setup pregunta en qué dominio responder, crea o reutiliza el espacio de nombres OAUTH_KV, toma el ID de cliente y el secreto, genera una clave de cookie y despliega. Esas dos primeras respuestas acaban en wrangler.local.jsonc, que git ignora: wrangler.jsonc no nombra el espacio de nombres de ninguna cuenta ni el dominio de nadie, así que un clon despliega en cualquier sitio. Volver a ejecutar setup para rotar un único secreto es seguro.
3 · Conecta un cliente
Deja vacíos los campos de ID de cliente y secreto: los clientes MCP se registran solos.
claude mcp add --transport http gmail-personal https://<your-host>/mcp
claude mcp add --transport http gmail-work https://<your-host>/mcp/workEjecuta /mcp en Claude Code para iniciar sesión en cada conexión con su cuenta de Google. En claude.ai es Configuración → Conectores → Añadir conector personalizado con la misma URL. Cualquier etiqueta de un solo segmento funciona después de /mcp/, que es como un despliegue sirve varias bandejas de entrada a clientes que rechazan que dos servidores compartan una URL.
Tu despliegue sirve esta guía en https://<your-host>/.
Qué puede hacer
whoami
search_messages
get_message
get_thread
get_attachment
send_message
reply_all
forward_message
create_draft
update_draft
send_draft
delete_draft
list_drafts
stage_attachment_begin
stage_attachment_append
stage_attachment_finish
list_labels
create_label
update_label
delete_label
modify_labels
modify_thread_labels
batch_modify_messages
trash_message · untrash_message
trash_thread · untrash_thread
Los mensajes salen como los envía un cliente de correo: texto plano con una alternativa HTML, archivos adjuntos e imágenes en línea referenciadas por cid:, anidados como multipart/mixed › multipart/related › multipart/alternative. Los asuntos y los nombres para mostrar usan RFC 2047, los nombres de archivo usan RFC 2231, así que el japonés, el chino y los emoji sobreviven al viaje.
reply_all lee el Reply-To, From, To y Cc del original, descarta tu propia dirección y cualquier dirección desde la que envíes correo, responde desde la que el remitente escribió, arrastra la cadena de References y cita el original en las partes que envíes. forward_message reproduce el sobre reenviado y puede volver a adjuntar los archivos del original.
create_draft con replyToMessageId escribe la respuesta como borrador para editar antes de enviar: se une al hilo del original, arrastra In-Reply-To y References, deriva los destinatarios de responder a todos y el asunto Re:, y cita el original. update_draft cambia solo los campos que se le dan; los destinatarios, el texto, los archivos añadidos a mano en cualquier cliente y el hilo al que responde el borrador se leen y se conservan. Un archivo cuyo base64 no quepa en los argumentos de la herramienta se prepara en su lugar: stage_attachment_begin devuelve una URL de subida que acepta los bytes crudos en un solo curl -T, stage_attachment_append acepta base64 en fragmentos, y todo campo attachments acepta el stagingId resultante.
La lectura está limitada a propósito: los cuerpos de mensajes e hilos tienen presupuestos de caracteres, una respuesta completa tiene un techo de bytes, y un adjunto se devuelve en línea solo mientras sea lo bastante pequeño para leerlo. Un hilo largo de lista de correo, o un archivo grande, vuelve recortado con una nota que lo indica en lugar de llenar el contexto del asistente.
Cómo funciona
Dos flujos OAuth se encuentran en un solo Worker. El cliente MCP se autentica ante el Worker; el Worker se autentica ante Google en tu nombre. Ninguno de los dos lados guarda las credenciales del otro.
sequenceDiagram
autonumber
participant C as MCP client<br/>(Claude Code · claude.ai)
participant W as Worker<br/>(OAuthProvider + McpAgent)
participant G as Google<br/>(OAuth + Gmail API)
C->>W: POST /register (dynamic client registration)
C->>W: GET /authorize (PKCE challenge)
W->>C: approval dialog
C->>G: consent screen — pick the account
G->>W: GET /callback?code=…
W->>W: allowlist check on the verified email
W->>G: exchange code → access + refresh token
W->>C: MCP access token (Google tokens sealed inside the grant)
C->>W: POST /mcp — tools/call
W->>G: Gmail REST (token refreshed as needed)
G->>W: message / thread / label data
W->>C: tool resultCapa | Archivo | Qué hace |
🔐 OAuth del lado MCP | Registro dinámico de clientes, PKCE, concesiones en KV con los tokens de Google sellados dentro | |
🔗 OAuth del lado de Google |
| Código de autorización con acceso sin conexión, estado de un solo uso vinculado a la sesión del navegador, CSRF de doble envío, lista de permitidos sobre el correo verificado |
🤖 Agente |
| Un Durable Object por sesión MCP, vinculado a la cuenta que lo abrió; renovación de tokens de un solo vuelo, fan-out limitado |
✉️ Correo |
| Construcción RFC 822, recorrido del árbol MIME, decodificación de juegos de caracteres, composición de respuestas y reenvíos |
Construido con
TypeScript en Cloudflare Workers — los Durable Objects guardan una sesión MCP cada uno, KV guarda las concesiones OAuth
Hono — enrutado para los endpoints OAuth, la devolución de llamada de Google y la página de configuración en
/@cloudflare/workers-oauth-provider— el servidor OAuth 2.1 contra el que se registran los clientes MCPagents—McpAgent, el transporte MCP sobre Durable Objects@modelcontextprotocol/sdkcon Zod — definiciones de herramientas y validación de argumentos
Gmail se llama directamente con fetch contra la API REST. El SDK oficial googleapis asume Node y carga mucho más de lo que un Worker debería incluir, así que la construcción de mensajes, el análisis MIME y la renovación de tokens viven en src/gmail.ts y src/utils.ts en su lugar.
Endpoints
Ruta | Propósito |
| Endpoint MCP |
| El mismo servidor bajo cualquier etiqueta de un solo segmento, para clientes que rechazan que dos servidores compartan una URL |
| Esta guía de configuración |
| Mecanismo OAuth |
Quién puede iniciar sesión
ALLOWED_EMAILS decide, comprobado contra la dirección que Google informa como verificada: después del consentimiento, antes de que exista ninguna concesión.
Valor | Quién entra |
(vacío) | nadie |
| esas cuentas |
| cualquiera en ese dominio |
| cualquier cuenta de Google verificada |
Cada concesión alcanza solo la bandeja de entrada que la autenticó, así que ampliar esta lista nunca amplía el acceso a bandejas ya conectadas. Poner * permite que desconocidos usen tu despliegue, y la cuota de tu cliente de Google, para su propio correo.
Límites
Dos techos evitan que un despliegue compartido se agote, ambos definidos en wrangler.jsonc:
Ajuste | Dónde | Por defecto | Qué limita |
|
|
| Aproximadamente cuántas cuentas de Google distintas pueden completar el inicio de sesión. Las cuentas ya conectadas siguen funcionando cuando se alcanza el límite; las nuevas son rechazadas. Los inicios de sesión que llegan juntos leen el recuento antes de que se registre ninguno, así que el total puede quedarse un poco por encima de este número. Google limita las aplicaciones no verificadas a 100 usuarios, así que deja margen por debajo. |
|
|
| Llamadas a Gmail que una cuenta puede hacer en esa ventana, en todas sus sesiones. Cloudflare mantiene este recuento por ubicación, así que una cuenta que se conecta desde dos regiones recibe aproximadamente esa cantidad en cada una. Una lectura amplia gasta varias: |
|
|
| Registros de cliente que una dirección puede hacer en esa ventana. Un cliente se registra una vez y conserva el id que se le da, así que el uso ordinario nunca se acerca a esto; el techo está ahí porque el registro no necesita credenciales y cada uno escribe en KV. |
En el plan Free de Workers se aplica un límite adicional: 50 solicitudes salientes por invocación. Una lectura amplia gasta una por mensaje, así que search_messages y list_drafts requieren maxResults de 45 o menos allí; por encima, el excedente vuelve como errores por mensaje en lugar de resultados. El plan de pago permite 1000.
Sube cualquiera de los dos y vuelve a desplegar. El limitador de tasa de Cloudflare lee su tope del binding en tiempo de compilación, así que el simple.limit de cada uno es el único lugar donde se cambia. Un despliegue de un solo usuario puede dejar ambos intactos: el uso normal de un asistente queda muy por debajo.
Seguridad
El autoalojamiento mueve la cuestión de la confianza en lugar de eliminarla, así que aquí está dónde queda todo.
Tus tokens siguen siendo tuyos. Los tokens de refresco se cifran dentro de su concesión OAuth en tu namespace de KV. El Durable Object de una sesión guarda el token de acceso de una hora de vida, y el framework del agente MCP mantiene una copia de la concesión allí mientras viva el objeto, token de refresco incluido. Ambos almacenes son tu propia cuenta de Cloudflare, cifrados en reposo. El correo nunca se guarda: pasa a través.
Una sesión, una bandeja de entrada. La sesión MCP está vinculada a la cuenta que la abrió, así que una concesión para una bandeja de entrada no puede actuar sobre otra mediante un id de sesión prestado.
Minimalismo de ámbitos.
gmail.modifycubre lectura, envío, etiquetas y papelera. Excluye el borrado permanente y todogmail.settings.*, manteniendo las reglas de reenvío automático y la exfiltración por filtros — los backdoors clásicos de la bandeja de entrada — fuera de lo que cualquier concesión robada podría hacer. Junto a él se solicitan dos ámbitos de solo lectura,userinfo.emailyuserinfo.profile: son cómo la lista de permitidos y el enlace de sesión saben qué cuenta inició sesión, y no llegan al correo.Las cabeceras no se pueden colar. Cada valor de cabecera saliente se rechaza si contiene CR, LF o NUL, así que ningún argumento puede salirse de su propio campo para añadir uno — un
Bccdentro de una línea de asunto, por ejemplo. Los tipos de medio se validan, y el historial citado se escapa en HTML. Lo que esto no hace es vigilar los argumentos en sí:bcces un parámetro real, así que un modelo que actúe sobre una instrucción oculta en el cuerpo de un mensaje podría rellenarlo, y el aviso de aprobación de tu cliente sigue siendo el control sobre eso.El acceso se puede retirar. Reducir
ALLOWED_EMAILSdetiene nuevos inicios de sesión. El acceso de una sola cuenta se revoca en myaccount.google.com/connections. Rotar el secreto de cliente de Google invalida todas las concesiones a la vez.
El Worker descifra el correo en memoria mientras sirve una solicitud, como debe hacer cualquier relay alojado. Si eso es inaceptable para una bandeja de entrada concreta, ejecuta un servidor MCP local para esa.
Cómo se probó
253 pruebas unitarias cubren la construcción de mensajes (anidamiento MIME, plegado RFC 2047, nombres de archivo RFC 2231, rechazo de CR/LF, ajuste de base64), extracción del cuerpo en distintos juegos de caracteres, composición de respuestas y reenvíos, los flujos de token de Google, la lista de permitidos de inicio de sesión, los controles CSRF y de enlace de estado que protegen el lado del navegador del inicio de sesión, y las herramientas en sí contra un Gmail de sustitución — propiedad de sesión, composición de destinatarios, selección de adjuntos, y qué devuelve una lectura parcialmente fallida.
Más allá de eso, cada herramienta se ha ejecutado contra cuentas de Gmail reales, con una cuenta separada comprobando lo que llegaba:
Área | Resultado |
Codificación | Asuntos en japonés plegados entre palabras codificadas; emojis, secuencias ZWJ, árabe RTL, marcas combinadas y CJK raro de ida y vuelta sin cambios |
Adjuntos | Un CSV llamado |
Hilos |
|
Dos cuentas | Ambas conectadas a un despliegue a la vez; un id de mensaje de una devolvió |
Organización | Una etiqueta CJK anidada creada, renombrada, aplicada por lotes y eliminada; la papelera de hilos y mensajes se invirtió en ambos casos |
Escala | Una bandeja de entrada de 15 000 mensajes buscada con operadores de Gmail y paginación sin tocar un límite de tasa |
Desarrollo
bun run dev # wrangler dev on :8788
bun run check # biome + tsc
bun test # 253 unit tests
bun run assets # regenerate the light and dark diagrams
bun run deployPreguntas y errores
Abre un issue.
Licencia
Copyright © 2026 mkpoli. Publicado bajo la Licencia MIT.
src/workers-oauth-utils.ts se deriva de la demo remote-mcp-github-oauth en cloudflare/ai, Copyright © 2025 Cloudflare, Inc., usado bajo la Licencia MIT. Ver THIRD-PARTY.md.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceProduction-ready MCP server for Gmail, enabling AI agents to search, read, send, draft, and manage emails, labels, and attachments via the Google Gmail API.
- FlicenseNot gradedqualityBmaintenanceAn MCP server that provides email sending, reading, replying, and searching capabilities through a Cloudflare Worker, allowing an AI assistant to manage an independent mailbox.
- AlicenseNot gradedqualityBmaintenanceA Gmail MCP server running on Cloudflare Workers that enables reading, searching, labeling, drafting, sending, and managing Gmail messages, including fetching raw attachment bytes, with per-user OAuth authorization.231MIT
- AlicenseNot gradedqualityCmaintenanceA Gmail MCP server that lets AI assistants search, read, send, and manage email across multiple Google accounts, deployed on Cloudflare Workers.231MIT
Related MCP Connectors
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Cloudflare Workers MCP server: email-validator
Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jlindustries845-droid/gmail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server