Skip to main content
Glama
Bloody-Regina

gmail-mcp

Gmail para tu asistente de IA: varias cuentas a la vez, en un servidor que tú controlas.

MIT Cloudflare Workers MCP OAuth 2.1 27 tools tests

日本語版 · 简体中文

gmail-mcp conecta Gmail con Claude y con cualquier otro cliente MCP. Puede buscar y leer correos, 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, desde claude.ai en el navegador y desde Claude en el móvil. Cada conexión inicia sesión en una cuenta de Google, y el token de actualización de Google permanece en tu cuenta de Cloudflare.

Hay dos cosas 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 usan una cuenta de Google por cuenta de asistente. Los servidores que sí pueden enviar suelen ser procesos locales: bien en el escritorio, invisibles desde el móvil.


Cómo se compara

gmail-mcp

Claude · Google integrados

taylorwilsdon/google_workspace_mcp

ArtyMcLabin/Gmail-MCP-Server

shinzo-labs/gmail-mcp

aaronsb/google-workspace-mcp

Dónde se ejecuta

Cloudflare Workers

alojado por el proveedor

tu servidor o tu propio servidor

servidor local

local

local

Accesible desde el móvil

Varias cuentas a la vez

✅ vinculada a la conexión

✅ cuentaXpedida por llamada

❌ solo alias

✅ elegida por llamada

Enviar correo

Adjuntos · imágenes cid:

sin documentar

Responder a todos con historial citado.

solo borradores

sin citar

Reenviar

Respeta la codificación de cada parte

❌ asume UTF-8

❌ asume UTF-8

Rechaza inyección CRLF en las cabeceras.

✅ framework

✅ las elimina

ninguna

Ajustes de la bandeja (filtros, vacaciones)

❌ fuera del alcance

filtros

filtros

Número de herramientas

24

11–16

16 (Gmail)

30

64

11

Quién guarda tu token de actualización

proveedor

google\_workspace\_mcp es el proyecto más completo de esta lista. Cubre todo Workspace y no solo Gmail, y además añade tu firma de Gmail y descarga los adjuntos directamente desde una URL, dos cosas que gmail-mcp no hace. shinzo-labs/gmail-mcp llega a los avisos de vacaciones, a los delegados y a S/MIME con sus 64 herramientas; todas viven bajo gmail.settings.*, un ámbito que gmail-mcp no solicita nunca, por lo que quedan fuera de su alcance pase lo que pase con un permiso.

Dos diferencias de diseño deciden el resto. Enrutar las cuentas mediante un argumento de llamada permite que un permiso toque todas las bandejas conectadas, mientras que vincular la bandeja debidaa la conexión hace que un argumento equivocado no llegue a nada. Y al leer, los servidores locales decodifican cada parte como UTF-8: los correos en ISO-2022-JP y con Shift_JIS llegan ilegibles, y los mensajes largos que Gmail guarda como adjuntos vuelven con el cuerpo vacío.


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.com

Google no expone ninguna API para los dos pasos siguientes, así que se hacen desde la Cloud console.

  • Pantalla de consentimiento de OAuthExterno, y luego, en Audiencia, pulse Publicar app. Déjalo en Pruebas. Google caduca cada token de actualización a los 7 días y cada conexión muere con su token. Publicada, la app muestra una advertencia de app no verificada al iniciar sesión y admite hasta 100 cuentas.

  • Credenciales → Crear credenciales → ID de cliente de OAuthAplicación web, con https://<tu-host>/callback como URI de redireccionamiento autorizada. Conserva el ID y el secreto de cliente.

<tu-host> es el dominio al que apuntas al Worker, o el host de workers.dev que obtiene en su lugar. Desplegar primero y volver para rellenar esto funciona: la guía que el Worker sirve en / muestra el valor exacto.

2 · Desplegar el Worker

Desplegar en Cloudflare

El botón copia el repositorio en tu cuenta de GitHub, crea el espacio de nombres KV y el Objeto Durable, y pide los cuatro secretos. Se despliega en workers.dev; se adjunta un dominio personalizado después en Ajustes → Dominios y rutas.

Desde una terminal en su lugar:

git clone https://github.com/mkpoli/gmail-mcp && cd gmail-mcp
bun install
bun run setup

