Skip to main content
Glama

Gmail для вашего ИИ-ассистента — несколько аккаунтов одновременно, на сервере, которым владеете вы.

MIT Cloudflare Workers MCP OAuth 2.1 27 tools tests

日本語版 · 简体中文

gmail-mcp подключает Gmail к Claude и любому другому MCP клиенту. Он умеет искать и читать письма, отправлять и отвечать всем с цитируемой историей, пересылать, работать с вложениями и встроенными изображениями, а также управлять черновиками, метками и тредами — сразу в нескольких аккаунтах Google.

Он работает как удалённый сервер на вашем собственном Cloudflare Worker, поэтому одно и то же соединение отвечает из Claude Code на ноутбуке, claude.ai в браузере и Claude на телефоне. Каждое соединение входит в один аккаунт Google, а refresh-токен Google остаётся в вашем аккаунте Cloudflare.

Две вещи приводят людей сюда. Встроенные в Claude и Google коннекторы Gmail читают почту и пишут черновики, но не могут отправлять, и держат один аккаунт Google на аккаунт ассистента. Серверы, которые умеют отправлять, обычно являются локальными процессами — хорошо за столом, но невидимы с телефона.


Сравнение

gmail-mcp

Claude · Google built-in

taylorwilsdon/google_workspace_mcp

ArtyMcLabin/Gmail-MCP-Server

shinzo-labs/gmail-mcp

aaronsb/google-workspace-mcp

Где работает

Cloudflare Workers

у вендора

ваш сервер или локально

локально

локально

локально

Доступно с телефона

Несколько ящиков одновременно

✅ привязано к соединению

✅ выбирается при вызове

❌ только алиасы

✅ выбирается при вызове

Отправка почты

Вложения · встроенные cid: изображения

не документировано

Ответ всем с цитируемой историей

только черновики

без цитирования

Пересылка

Учитывает charset каждой части

❌ предполагается UTF-8

❌ предполагается UTF-8

Отклоняет CRLF-инъекции в заголовках

✅ фреймворк

✅ удаляет

никакой

Настройки ящика (фильтры, автоответ)

❌ вне области

фильтры

фильтры

Количество инструментов

24

11–16

14 (Gmail)

30

64

11

Кто хранит ваш refresh-токен

вы

вендор

вы

вы

вы

вы

google_workspace_mcp — самый полный проект здесь. Он охватывает весь Workspace, а не только Gmail, и добавляет вашу подпись Gmail и тянет вложения прямо по URL — ни того, ни другого gmail-mcp не делает. shinzo-labs/gmail-mcp через свои 64 инструмента добирается до автоответов, делегатов и S/MIME; они живут под gmail.settings.* — областью, которую gmail-mcp никогда не запрашивает, так что они остаются вне его досягаемости, что бы ни случилось с грантом.

Два дизайнерских решения определяют почти всё остальное. Маршрутизация аккаунтов по аргументу вызова позволяет одному гранту касаться всех подключённых ящиков, тогда как привязка ящика к соединению означает, что неверный аргумент не достанет ничего. А при чтении локальные серверы декодируют каждую часть как UTF-8: письма в ISO-2022-JP и Shift_JIS приходят искажёнными, а длинные сообщения, которые Gmail хранит как вложения-блоб, возвращаются с пустым телом.


Related MCP server: littlebird-mail

Разверните его

Около десяти минут. Вам понадобятся аккаунт Cloudflare, bun и аккаунт Google. Домен в аккаунте Cloudflare необязателен — без него Worker отвечает на workers.dev.

1 · Создайте OAuth-клиент 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 не предоставляет API для следующих двух шагов, поэтому они выполняются в Cloud console:

  • Экран согласия OAuthВнешние, затем в разделе Аудитория нажмите Опубликовать приложение. Если оставить статус «Тестирование», Google будет истекать каждый refresh-токен через 7 дней, и каждое подключение умрёт вместе со своим токеном. После публикации приложение показывает предупреждение о непроверенном приложении при входе и обслуживает до 100 аккаунтов.

  • Учётные данные → Создать учётные данные → Идентификатор клиента OAuthВеб-приложение, с https://<ваш-хост>/callback в качестве разрешённого URI перенаправления. Сохраните идентификатор клиента и секрет.

