Skip to main content
Glama

あなたのAIアシスタントのためのGmail — 複数のアカウントを同時に、あなた自身のサーバーで。

MIT Cloudflare Workers MCP OAuth 2.1 27 tools tests

日本語版 · 简体中文

gmail-mcp は、Gmail を Claude やその他の MCP クライアントに接続します。検索・閲覧引用履歴付きの返信・全員返信転送添付ファイルやインライン画像の処理、下書き・ラベル・スレッドの管理を、複数の Google アカウントを同時に行えます。

これはあなた自身の Cloudflare Worker 上でリモートサーバーとして動作するため、同じ接続がノートPCの Claude Code、ブラウザの claude.ai、スマホの Claude から利用できます。各接続は1つの Google アカウントにサインインし、Google のリフレッシュトークンはあなたの Cloudflare アカウントに保持されます。

ここに来る理由は2つあります。Claude と Google に組み込まれた Gmail コネクタはメールの閲覧と下書き作成はできますが、送信はできず、アシスタントアカウントごとに1つの Google アカウントしか保持できません。送信できるサーバーは通常ローカルプロセスで、机の上では問題ありませんが、スマホからは見えません。


比較

gmail-mcp

Claude · Google 組み込み

taylorwilsdon/google_workspace_mcp

ArtyMcLabin/Gmail-MCP-Server

shinzo-labs/gmail-mcp

aaronsb/google-workspace-mcp

実行場所

Cloudflare Workers

ベンダー管理

あなたのサーバーまたはローカル

ローカル

ローカル

ローカル

スマホからアクセス可能

複数のメールボックスを同時に

✅ 接続ごとに固定

✅ 呼び出しごとに選択

❌ エイリアスのみ

✅ 呼び出しごとに選択

メール送信

添付ファイル・インライン cid: 画像

未文書化

引用履歴付きの全員返信

下書きのみ

引用なし

転送

各パートの文字コードを尊重

❌ UTF-8 前提

❌ UTF-8 前提

CRLF ヘッダーインジェクションを拒否

✅ フレームワーク

✅ 除去

なし

メールボックス設定(フィルタ、休暇)

❌ 対象外

フィルタ

フィルタ

ツール数

24

11–16

14 (Gmail)

30

64

11

リフレッシュトークンの保持者

あなた

ベンダー

あなた

あなた

あなた

あなた

google_workspace_mcp は、ここにあるプロジェクトの中で最も完全です。Gmail だけでなく Workspace 全体をカバーし、Gmail の署名を追加し、URL から直接添付ファイルを取得しますが、gmail-mcp はどちらも行いません。shinzo-labs/gmail-mcp は、64のツールで休暇応答、委任、S/MIME に対応しています。これらは gmail.settings.* の下にあり、gmail-mcp が要求しないスコープであるため、権限がどうであれ、その範囲外にあります。

残りの大部分を決めるのは、2つの設計上の違いです。呼び出し引数でアカウントをルーティングすると、1つの権限で接続されたすべてのメールボックスにアクセスできますが、メールボックスを接続にバインドすると、間違った引数は何にも到達しません。また、読み取りに関しては、ローカルサーバーはすべてのパートを UTF-8 としてデコードします。ISO-2022-JP や Shift_JIS のメールは文字化けし、Gmail が添付ファイルのブロブとして保存する長いメッセージは、本文が空で返されます。


Related MCP server: littlebird-mail

デプロイ

約10分です。Cloudflare アカウント、bun、Google アカウントが必要です。Cloudflare アカウントのドメインは任意です。ない場合は Worker は workers.dev で応答します。

1 · Google OAuth クライアントを作成

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 は次の2つのステップの API を公開していないため、これらは Cloud コンソール で行われます。

  • OAuth の同意画面外部, 次に 対象者 の下で アプリを公開 を押します。テスト状態のままにしておくと、Google は更新トークンを 7 日ごとに失効させ、接続はそのトークンとともに失われます。公開状態では、アプリはサインイン時に「未確認アプリ」の警告を表示しますが、最大 100 アカウントまで利用できます。

  • 認証情報 → 認証情報を作成 → OAuth クライアントIDWeb アプリケーション を選び、承認済みのリダイレクト URI に https://<your-host>/callback を設定します。クライアント ID とシークレットは各自で保管してください。

<your-host> は、Worker に向けるドメイン、または、そのまま使う場合に割り当てられる workers.dev のホスト名です。先にデプロイしてから、この値を埋めに戻ることもできます。Worker が / で提供するガイドに、正確な値が表示されます。