bun run setup pregunta en qué dominio responder, crea o reutiliza el espacio de nombres de OAUTH_KV, toma el ID y el secreto del cliente, genera una clave de cookie y despliega. Esas dos primeras respuestas caen en wrangler.local.jsonc, que git ignora — wrangler.jsonc no nombra ninguna cuenta ni dominio de nadie, así que un clon se despliega en cualquier parte. Re-ejecutar el setup para rotar un secreto es seguro.

3 · Conectar un cliente

Deja los campos de ID y secreto de cliente vacíos: los clientes MCP se registran ellos mismos.

claude mcp add --transport http gmail-personal https://<your-host>/mcp
claude mcp add --transport http gmail-work     https://<your-host>/mcp/work

Ejecuta /mcp en Claude Code para iniciar cada conexión con su cuenta de Google. En claude.ai es Ajustes → Connectors personalizados → Añadir conector personalizado con la misma URL. Cualquier etiqueta de un solo segmento funciona después de /mcp/, por lo cual una implementación atiende a varios clientes que rechazan a dos servidores compartiendo una URL.

Tu implementación sirve a esta guía en https://<tu-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 un cliente de correo los envía: texto sin formato con alternativa HTML, archivos adjuntos e imágenes en línea referenciadas por cid:, anidados como multipart/mixed› multipart/related› multipart/alternative. Los asuntos y nombres para mostrar usan RFC 2047, los nombres de archivo usan RFC 2231, así que el japonés, el chino y los emojis sobreviven el viaje.

reply_all lee el Reply-To, From, To y Cc originales, elimina tu propia dirección y cualquier dirección desde la que envíes el correo. Responde desde la dirección a la que el remitente escribió, continúa la cadena References, y cita el original en la parte que tú reenvíes. forward_message reproduce el sobre reenviado y puede reutilizar los archivos del original.

create_draft con replyToMessageId redacta una respuesta como borrador para editar antes de enviar: se une al hilo original, lleva In-Reply-To y References, deduce a quién 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 y los archivos añadidos a mano, así como el hilo, la respuesta y el asunto del borrador se leen y se conservan. Un archivo cuya base64 no quepa en los argumentos de la herramienta se prepara: stage_attachment_begin devuelve una URL de subida que acepta los bytes crudos en un curl -T, stage_attachment_append admite base64 en trozos, y cada clave de attachments admite el stagingId resultante.

La lectura es limitada a propósito: el cuerpo del mensaje y del hilo tienen presupuestos de caracteres, la totalidad de una respuesta tiene un techo de bytes y una descarga se devuelve en línea solo mientras quepa; un hilo largo de lista de correo, o un archivo grande, te vuelve recortado justo donde no cabe para que el asistente no se llene en vez de leer.


Cómo funciona

Dos flujos OAuth se encuentran en un solo Worker. El cliente MCP se autentica con el Worker; el Worker se autentica con Google en tu nombre. Ninguna de las partes tiene las credenciales de la otra.

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 result

Capa

Archivo

Qué hace

🔐 OAuth en el lado de MCP

workers-oauth-provider

Registro dinámico de clientes, PKCE, concesiones en KV con los tokens de Google sellados dentro

🔗 OAuth en el lado de Google

src/google-handler.ts

Código de autorización con acceso offline, estado de un solo uso vinculado a la sesión del navegador, CSRF de doble envío, lista de permitidos en el correo verificado

🤖 Agente

src/index.ts

Un Objeto Durable por sesión MCP, vinculado a la cuenta que lo abrió; refresco de token de un solo vuelo y amortiguación de salida

✉️ Correo

src/gmail.ts

Construcción RFC 822, árbol MIME, decodificación de juegos de caracteres, composición de respuesta y reenvío

Construido con

El propio Gmail se llama mediante fetch plano a la REST API. El SDK oficial de googleapis asume Node y carga mucho más de lo que debería cargar un Worker, así que la construcción del mensaje, el análisis MIME y el refresco de tokens viven en src/gmail.ts y src/utils.ts en su lugar.

Endpoints

Ruta

Propósito

/mcp

Endpoint de MCP

/mcp/<etiqueta>

El mismo servidor bajo cualquier etiqueta de segmento único, para clientes que rechazan que dos servidores compartan una URL

/

Esta guía de ajustes

/authorize · /token · /register · /callback