<ваш-хост> — это домен, который вы указываете для Worker, или имя хоста workers.dev, которое он получает в противном случае. Сначала развернуть, а потом вернуться и заполнить это — работает: руководство, которое Worker отдаёт по адресу /, показывает точное значение.

2 · Разверните Worker

Deploy to Cloudflare

Кнопка копирует репозиторий в ваш аккаунт GitHub, создаёт пространство имён KV и Durable Object и запрашивает четыре секрета. Развёртывание происходит на workers.dev; собственный домен подключается позже через Settings → Domains & Routes.

Вместо этого из терминала:

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

bun run setup спрашивает, на каком домене отвечать, создаёт или переиспользует пространство имён OAUTH_KV, принимает идентификатор клиента и секрет, генерирует ключ cookie и развёртывает. Первые два ответа попадают в wrangler.local.jsonc, который git игнорирует — в wrangler.jsonc не указано ни пространство имён какого-либо аккаунта, ни чей-либо домен, поэтому клон разворачивается где угодно. Повторный запуск setup для ротации одного секрета безопасен.

3 · Подключите клиент

Оставьте поля идентификатора клиента и секрета пустыми — MCP-клиенты регистрируются сами.

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

Запустите /mcp в Claude Code, чтобы подписать каждое подключение на его аккаунт Google. В claude.ai это Settings → Connectors → Add custom connector с тем же URL. Любая метка из одного сегмента работает после /mcp/ — так одно развёртывание обслуживает несколько почтовых ящиков для клиентов, которые не принимают два сервера с общим URL.

Ваше развёртывание отдаёт это руководство по адресу https://<ваш-хост>/.


Что он умеет

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

Сообщения отправляются так же, как их отправляет почтовый клиент: обычный текст с HTML-альтернативой, вложения файлов и встроенные изображения, на которые ссылаются через cid:, вложенные как multipart/mixed › multipart/related › multipart/alternative. Темы и отображаемые имена используют RFC 2047, имена файлов — RFC 2231, поэтому японский, китайский и эмодзи переживают путь без потерь.

reply_all читает Reply-To, From, To и Cc исходного письма, отбрасывает ваш собственный адрес и любой адрес, с которого вы отправляете почту, отвечает с того адреса, на который писал отправитель, переносит цепочку References и цитирует исходное письмо в тех частях, которые вы отправляете. forward_message воспроизводит пересылаемый конверт и может повторно прикрепить файлы исходного письма.

create_draft с replyToMessageId записывает ответ как черновик для редактирования перед отправкой: он присоединяется к исходной ветке, переносит In-Reply-To и References, выводит получателей ответа всем и тему Re: и цитирует исходное письмо. update_draft изменяет только те поля, которые ему переданы; получатели, текст, файлы, добавленные вручную в любом клиенте, и ветка, на которую отвечает черновик, считываются обратно и сохраняются. Файл, чей base64 не помещается в аргументы инструмента, вместо этого разбивается на этапы: stage_attachment_begin возвращает URL для загрузки, который принимает сырые байты одним curl -T, stage_attachment_append принимает base64 частями, и каждое поле attachments принимает полученный stagingId.

Чтение ограничено намеренно: тела сообщений и веток имеют лимиты символов, весь ответ имеет потолок байтов, а вложение возвращается встроенным только пока оно достаточно маленькое для чтения. Длинная ветка списка рассылки или большой файл возвращаются обрезанными с примечанием об этом, а не заполняют контекст ассистента.

Как это работает

Два потока OAuth встречаются в одном Worker. MCP-клиент аутентифицируется на Worker; Worker аутентифицируется на Google от вашего имени. Ни одна сторона не держит учётные данные другой.

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

Слой

Файл

Что делает

🔐 OAuth на стороне MCP

workers-oauth-provider

Динамическая регистрация клиентов, PKCE, гранты в KV с запечатанными внутри токенами Google

🔗 OAuth на стороне Google

src/google-handler.ts

Код авторизации с офлайн-доступом, одноразовое состояние, привязанное к сессии браузера, двойная отправка CSRF, белый список по подтверждённому email

🤖 Агент

src/index.ts

Один Durable Object на MCP-сессию, привязанный к аккаунту, который её открыл; обновление токена с одним полётом, троттлинг веерной отправки

✉️ Почта

src/gmail.ts

Построение RFC 822, обход дерева MIME, декодирование кодировок, составление ответов и пересылок