2 · Worker をデプロイする

Deploy to Cloudflare

このボタンを押すと、リポジトリがあなたの GitHub アカウントにコピーされ、KV 名前空間と Durable Object が作成され、4 つのシークレットの入力を求められます。workers.dev にデプロイされます。カスタムドメインは、後で 設定 → ドメインとルート で追加します。

ターミナルから行う場合:

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

bun run setup は、応答先ドメインを尋ね、OAUTH_KV 名前空間を作成または再利用し、クライアント ID とシークレットを受け取り、Cookie キーを生成して、デプロイします。最初の 2 つの回答は wrangler.local.jsonc に保存されます。これは git で無視されます。wrangler.jsonc にはどのアカウントの名前空間もドメインも記述されていないため、クローンはどこへでもデプロイできます。1 つのシークレットをローテーションするために setup を再実行しても安全です。

3 · クライアントを接続する

クライアント ID と クライアント シークレットのフィールドは空のままにしてください。MCP クライアントが自身を登録します。

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

Claude Code で /mcp を実行すると、各接続をその Google アカウントにサインインできます。claude.ai では、設定 → コネクター → カスタムコネクターを追加 で同じ URL を指定します。/mcp/ の後には任意の単一セグメントのラベルを使用できます。これにより、1 つのデプロイメントで、同じ URL を共有する 2 つのサーバーを拒否するクライアントにも複数のメールボックスを提供できます。

あなたのデプロイメントは、このガイドを https://<your-host>/ で提供します。


できること

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-ToFromToCc を読み取り、自分のアドレスと送信元として使用するすべてのアドレスを除外し、送信者が宛てたアドレスから返信し、References チェーンを引き継ぎ、送信する部分で元のメッセージを引用します。forward_message は転送時のエンベロープを再現し、元の添付ファイルを再添付できます。

replyToMessageId を指定した create_draft は、送信前に編集できる下書きとして返信を作成します。元のスレッドに加わり、In-Reply-ToReferences を引き継ぎ、全員返信の宛先と「Re:」件名を導出し、元のメッセージを引用します。update_draft は指定されたフィールドのみ変更します。宛先、本文、任意のクライアントで手動で追加された添付ファイル、下書きが返信するスレッドは読み戻されて保持されます。base64 がツールの引数に収まらないファイルは、代わりにステージングされます。stage_attachment_begin は、curl -T で生バイトを 1 回で受け取るアップロード URL を返し、stage_attachment_append は base64 をチャンクで受け取り、すべての attachments フィールドは結果の stagingId を受け付けます。

読み取りは意図的に制限されています。メッセージとスレッドの本文には文字数制限、レスポンス全体にはバイト上限があり、添付ファイルは十分に小さい場合のみインラインで返されます。長いメーリングリストのスレッドや大きなファイルは、アシスタントのコンテキストを取得せず、その旨を注記付きで省略されて返されます。


仕組み

2 つの OAuth フローが 1 つの 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

レイヤー

ファイル

役割

🔐 MCP 側 OAuth

workers-oauth-provider

動的クライアント登録、PKCE、KV への OAuth 付与(Google トークンが封入されている)

🔗 Google 側 OAuth

src/google-handler.ts

オフライン アクセス付きの認証コード、ブラウザ セッションにバインドされたワンタイム状態、ダブルサブミット CSRF、検証済みメールの許可リスト

🤖 Agent

src/index.ts

MCP セッションごとに 1 つの Durable Object をそのセッションを開いたアカウントに紐付ける。シングルフライトのトークン更新、スロットリングされたファンアウト

✉️ Mail

src/gmail.ts

RFC 822 の構築、MIME ツリーの走査、文字コードのデコード、返信・転送の構成

使用技術

