gmail-mcp
AI 어시스턴트용 Gmail — 여러 계정을 동시에, 직접 소유한 서버에서.
gmail-mcp는 Gmail을 Claude 및 기타 MCP 클라이언트에 연결합니다. 메일 검색 및 읽기, 인용된 이력을 포함한 보내기 및 전체 회신, 전달, 첨부 파일 및 인라인 이미지 처리, 그리고 여러 Google 계정을 동시에 사용하는 드래프트, 라벨, 스레드 관리를 지원합니다.
자신의 Cloudflare Worker에서 원격 서버로 실행되므로, 동일한 연결이 노트북의 Claude Code, 브라우저의 claude.ai, 휴대폰의 Claude에서 모두 응답합니다. 각 연결은 하나의 Google 계정으로 로그인하며, Google 리프레시 토큰은 사용자의 Cloudflare 계정에 유지됩니다.
사람들이 이 프로젝트를 찾게 되는 이유는 두 가지입니다. Claude와 Google에 내장된 Gmail 커넥터는 메일을 읽고 드래프트를 작성할 수 있지만 보낼 수는 없으며, 어시스턴트 계정당 하나의 Google 계정만 보유합니다. 보내기가 가능한 서버는 대개 로컬 프로세스로, 책상에서는 괜찮지만 휴대폰에서는 보이지 않습니다.
비교
gmail-mcp | ||||||
실행 위치 | Cloudflare Workers | 벤더 호스팅 | 자체 서버 또는 로컬 | 로컬 | 로컬 | 로컬 |
휴대폰에서 접근 가능 | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
여러 사서함 동시 사용 | ✅ 연결별 바인딩 | ❌ | ✅ 호출별 선택 | ❌ 별칭만 가능 | ❌ | ✅ 호출별 선택 |
메일 보내기 | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
첨부 파일 · 인라인 | ✅ | 문서화 안 됨 | ✅ | ✅ | ❌ | ✅ |
인용 이력 포함 전체 회신 | ✅ | ❌ | 드래프트만 | 인용 없음 | ❌ | ✅ |
전달 | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ |
각 부분의 charset 존중 | ✅ | — | ❌ 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가 요청하지 않는 범위이므로 권한이 어떻게 되든 그 범위 밖에 있습니다.
나머지 대부분을 결정하는 두 가지 설계 차이가 있습니다. 호출 인자로 계정을 라우팅하면 하나의 권한으로 모든 연결된 사서함에 접근할 수 있는 반면, 사서함을 연결에 바인딩하면 잘못된 인자로는 아무것도 접근할 수 없습니다. 그리고 읽기 측면에서 로컬 서버는 모든 부분을 UTF-8로 디코딩합니다. ISO-2022-JP 및 Shift_JIS 메일은 깨져서 도착하고, Gmail이 첨부 파일 블롭으로 저장하는 긴 메시지는 본문이 비어서 반환됩니다.
배포하기
약 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.comGoogle은 다음 두 단계에 대한 API를 제공하지 않으므로 Cloud 콘솔에서 진행합니다:
OAuth 동의 화면 → 외부, 그런 다음 대상 고객 아래에서 앱 게시를 누릅니다. 테스트 상태로 두면 Google이 모든 리프레시 토큰을 7일마다 만료시키고 각 연결은 토큰과 함께 죽습니다. 게시하면 앱은 로그인 시 미검증 앱 경고를 표시하고 최대 100개 계정을 제공합니다.
사용자 인증 정보 → 사용자 인증 정보 만들기 → OAuth 클라이언트 ID → 웹 애플리케이션, 승인된 리디렉션 URI로
https://<your-host>/callback을 지정합니다. 클라이언트 ID와 비밀번호를 보관하세요.
<your-host>는 Worker를 가리키는 도메인, 또는 그렇지 않을 경우 부여되는 workers.dev 호스트 이름입니다. 먼저 배포하고 나중에 돌아와서 이 값을 채워도 됩니다 — Worker가 /에서 제공하는 안내서에 정확한 값이 표시됩니다.
2 · Worker 배포
이 버튼은 저장소를 GitHub 계정으로 복사하고, KV 네임스페이스와 Durable Object를 생성하며, 네 가지 비밀 값을 요청합니다. workers.dev에 배포되며, 이후 Settings → Domains & Routes에서 사용자 지정 도메인을 연결합니다.
대신 터미널에서:
git clone https://github.com/mkpoli/gmail-mcp && cd gmail-mcp
bun install
bun run setupbun run setup은 응답할 도메인을 묻고, OAUTH_KV 네임스페이스를 생성하거나 재사용하며, 클라이언트 ID와 비밀번호를 입력받고, 쿠키 키를 생성한 후 배포합니다. 처음 두 답변은 git이 무시하는 wrangler.local.jsonc에 저장됩니다 — wrangler.jsonc는 어떤 계정의 네임스페이스도 어떤 사람의 도메인도 명시하지 않으므로, 클론은 어디서든 배포할 수 있습니다. 단일 비밀 값을 교체하기 위해 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/workClaude Code에서 /mcp를 실행하여 각 연결을 해당 Google 계정에 로그인시킵니다. claude.ai에서는 Settings → Connectors → Add custom connector에서 동일한 URL을 사용합니다. /mcp/ 뒤에는 어떤 단일 세그먼트 레이블도 사용할 수 있으며, 이는 하나의 배포가 URL 공유를 거부하는 클라이언트들에게 여러 사서함을 제공하는 방식입니다.
배포는 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은 원시 바이트를 한 번의 curl -T로 받는 업로드 URL을 반환하고, 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계층 | 파일 | 역할 |
🔐 MCP 측 OAuth | 동적 클라이언트 등록, PKCE, 내부에 Google 토큰이 봉인된 KV의 권한 부여 | |
🔗 Google 측 OAuth |
| 오프라인 액세스가 포함된 인증 코드, 브라우저 세션에 바인딩된 일회성 상태, 이중 제출 CSRF, 검증된 이메일의 허용 목록 |
🤖 에이전트 |
| MCP 세션당 하나의 Durable Object, 세션을 연 계정에 바인딩됨; 단일 비행 토큰 갱신, 제한된 팬아웃 |
✉️ 메일 |
| RFC 822 구성, MIME 트리 탐색, 문자셋 디코딩, 답장 및 전달 작성 |
사용된 기술
TypeScript 기반 Cloudflare Workers — Durable Objects가 각각 하나의 MCP 세션을 보유하고, KV가 OAuth 권한 부여를 보유
Hono — OAuth 엔드포인트, Google 콜백,
/의 설정 페이지 라우팅@cloudflare/workers-oauth-provider— MCP 클라이언트가 등록하는 OAuth 2.1 서버agents—McpAgent, Durable Objects를 통한 MCP 전송@modelcontextprotocol/sdk및 Zod — 도구 정의 및 인수 검증
Gmail 자체는 REST API에 대한 일반 fetch로 호출됩니다. 공식 googleapis SDK는 Node를 가정하고 Worker가 제공해야 하는 것보다 훨씬 많은 것을 포함하므로, 메시지 구성, MIME 파싱, 토큰 갱신은 대신 src/gmail.ts와 src/utils.ts에 있습니다.
엔드포인트
경로 | 용도 |
| MCP 엔드포인트 |
| URL 공유를 거부하는 클라이언트를 위한, 단일 세그먼트 레이블 아래의 동일한 서버 |
| 이 설정 안내서 |
| OAuth 메커니즘 |
로그인할 수 있는 사람
ALLOWED_EMAILS가 결정하며, Google이 검증된 것으로 보고하는 주소와 대조하여 확인됩니다 — 동의 후, 권한 부여가 존재하기 전에.
값 | 허용되는 사람 |
(비어 있음) | 아무도 없음 |
| 해당 계정들 |
| 해당 도메인의 모든 사람 |
| 모든 검증된 Google 계정 |
각 권한 부여는 인증한 사서함에만 도달하므로, 이 목록을 넓혀도 이미 연결된 사서함에 대한 접근이 넓어지지 않습니다. *로 설정하면 낯선 사람이 사용자의 배포와 Google 클라이언트 할당량을 자신의 메일에 사용할 수 있습니다.
제한
공유 배포가 고갈되는 것을 방지하는 두 가지 상한이 있으며, 둘 다 wrangler.jsonc에 설정됩니다:
설정 | 위치 | 기본값 | 제한하는 대상 |
|
|
| 로그인을 완료할 수 있는 서로 다른 Google 계정의 대략적인 수. 상한에 도달하면 이미 연결된 계정은 계속 작동하고, 새 계정은 거부됩니다. 동시에 도착하는 로그인은 각각 기록되기 전에 수를 읽으므로, 총계는 이 숫자보다 약간 높게 settle될 수 있습니다. Google은 미검증 앱을 100명의 사용자로 제한하므로 그 아래에 여유를 두세요. |
|
|
| 해당 창에서 한 계정이 모든 세션에 걸쳐 수행할 수 있는 Gmail 호출 수. Cloudflare는 이 수를 위치별로 유지하므로, 두 지역에서 연결하는 계정은 각 지역에서 대략 그만큼 얻습니다. 넓은 읽기는 여러 번 소모합니다: 50개를 반환하는 |
|
|
| 해당 창에서 한 주소가 수행할 수 있는 클라이언트 등록 수. 클라이언트는 한 번 등록하고 부여된 ID를 유지하므로 일반적인 사용은 이 수에 근접하지 않습니다. 상한이 있는 이유는 등록에 자격 증명이 필요 없고 각 등록이 KV에 쓰기 때문입니다. |
Workers Free 플랜에서는 추가 상한이 적용됩니다: 호출당 아웃바운드 요청 50회. 넓은 읽기는 메시지당 1회를 소비하므로, search_messages와 list_drafts는 maxResults를 45 이하로 설정해야 합니다. 그 이상이면 초과분은 결과 대신 메시지별 오류로 반환됩니다. 유료 플랜은 1000을 허용합니다.
상한을 올리거나 재배포하세요. Cloudflare의 속도 제한기는 빌드 시점에 바인딩에서 상한을 읽으므로, 각각의 simple.limit이 이를 변경할 수 있는 유일한 곳입니다. 단일 사용자 배포는 둘 다 그대로 둘 수 있습니다 — 일반적인 어시스턴트 사용은 이 한도보다 훨씬 아래에 있습니다.
보안
자체 호스팅은 신뢰 문제를 제거하는 것이 아니라 이동시킬 뿐입니다. 그래서 모든 것이 위치하는 곳은 다음과 같습니다.
토큰은 당신의 것입니다. 리프레시 토큰은 KV 네임스페이스의 OAuth 권한 부여 내부에 암호화되어 저장됩니다. 세션의 Durable Object는 1시간 동안 유효한 액세스 토큰을 보유하며, MCP 에이전트 프레임워크는 객체가 존재하는 동안 권한 부여 사본을 유지합니다(리프레시 토큰 포함). 두 저장소 모두 당신의 Cloudflare 계정에 있으며, 저장 시 암호화됩니다. 메일은 저장되지 않습니다 — 그냥 통과할 뿐입니다.
하나의 세션, 하나의 사서함. MCP 세션은 이를 연 계정에 바인딩되므로, 한 사서함에 대한 권한 부여는 빌린 세션을 통해 다른 사서함에 작용할 수 없습니다.
최소 권한 범위.
gmail.modify는 읽기, 보내기, 라벨, 휴지통을 포함합니다. 영구 삭제와gmail.settings전체는 제외하므로, 자동 전달 규칙과 필터를 통한 유출 — 전형적인 사서함 백도어 — 은 어떤 도난당한 권한으로도 불가능합니다. 두 개의 읽기 전용 범위(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 시퀀스, RTL 아랍어, 결합 문자, 희귀 CJK가 변경 없이 왕복됨 |
첨부 파일 |
|
스레딩 |
|
두 계정 | 둘 다 한 번에 하나의 배포에 연결됨; 한 계정의 메시지 ID가 다른 계정에서 |
정리 | 중첩된 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질문 및 버그
이슈를 열어주세요.
라이선스
Copyright © 2026 mkpoli. MIT 라이선스에 따라 배포됩니다.
src/workers-oauth-utils.ts는 cloudflare/ai의 remote-mcp-github-oauth 데모에서 파생되었으며, Copyright © 2025 Cloudflare, Inc., MIT 라이선스에 따라 사용됩니다. 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 Connectors
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Authenticated email gateway for AI agents — per-agent inboxes, HITL approval, SPF/DKIM verified.
Authenticated email gateway for AI agents — per-agent inboxes, HITL approval, SPF/DKIM verified.
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/Bloody-Regina/personal-gmail-mcp-bloodyregina'
If you have feedback or need assistance with the MCP directory API, please join our Discord server