Создано с помощью

  • TypeScript на Cloudflare Workers — Durable Objects держат по одной MCP-сессии, KV держит OAuth-гранты

  • Hono — маршрутизация для OAuth-эндпоинтов, колбэка Google и страницы настройки по адресу /

  • @cloudflare/workers-oauth-provider — OAuth 2.1-сервер, против которого регистрируются MCP-клиенты

  • agentsMcpAgent, MCP-транспорт поверх Durable Objects

  • @modelcontextprotocol/sdk с Zod — определения инструментов и валидация аргументов

  • Bun, Biome, Wrangler — установка, тестирование, линт, развёртывание

Gmail вызывается через обычный fetch против REST API. Официальный SDK googleapis предполагает Node и несёт гораздо больше, чем должен отправлять Worker, поэтому построение сообщений, разбор MIME и обновление токенов живут в src/gmail.ts и src/utils.ts вместо этого.

Эндпоинты

Путь

Назначение

/mcp

MCP-эндпоинт

/mcp/<label>

Тот же сервер под любой меткой из одного сегмента, для клиентов, которые не принимают два сервера с общим URL

/

Это руководство по настройке

/authorize · /token · /register · /callback

Механика OAuth

Кто может войти

ALLOWED_EMAILS решает, проверяется по адресу, который Google сообщает как подтверждённый — после согласия, до создания любого гранта.

Значение

Кто получает доступ

(пусто)

никто

you@gmail.com, work@company.com

эти аккаунты

*@company.com

любой в этом домене

*

любой подтверждённый аккаунт Google

Каждый грант достигает только того почтового ящика, который его аутентифицировал, поэтому расширение этого списка никогда не расширяет доступ к уже подключённым почтовым ящикам. Установка * позволяет незнакомцам использовать ваше развёртывание и квоту вашего Google-клиента для своей почты.

Лимиты

Два потолка защищают общее развёртывание от истощения, оба задаются в wrangler.jsonc:

Настройка

Где

По умолчанию

Что ограничивает

MAX_ACCOUNTS

vars

25

Примерно сколько разных аккаунтов Google могут когда-либо завершить вход. Уже подключённые аккаунты продолжают работать, когда лимит достигнут; новые отклоняются. Входы, приходящие одновременно, каждый читает счётчик до того, как любой из них записан, поэтому итог может оказаться чуть выше этого числа. Google ограничивает непроверенные приложения 100 пользователями, поэтому оставьте место ниже этого.

RATE_LIMITER.simple.limit

unsafe.bindings

120 за 60с

Вызовы Gmail, которые один аккаунт может сделать в этом окне, во всех своих сессиях. Cloudflare считает это количество по местоположению, поэтому аккаунт, подключающийся из двух регионов, получает примерно столько в каждом. Широкое чтение тратит несколько: search_messages, возвращающий 50, делает 51 вызов.

REGISTER_LIMITER.simple.limit

unsafe.bindings

10 за 60с

Регистрации клиентов, которые один адрес может сделать в этом окне. Клиент регистрируется один раз и сохраняет выданный ему идентификатор, поэтому обычное использование никогда не приближается к этому; потолок существует потому, что регистрация не требует учётных данных и каждая запись пишет в KV.

На тарифе Workers Free действует дополнительный потолок: 50 исходящих запросов на один вызов. Широкое чтение тратит по одному запросу на сообщение, поэтому search_messages и list_drafts там требуют maxResults не выше 45; сверх этого излишек возвращается в виде ошибок на каждое сообщение, а не результатов. Платный план допускает 1000.

Поднимите любой из них и разверните заново. Ограничитель скорости Cloudflare считывает свой потолок из привязки во время сборки, так что simple.limit в каждом из них — единственное место, которое его меняет. Развёртывание для одного пользователя может оставить оба без изменений — обычное использование ассистента находится намного ниже них.


Безопасность

