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 | 공급업체 호스팅 | 당신의 서버 또는 로컬 | 로컬 | 로컬 | 로컬 |
휴대폰에서 접근 가능 | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ |
여러 사서함 동시 지원 | ✅ 연결별 바인딩 | ❌ | ✅ 호출별 선택 | ❌ 별칭만 | ❌ | ✅ 호출별 선택 |
메일 보내기 | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
첨부 파일 · 인라인 | ✅ | 문서화되지 않음 | ✅ | ✅ | ❌ | ✅ |
인용된 기록이 포함된 전체 답장 | ✅ | ❌ | 초안만 | 인용 없음 | ❌ | ✅ |
전달 | ✅ | ❌ | ✅ | ❌ | ❌ | ✅ |
각 부분의 문자셋 존중 | ✅ | — | ❌ 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의 rate limiter는 빌드 시 바인딩에서 상한을 읽으므로, 각각의 simple.limit만이 그것을 변경하는 유일한 곳입니다. 단일 사용자 배포는 둘 다 그대로 둬도 됩니다 — 일반적인 어시스턴트 사용은 그보다 훨씬 아래에 있습니다.
보안
셀프 호스팅은 신뢰의 문제를 제거하는 대신 옮길 뿐이므로, 여기에 모든 것이 어디에 있는지 정리합니다.
토큰은 여러분의 것입니다. 리프레시 토큰은 KV 네임스페이스의 OAuth grant 내부에 암호화되어 저장됩니다. 세션의 Durable Object는 1시간 동안 유효한 액세스 토큰을 보유하며, MCP 에이전트 프레임워크는 객체가 살아 있는 한 grant의 사본(리프레시 토큰 포함)을 그곳에 유지합니다. 두 저장소 모두 여러분 자신의 Cloudflare 계정에 있으며 저장 시 암호화됩니다. 메일은 저장되지 않습니다 — 통과할 뿐입니다.
하나의 세션, 하나의 사서함. MCP 세션은 그것을 연 계정에 바인딩되므로, 한 사서함의 grant는 빌린 세션 id로 다른 사서함에 작용할 수 없습니다.
스코프 최소화.
gmail.modify는 읽기, 보내기, 라벨, 휴지통을 포함합니다. 영구 삭제와 모든gmail.settings.*를 제외함으로써, 자동 전달 규칙과 필터 유출(전형적인 사서함 백도어)은 도난당한 grant가 할 수 있는 범위 밖에 남습니다. 그와 함께 두 개의 읽기 전용 스코프,userinfo.email과userinfo.profile이 요청됩니다. 이들은 allowlist와 세션 바인딩이 어떤 계정이 로그인했는지 알 수 있는 방법이며, 메일에는 닿지 않습니다.헤더는 밀반입될 수 없습니다. 모든 발신 헤더 값은 CR, LF 또는 NUL을 포함하면 거부되므로, 어떤 인수도 자신의 필드를 벗어나 필드를 하나 덧붙일 수 없습니다 — 예를 들어 제목 줄 안의
Bcc같은 것. 미디어 타입은 검증되고, 인용된 기록은 HTML 이스케이프됩니다. 이 기능은 인수 자체를 단속하지 않습니다.bcc는 실제 매개변수이므로, 메시지 본문에 숨겨진 지시에 따라 행동하는 모델이 여전히 그것을 채울 수 있으며, 클라이언트의 승인 프롬프트가 그에 대한 확인 수단으로 남습니다.액세스를 철회할 수 있습니다.
ALLOWED_EMAILS를 좁히면 새 로그인이 중단됩니다. 단일 계정의 액세스는 myaccount.google.com/connections에서 해지됩니다. Google 클라이언트 시크릿을 교체하면 모든 grant가 한 번에 무효화됩니다.
Worker는 요청을 처리하는 동안 메일을 메모리에서 복호화합니다. 호스팅되는 모든 릴레이가 그렇듯이. 특정 사서함에서 그것이 받아들일 수 없다면, 그 사서함에 대해서는 로컬 MCP 서버를 실행하세요.
테스트 방법
253개의 유닛 테스트는 메시지 구성(MIME 중첩, RFC 2047 폴딩, RFC 2231 파일명, CR/LF 거부, base64 래핑), 다양한 charset에서의 본문 추출, 답장 및 전달 작성, Google 토큰 흐름, 로그인 allowlist, 로그인의 브라우저 측을 지키는 CSRF 및 state 바인딩 검사, 그리고 모의 Gmail을 상대로 한 도구 자체(세션 소유권, 수신자 구성, 첨부 파일 선택, 부분 실패한 읽기가 반환하는 것)를 다룹니다.
그 외에도 모든 도구는 실제 Gmail 계정에 대해 실행되었으며, 별도의 계정이 도착한 내용을 확인했습니다:
영역 | 결과 |
인코딩 | 일본어 제목이 인코딩된 단어에 걸쳐 폴딩됨; 이모지, ZWJ 시퀀스, RTL 아랍어, 결합 문자, 희귀 CJK가 변경 없이 왕복됨 |
첨부 파일 |
|
스레딩 |
|
두 계정 | 두 계정이 동시에 하나의 배포에 연결됨; 한 계정의 메시지 id가 다른 계정에서 |
정리 | 중첩된 CJK 라벨이 생성, 이름 변경, 일괄 적용, 삭제됨; 스레드 및 메시지 휴지통 처리가 모두 되돌려짐 |
규모 | 15,000개 메시지 규모의 사서함을 Gmail 연산자와 페이지네이션으로 rate limit에 걸리지 않고 검색함 |
개발
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 License에 따라 배포됩니다.
src/workers-oauth-utils.ts는 cloudflare/ai의 remote-mcp-github-oauth 데모에서 파생되었으며, Copyright © 2025 Cloudflare, Inc., MIT License에 따라 사용됩니다. 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
MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.
Shipmail MCP server for AI agent custom-domain email inboxes with REST API and webhooks.
Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.
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/eubin-create/gmail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server