Maquinaria OAuth


Quién puede entrar

ALLOWED_EMAILS decide, y se comprueba contra la dirección que Google informa como verificada — después de su conset, lo tanto, lo tanto lo tanto:

Valor

Quién entra

(vacío)

nadie

you@gmail.com, trabajo@empresa.com

esas cuentas

*@empresa.com

cualquiera en ese dominio

*

cualquier cuenta de Google verificada

Cada concesión alcanza solo la bandeja que gestionó su autenticación, por lo que ampliar esta lista nunca amplía el acceso a las bandejas ya conectadas. Poner * deja que extraños usen tu implementación y la cuota de tus emails de Google para su propio correo.


Límites

Dos techos mantienen una implementación compartida de no ser drenados, ambos en wrangler.jsonc:

Ajuste

Dónde

Por defecto

Qué limita

MAX_ACCOUNTS

vars

25

`Cuántas cuentas de Google ri! cuentas que pueden completar el inicio de sesión. Las cuentas ya conectadas sinden al [+] en la que se alcanza el límite;

RATE_LIMITER.simple.limit

unsafe.bindings

dozena

cada 1 min

g

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, por lo que search_messages y list_drafts requieren maxResults de 45 o menos allí; por encima de eso, 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 velocidad de Cloudflare lee su límite del binding en tiempo de compilación, por lo que el simple.limit de cada uno es el único lugar que lo cambia. Un despliegue de un solo usuario puede dejar ambos como están: el uso normal del asistente queda muy por debajo de ellos.


Seguridad

El autoalojamiento mueve la cuestión de la confianza en lugar de eliminarla, así que aquí es donde está todo.

  • Tus tokens siguen siendo tuyos. Los tokens de refresco están cifrados dentro de su concesión OAuth en tu namespace KV. El Durable Object de una sesión mantiene el token de acceso de una hora de duración, y el framework del agente MCP guarda 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 almacena: pasa a través.

  • Una sesión, una bandeja de entrada. La sesión MCP está vinculada a la cuenta que la abrió, por lo 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.modify cubre lectura, envío, etiquetas y papelera. Excluye el borrado permanente y todo gmail.settings.*, manteniendo las reglas de reenvío automático y la exfiltración de filtros — las puertas traseras clásicas de la bandeja de entrada — fuera de lo que cualquier concesión robada podría hacer. Se solicitan dos ámbitos de solo lectura junto a él, userinfo.email y userinfo.profile: son la forma en que la lista de permitidos y el enlace de sesión saben qué cuenta inició sesión, y no llegan a ningún correo.

  • Las cabeceras no se pueden contrabandear. Cada valor de cabecera saliente se rechaza si contiene CR, LF o NUL, por lo que ningún argumento puede escapar de su propio campo para añadir uno — un Bcc dentro 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í: bcc es un parámetro real, por lo 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_EMAILS detiene 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 atiende una solicitud, como debe hacer cualquier relé 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), la extracción del cuerpo en distintos juegos de caracteres, la composición de respuestas y reenvíos, los flujos de token de Google, la lista de permitidos de inicio de sesión, las comprobaciones CSRF y de enlace de estado que protegen el lado del navegador del inicio de sesión, y las propias herramientas contra un Gmail simulado: propiedad de sesión, composición de destinatarios, selección de adjuntos y lo que 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 請求書.csv enviado, entregado y descargado de vuelta byte idéntico; una imagen inline cid: renderizada por el destinatario

Hilos

reply_all se dirigió al remitente, mantuvo el Cc de terceros, eliminó su propia dirección y citó el original en el mismo hilo

Dos cuentas

Ambas conectadas a un despliegue a la vez; un id de mensaje de una devolvió 404 en la otra

Organización

Una etiqueta CJK anidada creada, renombrada, aplicada por lotes y eliminada; la papelera de hilos y mensajes invertida en ambos casos

Escala

Una bandeja de 15 000 mensajes buscada con operadores de Gmail y paginación sin tocar un límite de velocidad


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 deploy

Preguntas 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., usada bajo la Licencia MIT. Ver THIRD-PARTY.md.

-
license - not tested
Not graded
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

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/Bloody-Regina/personal-gmail-mcp-bloodyregina'

If you have feedback or need assistance with the MCP directory API, please join our Discord server