Самостоятельный хостинг переносит вопрос доверия, а не устраняет его, так что вот как обстоят дела.

  • Ваши токены остаются вашими. Refresh-токены зашифрованы внутри их OAuth-гранта в вашем пространстве имён KV. Durable Object сессии хранит access-токен со сроком жизни в один час, а фреймворк MCP-агента держит там копию гранта, пока жив объект, включая refresh-токен. Оба хранилища находятся в вашем собственном аккаунте Cloudflare и зашифрованы в состоянии покоя. Почта никогда не хранится — она проходит транзитом.

  • Одна сессия — один почтовый ящик. Сессия MCP привязана к аккаунту, который её открыл, поэтому грант для одного почтового ящика не может действовать на другой через заимствованный идентификатор сессии.

  • Минимализм областей доступа. gmail.modify покрывает чтение, отправку, метки и корзину. Он исключает необратимое удаление и всё из gmail.settings.*, оставляя правила автоматической пересылки и эксфильтрацию через фильтры — классические лазейки в почтовый ящик — за пределами того, что может сделать украденный грант. Вместе с ним запрашиваются две области доступа только для чтения, userinfo.email и userinfo.profile: именно по ним белый список и привязка сессии понимают, какой аккаунт выполнил вход, и до почты они не добираются.

  • Контрабанда заголовков невозможна. Каждое значение исходящего заголовка отклоняется, если оно содержит CR, LF или NUL, поэтому ни один аргумент не может вырваться из собственного поля и добавить ещё одно — скажем, Bcc внутри строки темы. MIME-типы проверяются, а цитируемая история экранируется как HTML. Но сами аргументы не контролируются: bcc — настоящий параметр, поэтому модель, выполняющая инструкцию, скрытую в теле сообщения, всё ещё может его заполнить, и проверкой этого остаётся запрос на подтверждение в вашем клиенте.

  • Доступ можно отозвать. Сужение ALLOWED_EMAILS останавливает новые входы. Доступ отдельного аккаунта отзывается на myaccount.google.com/connections. Ротация секрета клиента Google разом аннулирует все гранты.

Worker расшифровывает почту в памяти во время обработки запроса, как и любой размещённый ретранслятор. Если для какого-то почтового ящика это неприемлемо, запустите для него локальный MCP-сервер.


Как это тестировалось

253 модульных теста покрывают конструирование сообщений (вложенность MIME, перенос по RFC 2047, имена файлов по RFC 2231, отклонение CR/LF, перенос base64), извлечение тела письма в различных кодировках, составление ответов и пересылок, потоки токенов Google, белый список входа, проверки CSRF и привязки состояния, защищающие браузерную сторону входа, а также сами инструменты против имитации Gmail — принадлежность сессии, составление получателей, выбор вложений и то, что возвращает частично неудачное чтение.

Кроме того, каждый инструмент запускался на реальных аккаунтах Gmail, а отдельный аккаунт проверял, что пришло:

Область

Результат

Кодировка

Японские темы с переносами между закодированными словами; эмодзи, ZWJ-последовательности, арабский RTL, комбинируемые знаки и редкие символы CJK прошли полный цикл без изменений

Вложения

CSV-файл с именем 請求書.csv был отправлен, доставлен и скачан обратно байт-в-байт идентичным; встроенное изображение cid: отобразилось у получателя

Цепочки

reply_all обратился к отправителю, сохранил сторонний Cc, убрал собственный адрес и процитировал исходное сообщение в той же цепочке

Два аккаунта

Оба одновременно были подключены к одному развёртыванию; идентификатор сообщения из одного вернул 404 в другом

Организация

Вложенная метка CJK создана, переименована, применена пакетно и удалена; перемещение в корзину ветки и сообщения в обоих случаях отменено

Масштаб

Выполнен поиск по почтовому ящику с 15 000 сообщений с помощью операторов Gmail и пагинации без превышения лимита запросов


Разработка

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

Вопросы и ошибки

Создайте issue.


Лицензия

Авторское право © 2026 mkpoli. Распространяется под лицензией MIT.

src/workers-oauth-utils.ts является производным от демо remote-mcp-github-oauth в репозитории cloudflare/ai, авторское право © 2025 Cloudflare, Inc., используется по лицензии MIT. См. THIRD-PARTY.md.

A
license - permissive license
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 Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Production-ready MCP server for Gmail, enabling AI agents to search, read, send, draft, and manage emails, labels, and attachments via the Google Gmail API.
  • F
    license
    Not graded
    quality
    B
    maintenance
    An MCP server that provides email sending, reading, replying, and searching capabilities through a Cloudflare Worker, allowing an AI assistant to manage an independent mailbox.
  • A
    license
    Not graded
    quality
    B
    maintenance
    A 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.
    231
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A Gmail MCP server that lets AI assistants search, read, send, and manage email across multiple Google accounts, deployed on Cloudflare Workers.
    231
    MIT

View all related MCP servers

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.

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/jlindustries845-droid/gmail-mcp'

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