Skip to main content
Glama
Nicolasza1973

gmail-mcp

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

MIT Cloudflare Workers MCP OAuth 2.1 27 tools tests

English · 简体中文

gmail-mcp はGmailをClaudeおよびその他のMCPクライアントに接続します。メールの検索と読み取り、引用履歴付きの送信と全員に返信、転送、添付ファイルとインライン画像の処理、下書き・ラベル・スレッドの管理を、複数のGoogleアカウントで同時に行うことができます。

これはあなた自身のCloudflare Worker上でリモートサーバーとして実行されるため、同じ接続がラップトップ上のClaude Code、ブラウザ上のclaude.ai、スマートフォン上のClaudeからの要求に応答します。各接続は1つのGoogleアカウントにサインインし、GoogleのリフレッシュトークンはあなたのCloudflareアカウント内に留まります。

人々がここに来る理由は二つあります。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がリクエストしないスコープであるため、権限の付与に関わらずgmail-mcpの範囲外です。

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


Related MCP server: multiGmailMCP

デプロイ

約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クライアントID → ウェブアプリケーション、認証済みリダイレクト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にはどのアカウントの名前空間も誰のドメインも指定されていないため、クローンはどこにでもデプロイできます。単一のシークレットをローテーションするためにセットアップを再実行しても安全です。

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

replyToMessageIdを指定したcreate_draftは、送信前に編集するための下書きとして返信を作成します。元のスレッドに参加し、In-Reply-ToとReferencesを引き継ぎ、返信先全員の受信者とRe:件名を導き出し、元のメールを引用します。update_draftは、指定されたフィールドのみを変更します。受信者、テキスト、任意のクライアントで手動で追加されたファイル、および下書きが返信するスレッドは読み戻されて保持されます。base64がツールの引数に収まらないファイルは、代わりにステージングされます。stage_attachment_beginは、1回のcurl -Tで生のバイトを受け取るアップロード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、Googleトークンを内部に封印したKV内の許可

🔗 Google側OAuth

src/google-handler.ts

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

🤖 エージェント

src/index.ts

MCPセッションごとに1つのDurable Object、それを開いたアカウントにバインド。シングルフライトトークンリフレッシュ、スロットル付きファンアウト

✉️ メール

src/gmail.ts

RFC 822構築、MIMEツリーウォーキング、文字セットデコード、返信・転送の構成

使用技術

  • TypeScript on Cloudflare Workers — Durable Objectはそれぞれ1つのMCPセッションを保持し、KVはOAuth許可を保持します

  • Hono — OAuthエンドポイント、Googleコールバック、/のセットアップページのルーティング

  • @cloudflare/workers-oauth-provider — MCPクライアントが登録するOAuth 2.1サーバー

  • agents — McpAgent、Durable Object上のMCPトランスポート

  • @modelcontextprotocol/sdk with Zod — ツール定義と引数バリデーション

  • Bun, Biome, Wrangler — インストール、テスト、リント、デプロイ

Gmail自体は、REST APIに対するプレーンなfetchで呼び出されます。公式のgoogleapis SDKはNodeを前提としており、Workerが提供するにはあまりにも多くのものを含んでいるため、メッセージ構築、MIME解析、トークンリフレッシュは代わりにsrc/gmail.tsとsrc/utils.tsにあります。

エンドポイント

パス

目的

/mcp

MCPエンドポイント

/mcp/<label>

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

/

このセットアップガイド

/authorize · /token · /register · /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

60sあたり120

1つのアカウントがその期間に行えるGmail呼び出しの数。すべてのセッションを横断します。Cloudflareはこのカウントをロケーションごとに保持するため、2つのリージョンから接続するアカウントは、それぞれでおおよそその数になります。広範な読み取りは複数消費します。50件を返すsearch_messagesは51回の呼び出しを行います。

REGISTER_LIMITER.simple.limit

unsafe.bindings

60sあたり10

1つのアドレスがその期間に行えるクライアント登録の数。クライアントは一度登録して、付与されたIDを保持するため、通常の使用ではこの制限に達することはありません。この上限は、登録に認証情報が不要で、それぞれがKVに書き込むために存在します。

Workers Free プランでは、さらに呼び出しあたり50件の送信リクエストという上限が適用されます。読み取り系の操作はメッセージごとに1件を消費するため、search_messages や list_drafts では maxResults を45以下に設定してください。それを超えると、超過分は結果ではなくメッセージごとのエラーとして返されます。有料プランでは1000件まで可能です。

いずれかの制限値を引き上げて再デプロイしてください。Cloudflare のレートリミッターはビルド時にバインディングから上限値を読み取るため、変更箇所はそれぞれの simple.limit のみです。シングルユーザー環境ではそのままでも問題ありません。通常のアシスタント利用では制限値を大きく下回るためです。


セキュリティ

セルフホスティングは信頼の問題を解消するのではなく、移行するものです。以下に各要素の位置づけを示します。

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

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

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

  • ヘッダーは密輸できません。 すべての送信ヘッダー値は、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 シーケンス、右横書きアラビア語、結合文字記号、希少な CJK が変更されずに往復

添付ファイル

請求書.csv という名前の CSV を送信、配信、ダウンロードし、バイト単位で同一であることを確認。インラインの cid: 画像が受信者側でレンダリングされる

スレッド化

reply_all は送信者に宛て、第三者の Cc を保持し、自身のアドレスを除外し、同じスレッド内で元のメッセージを引用

2つのアカウント

両方が同時に1つのデプロイメントに接続。一方のアカウントからのメッセージ ID は他方で 404 を返す

整理

ネストされた CJK ラベルを作成、名前変更、バッチ適用、削除。スレッドとメッセージのゴミ箱送りを両方とも元に戻す

規模

Gmail オペレーターとページネーションを使用して 15,000 メッセージのメールボックスを検索し、レート制限に抵触しない


開発

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/ai の remote-mcp-github-oauth demo を元にしており、Copyright © 2025 Cloudflare, Inc.、MIT ライセンスの下で使用されています。詳しくは THIRD-PARTY.md を参照してください。

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Connects AI assistants to multiple Gmail accounts simultaneously, enabling search, read, draft, send, and reply operations with per-account permission controls.
    54
    ISC