Gmail 自体は [RS APIを構成する に対する素の fetch 呼び出しです。公式の googleapis SDK は Node を前提とし、Worker に搭載すには大きすぎるため、メッセージ構築、MIME パース、トークン更新は src/gmail.tssrc/utils.ts に実装されています。

エンドポイント

パス

目的

/mcp

MCP エンドポイント

/mcp/<label>

同一サーバーを任意の単一セグメントのラベルの下に置く。URL を共有する 2 つのサーバーを拒否するクライアント向け

/

このセットアップガイド

/authorize · /token · /registerser · /callback

OAuth の内部機構


サインインできるユーザー

ALLOWED_EMAILS が決定します。これは、Google が検証済みとして報告するアドレスと照合されます。条件の後、付与が存在する前に行われます。

アクセスできるユーザー

(空)

誰も

you@gmail.com, work@company.com

それらのアカウント

*@company.com

そのドメインの全員

*

検証済みのすべての Google アカウント

各付与は、認証したメールボックスにのみ到達します。つまり、このリストを広げても、すでに接続されているメールボックスへのアクセスが広がることはありません。* を設定すると、自分のメールのためにあなたのデプロイメントと Google クライアントのクエラを利用できるのはだ全ラームです。


制限

2 つの上限が、共有デプロイのリソースを食い尽くすことを防ぎます。どちらも wrangler.jsonc に設定されています。

設定

場所

デフォルト

対象

MAX_ACCOUNTS

vars

25

サインインを完了できる固有の Google アカウントの概数。上限に達しても、接続済みのアカウントは動作し続けます。新規アカウントは拒否されます。同時に到着したサインインは、記録前にそれぞれがカウントを読み取るため、全体としてこの上限を若干超えることがあります。Google は未確認アプリを 100 ユーザーに制限しているため、この数以下に余裕を残してください。

RATE_LIMITER.simple.limit

unsafe.bindings

120 per 60s

そのウィンドウ内で、1 つのアカウントがそのすべてのセッション合わせて発行できる Gmail 呼び出しの回数。Cloudflare はこの回数地域ごとに維持するため、2 つの地域から接続されたアカウントは、それぞれの地域でおおよそその数を発行できます。大量読み取りは複数消費します。search_messages が 50 件返すと 51 回呼び出します。

REGISTER_LIMITER.simple.limit

unsafe.bindings

10 per 60s

そのウィンドウ内で 1 つの送信元アドレスが行えるクライアント登録の数。クライアントは 1 度登録し、渡された ID を保持するので、通常の利用では決して接近しません。上限があるのは、登録には認証情報が不要で、実行ごとに KV への書き込みが発生 あたためです。

Workers Freeプランでは、さらに上限が適用されます: 1回の呼び出しにつきアウトバウンドリクエストは50件です。ワイドリードはメッセージごとに1件を消費するため、search_messageslist_drafts では maxResults を45以下にする必要があります。それを超えると、超過分は結果ではなくメッセージごとのエラーとして返されます。有料プランでは1000件です。

どちらかを引き上げて再デプロイしてください。Cloudflareのレートリミッターはビルド時にバインディングから上限を読み取るため、各々の simple.limit がそれを変更する唯一の場所です。シングルユーザー展開では、両方ともそのままで問題ありません。通常のアシスタント利用は、それらをはるかに下回ります。


セキュリティ

セルフホスティングは信頼の問題を移すだけで、なくすわけではないため、ここにすべての位置づけを示します。

  • トークンはあなたのもののままです。 リフレッシュトークンは、KV名前空間内のOAuthグラント内で暗号化されます。セッションのDurable Objectは1時間有効なアクセストークンを保持し、MCPエージェントフレームワークはオブジェクトが存在する限り、リフレッシュトークンを含むグラントのコピーをそこに保持します。どちらのストアもお客様自身のCloudflareアカウント内にあり、保存時は暗号化されます。メールが保存されることはありません。通過するだけです。

  • 1セッション、1メールボックス。 MCPセッションはそれを開いたアカウントにバインドされるため、あるメールボックスのグラントが、借用したセッションIDを介して別のメールボックスに作用することはできません。

  • スコープの最小化。 gmail.modify は読み取り、送信、ラベル、ゴミ箱をカバーします。完全削除と gmail.settings.* のすべてを除外し、自動転送ルールとフィルタの外部送信(古典的なメールボックスのバックドア)を、盗まれたグラントが実行できる範囲外に保ちます。これに加えて、userinfo.emailuserinfo.profile の2つの読み取り専用スコープが要求されます。これらは、許可リストとセッションバインディングがどのアカウントがサインインしたかを認識する方法であり、メールには一切アクセスしません。

  • ヘッダーを密輸することはできません。 送信されるすべてのヘッダー値は、CR、LF、NUL を含む場合に拒否されるため、引数が自身のフィールドから抜け出して追加することはできません(たとえば、件名内の Bcc など)。メディアタイプは検証され、引用された履歴は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 を保持し、自身のアドレスを削除し、同じスレッドで元のメッセージを引用しました

2つのアカウント

両方が同時に1つのデプロイメントに接続され、一方のメッセージIDは他方で 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 を開いてください。


ライセンス

Copyright © 2026 mkpoli. MITライセンス の下で公開されています。

src/workers-oauth-utils.ts は、cloudflare/airemote-mcp-github-oauth デモ から派生したもので、Copyright © 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