Gmail MCP Gateway
Gmail MCP Gateway
AI 에이전트가 여러 Gmail 계정에 대해 전체 읽기 및 정리 접근 권한을 가지되, 메일을 보내거나 휴지통으로 이동하거나 삭제할 수 없는 MCP 서버입니다.
Gmail MCP Gateway
ALLOWED FORBIDDEN
─────── ─────────
Search Send
Read messages Send draft
Read threads Trash
Read attachments Delete
Create drafts Mark spam
Edit drafts Gmail settings
Archive Forwarding rules
Read / unread Arbitrary API calls
Labels이 보장은 클라이언트에 대한 지시사항이 아닌 애플리케이션 코드에 의해 적용됩니다. 버그가 있거나 손상되었거나 프롬프트 인젝션된 MCP 클라이언트는 이 게이트웨이를 통해 이메일을 보낼 수 없습니다. 이를 허용하는 코드 경로가 존재하지 않기 때문입니다.
목차
Related MCP server: imap-mcp
빠른 시작
Python 3.11+ 필요. 5단계, 약 10분 소요, 대부분은 Google 콘솔에서 작업합니다.
1. 설치
git clone <this-repo> gmail-mcp-gateway
cd gmail-mcp-gateway
uv sync # or: python -m venv .venv && .venv/bin/pip install -e .
.venv/bin/gmail-mcp-gateway --version선택적으로 PATH에 추가하면 아래 예제가 더 자연스럽게 읽힙니다:
export PATH="$PWD/.venv/bin:$PATH"2. Google OAuth 클라이언트 생성
한 번만 수행하며 무료이며, 이후 추가하는 모든 계정이 공유합니다.
https://console.cloud.google.com/에서 프로젝트를 만듭니다.
API 및 서비스 → 라이브러리 → Gmail API 사용 설정.
API 및 서비스 → OAuth 동의 화면 → 외부, 필수 필드를 채우고 테스트 사용자에 자신의 Google 계정을 추가합니다.
앱 게시 (사용자가 본인뿐이라면 아직 검토 확인이 필요하지 않습니다). 이 단계를 건너뛰면 앱이 "테스트" 상태로 남아 Google이 7일 후에 갱신 토큰을 만료시키며 매주 재인증해야 합니다.
사용자 인증 정보 → 사용자 인증 정보 만들기 → OAuth 클라이언트 ID → 데스크톱 앱 → JSON 다운로드.
여기서 범위를 선택하지 않습니다. 게이트웨이는 인증 시 필요한 것만 요청하며 Gmail 외부의 모든 요청을 거부합니다.
3. OAuth 클라이언트 설치
install -Dm600 ~/Downloads/client_secret_*.json \
~/.local/share/gmail-mcp-gateway/secrets/oauth_client.json수동으로 배치해야 하는 유일한 파일입니다. 암호화 키는 첫 실행 시 자동 생성됩니다.
4. 계정 인증
gmail-mcp-gateway accounts add personal브라우저가 열립니다. 요청된 권한을 승인하고 모든 상자를 선택한 상태로 둡니다 (권한이 거부되면 게이트웨이는 부분 작동 대신 큰 오류를 발생시킵니다). 갱신 토큰이 암호화되어 저장되며, 이후 게이트웨이는 무인으로 실행됩니다.
원하는 만큼 추가할 수 있습니다 — 각 계정은 자체 동의, 갱신 토큰, 암호화 키, 속도 제한 버킷, 감사 추적을 갖습니다:
gmail-mcp-gateway accounts add work
gmail-mcp-gateway accounts add newsletters --read-only # Google itself refuses writes5. 확인
gmail-mcp-gateway health # exit 0 = ready, 2 = something is wrong[ok ] directories config=/home/you/.config/gmail-mcp-gateway ...
[ok ] database /home/you/.local/share/gmail-mcp-gateway/gateway.db
[ok ] master_key loaded
[ok ] oauth_client configured
[ok ] accounts 1/1 authorized
gmail-mcp-gateway 1.0.0: healthy그런 다음 MCP 클라이언트를 연결하거나(자세한 내용은 MCP 클라이언트 연결 참조) 먼저 테스트해 보세요:
uv run python scripts/try-it.py --account personal환경 변수
일반 로컬 설치의 경우 어떤 환경 변수도 필요하지 않습니다. 위 빠른 시작에서는 환경 변수를 전혀 설정하지 않습니다. 기본값은 구성 파일을 ~/.config에, 데이터와 비밀을 ~/.local/share에 배치하며 암호화 키는 자체 생성됩니다.
이러한 변수는 컨테이너, systemd 유닛, 비밀 관리자와 같이 파일 기반 메커니즘이 적절하지 않은 환경을 위해 존재합니다.
변수 | 필수? | 기본값 | 용도 |
| 아니요¹ | — | Google OAuth 클라이언트 ID |
| 아니요¹ | — | Google OAuth 클라이언트 비밀 |
| 아니요² | 자동 생성 | 32바이트 base64 자격 증명 암호화 키 |
| 아니요 |
|
|
| 아니요 |
|
|
| 아니요 |
| 키, OAuth 클라이언트, 자격 증명 |
| 아니요 |
| HTTP 바인드 주소 |
| 아니요 |
| HTTP 바인드 포트 |
| 아니요 |
| HTTP 전송을 설정으로 활성화 |
| 아니요 |
| 루프백이 아닌 바인드 허용 |
| 아니요 |
|
|
¹ secrets/oauth_client.json의 대안입니다. 파일 또는 쌍을 제공하세요.
² 설정하지 않으면 게이트웨이가 첫 실행 시 secrets/master.key (모드 0600)를 생성합니다.
환경 변수는 config.toml을 재정의하고, 이는 기본값을 재정의합니다.
각 값 생성
OAuth 클라이언트 ID와 비밀 — 빠른 시작 2단계에서 다운로드한 JSON에서 가져옵니다. 파일 대신 환경 변수를 사용하려면:
jq -r '.installed.client_id' ~/Downloads/client_secret_*.json
jq -r '.installed.client_secret' ~/Downloads/client_secret_*.json마스터 키 — 32바이트 랜덤, base64:
openssl rand -base64 32
# or, without openssl:
python3 -c "import base64,secrets; print(base64.b64encode(secrets.token_bytes(32)).decode())"이 키는 저장된 갱신 토큰을 복호화합니다. 계정을 추가한 후 키를 변경하면 자격 증명을 읽을 수 없게 되며 모든 계정에
accounts reauth가 필요합니다. 데이터 디렉토리를 백업하는 곳과 함께 백업하세요.
게이트웨이 베어러 토큰 — 환경 변수가 아닙니다. MCP 클라이언트가 HTTP 전송을 통해 보내는 것이며, Google 자격 증명과는 관련이 없습니다. CLI가 이를 생성하고 SHA-256 해시만 저장합니다:
gmail-mcp-gateway token create my-agent평문은 한 번 출력되며 클라이언트 구성에 들어갑니다.
.env 파일 사용
게이트웨이는 .env를 자동으로 읽지 않습니다 — 보안 도구는 시작된 디렉터리에서 자동으로 비밀을 흡수해서는 안 됩니다. 모든 변수를 문서화한 .env.example을 복사하고 명시적으로 로드하세요:
cp .env.example .env # already covered by .gitignore
$EDITOR .env
set -a && source .env && set +a
gmail-mcp-gateway healthsystemd는 EnvironmentFile=을 사용하고, Docker Compose는 env_file:을 사용합니다.
실행
stdio — 일반적인 선택
클라이언트가 게이트웨이를 하위 프로세스로 시작하고 파이프를 통해 통신합니다. 포트, 토큰, 네트워크 노출이 없습니다. Google 자격 증명은 게이트웨이 프로세스 내에 남아 있으며, 클라이언트는 도구 호출만 볼 수 있습니다.
gmail-mcp-gateway serve --transport stdio수동으로 실행하면 멈춘 것처럼 보일 수 있습니다 — 정상입니다. stdin에서 JSON-RPC를 기다리고 있습니다. 일반적으로 MCP 클라이언트가 자동으로 시작합니다.
Streamable HTTP — 독립 실행형 서비스
장기 실행 서비스나 프로세스를 생성할 수 없는 클라이언트를 위해.
gmail-mcp-gateway token create my-agent # once; save the printed token
gmail-mcp-gateway serve --transport http --host 127.0.0.1 --port 8765엔드포인트는 프백에 바인드되며 베어러 토큰이 필요하고 DNS 리바인딩 보호가 활성화됩니다. GET /healthz는 인증 없이 작동하며 활성 상태만 보고합니다.
루프백이 아닌 주소를 바인드하려면 GMAIL_MCP_ALLOW_REMOTE_BIND=true가 필요하며, 인터넷 라우팅 가능한 주소는 그렇더래도 거부됩니다. 원격 클라이언트의 경유 널:
ssh -L 8765:127.0.0.1:8765 gateway-hostsystemd
deploy/gmail-mcp-gateway.service는 강화된 샌드박스에서 전용 시스템 사용자로 실행됩니다 — ProtectSystem=strict, 빈 CapailityBoundingSet, seccom 필터, 데이터 디렉토리에 NoExecPaths. 설칠 단계는 유닛트의 헤더에 있습니다. 서비스 사용자로 한 번, 대화식으로 계정을 인증한 후 시작하세요.
Docker
deploy/Dockerfile과 deploy/docker-compose.yml는 트 트 및 읽기 전용으로 실행되며, 모든 기느이 해제되며, 포트는 프백에만 게시됩니다. 이미지에는 자격 증명이 없으며 /secrets 볼륨에 있습니다.
docker compose -f deploy/docker-compose.yml up -d일회성 인증 시퀀스 — OAuth 클라이언트 배치, 리다이렉트 포트가 게시된 상태에서 동의 흐름 실행, 토큰 발행 — 은 Compose 파일 헤더 주석에 있습니다.
MCP 클라이언트 연결
stdio
{
"mcpServers": {
"gmail": {
"command": "/absolute/path/to/gmail-mcp-gateway/.venv/bin/gmail-mcp-gateway",
"args": ["serve", "--transport", "stdio"]
}
}
}Claude Code:
claude mcp add gmail -- /absolute/path/to/.venv/bin/gmail-mcp-gateway serve --transport stdioHTTP
{
"mcpServers": {
"gmail": {
"type": "http",
"url": "http://127.0.0.1:8765/mcp",
"headers": { "Authorization": "Bearer <token from `token create`>" }
}
}
}클라이언트는 Google 자격 증명 파일을 마운트하거나 그렇게 접근하지 않습니다. stdio에서는 클라이언트가 파이프와 통신하고, HTTP에서는 Google 자격 증명과 관런이 없은 게이트웨이 토큰을 보관합니다.
도구 참조
모든 도구는 account 별칭을 받사용합니다 — 기본 게정이 없습니디. 변이 도구는 선택적인client_request_id를 받아 일원성을 확보합니다: 동일한 id와 인수로 호출을 반복하면 두 번 작동하는 대신 첫 번째 결고를 반환합니다.
도구 | 기능 | ||||||||||||||||||||||||||||||||||||||||||||||
| 별칭, 주소, 상태, 부여된 기능. 자격 증명 없음. | ||||||||||||||||||||||||||||||||||||||||||||||
| 계정별 실시간 인증 확인 및 사서할 총계. | ||||||||||||||||||||||||||||||||||||||||||||||
| Gmail 검색 문법; |
| 하나의 메시지: 보낸이, 받는이, 찬거, 숨은찬거, 제무, 타임스탬무, 레이뷸, 읽음 상타, 온문, 첨부 화일 재고. |
| 대화 전체를 참여참 순서로, 참여와 함께. |
| 첨부 화일 재고. 다운로드 하지 않음. |
| 바이트 가저오기: 작을 때인라인 base64, 크면 게이트웨이 자체 디렉토리저장. |
| 모든 레잴과 개수, 및 게이트웨이가 각각을 수정할 지 여부. |
| ID나 이름으로 레잴 적용. |
| ID나 이름으로 레잴 제거. |
|
|
|
|
|
|
| 저장된 임시 보관함 (받는 사람, 제목, 미리 보기). |
| 하나의 임시 보관함 전체. |
| 새 텍스트 전용 임시 보관함. 저장됨, 전송 안 함. |
| 기존 스레드의 답장 임시 보관함, 올바른 |
| 임시 보관함 편집; 생략된 필드는 값 유지, 스레딩 보존. |
변는 개별 메시지나 스레드, 그고 배취(기본 100개 ID 제한)에서 작용합니다. 레잴은 ID(Label_7)나 화면 표시 이름(Receipts)으로 지전할 수 있습니디.
읽과 쓰는 필요한 곳에서 비대칭으로 처됩됩니다: gmail_search는 TRASH로 필터링하거나 include_spam_trash를 설장할 수 있습니디. 이는 이 있것을 검사하는 것이 읽기 작업이기 때움입니다. 그 레잴을 적용하는 거부되며, 메일을 시통로 이돌하거나 스팸으로 신고할 수 있기 때움입니다.
오류
실패는 isErr: true와 텍트 블록 및 구조화된 콘텐트트에 구조화된 페이로드가 있는 MCP 도구 오류로 반환됩니다:
{"error": {
"code": "forbidden_label",
"message": "refusing to add label 'TRASH': moving messages to Trash is a forbidden capability of this gateway",
"retryable": false
}}코드에는 invalid_input, unknown_account, not_found, too_large, batch_too_large, rate_limited, forbidden_operation, forbidden_label, account_read_only, needs_reauth, upstream_rate_limited, upstream_unavailble, network_error, timeout, 및 internal_error가 포함됩니다. 내부 예외는 서버 측에 로깅되고 단순한 internal_error로 보고됩니다 — 클라이언트는 추적이나 내부 경로를 절대 받지 않습니다.
관리
gmail-mcp-gateway accounts list
gmail-mcp-gateway accounts status # live Gmail check per account
gmail-mcp-gateway accounts auth <alias>
gmail-mcp-gateway accounts reauth <alias> # after a revoked or expired grant
gmail-mcp-gateway accounts remove <alias> --yes # revokes at Google, deletes locally
gmail-mcp-gateway token create <name>
gmail-mcp-gateway token list
gmail-mcp-gateway token revoke <name>
gmail-mcp-gateway audit --limit 50 # recent state-changing operations
gmail-mcp-gateway audit --account work --since-hours 24
gmail-mcp-gateway audit --outcome denied --json
gmail-mcp-gateway prune # expired audit rows, dedup keys, attachments
gmail-mcp-gateway health --json헤드리스 호스트에서는 리디렉션 포트를 포워딩하여 인증합니다:
# on the server
gmail-mcp-gateway accounts add work --no-browser --port 8899
# on your laptop
ssh -L 8899:127.0.0.1:8899 server
# then open the printed URL locally감사 로그는 성공, 실패, 거부 모두에 대해 계정, 타임스탬프, 작업, 영향받은 ID, 결과, 오류 코드, 지속 시간 및 호출 주체를 기록합니다. 토큰, 메시지 본문, 제목 또는 첨부 파일 내용은 절대 기록하지 않습니다. 관리는 CLI 전용입니다: 손상된 MCP 클라이언트는 계정을 추가하거나, 동의 흐름을 트리거하거나, 토큰을 발급하거나, 감사 로그를 읽을 수 없습니다.
디렉터리 구조
구성, 데이터, 비밀은 분리되어 있으며 각각 별도로 재정의할 수 있으므로 각각 다른 백업 저장소를 가질 수 있습니다:
역할 | 변수 | 기본값 | 내용 |
구성 |
|
|
|
데이터 |
|
|
|
비밀 |
|
|
|
config.toml은 선택 사항입니다. 모든 키(배치 상한, 페이지 크기, 본문 및 첨부 파일 예산, 속도 제한, 재시도 정책, 멱등성 창)와 기본값은
deploy/config.example.toml을 참조하세요.
경계가 어떻게 강제되는지
네 개의 독립적인 계층. 각각 하나만으로도 전송을 차단할 수 있으며, 메시지가 나가려면 네 계층 모두가 실패해야 합니다.
1. 도구 표면. 18개의 도구가 존재합니다. gmail_send, gmail_trash, gmail_raw_request는 없으며, URL, 경로, HTTP 메서드 또는 엔드포인트 이름을 허용하는 도구도 없습니다. 일반적인 Gmail 프록시는 작성되지 않았기 때문에 클라이언트가 접근할 수 없습니다.
mcpsrv/server.py
2. 엔드포인트 허용 목록. Gmail에 대한 모든 HTTP 요청은 14개의 Endpoint 상수 중 하나를 지정해야 합니다. users.messages.send, users.drafts.send, users.messages.trash, users.messages.delete 및 users.settings 아래의 모든 것은 단순히 존재하지 않습니다. 경로 매개변수는 엄격한 ID 패턴에 대해 검증되고 빈 안전 집합으로 퍼센트 인코딩되므로 어떤 값도 /를 도입하여 다른 엔드포인트에 도달할 수 없습니다. 차단 목록은 요청이 나가기 직전에 확인된 메서드와 경로를 다시 확인하며, 이는 요청이 어떻게 구성되었는지와 무관합니다. DELETE 및 PATCH는 전혀 발행할 수 없습니다.
gmail/allowlist.py
3. 레이블 정책. 이는 허용 목록이 남겨둔 뒷문을 닫습니다. users.messages.modify는 허용됩니다(보관 및 읽음 상태를 처리하는 방식입니다). 그러나 Gmail은 TRASH와 SPAM을 일반 레이블로 취급하므로, 이를 적용하면 메시지가 휴지통으로 이동되거나 스팸으로 신고됩니다. 변경 사항의 모든 레이블 ID는 양방향으로 대소문자를 구분하지 않고 확인되며, 조립된 요청 본문은 전송 전에 다시 확인됩니다.
gmail/labels.py
4. OAuth 범위. 계정은 gmail.modify로만 인증되며 다른 것은 없습니다. 이 범위는 메시지를 영구 삭제할 수 없으며(messages.delete는 https://mail.google.com/ 필요), Gmail 설정을 전혀 건드릴 수 없으므로 전달 규칙, 필터, POP/IMAP 구성 및 영구 삭제는 여기서 단순히 차단되는 것이 아니라 Google의 인증 계층에서 불가능합니다. Google은 전송 없이 초안 작성을 허용하는 범위를 게시하지 않으므로 전송은 대신 계층 1-2에서 차단됩니다. --read-only로 추가된 계정은 gmail.readonly를 받으며, Google 자체가 모든 쓰기를 거부합니다.
보안 모델
이메일 콘텐츠는 신뢰할 수 없습니다. 본문, 제목, 발신자 이름 및 첨부 파일 이름은 제3자가 작성하며, 이를 읽는 모델을 대상으로 한 명령을 포함할 수 있습니다. 게이트웨이는 모든 읽기 결과에 content_is_untrusted: true를 표시하며, 서버 지침은 클라이언트에게 이메일을 지시가 아닌 데이터로 취급하도록 지시합니다. 더 유용하게는, 주입된 명령이 요청할 기능이 존재하지 않습니다.
HTML은 절대 실행되지 않으며 마크업으로 반환되지 않습니다. <script>, <style>, <iframe> 및 유사한 요소는 내용과 함께 폐기됩니다. 다른 모든 태그는 제거됩니다. 결과는 일반 텍스트입니다.
보이지 않는 유니코드는 제거됩니다. 너비가 0인 문자, 양방향 재정의 및 유니코드 태그 문자는 공격자가 사람에게는 한 가지를 보여주고 LLM은 다른 것을 읽게 할 수 있습니다. 이들은 제거되며 개수는 removed_hidden_characters로 보고됩니다.
첨부 파일은 저장되며 열리지 않습니다. 게이트웨이는 첨부 파일 내용을 구문 분석, 렌더링 또는 실행하지 않습니다. 클라이언트는 파일 이름을 제안할 수 있지만 경로는 절대 제안할 수 없습니다. 대상은 항상 <attachments_dir>/<account>/<message_id>/<sanitized-name>이며, 포함 여부가 확인되고 재확인되며, O_NOFOLLOW로 모드 0600으로 기록됩니다.
자격 증명이 클라이언트에 도달하지 않습니다. 갱신 토큰, 액세스 토큰 및 OAuth 클라이언트 비밀은 게이트웨이 프로세스 내에만 존재합니다. 각 계정의 자격 증명은 계정별로 파생된 키(HKDF-SHA256(master, "…account:<id>"))로 AES-256-GCM으로 봉인되며, 계정 ID가 연결된 데이터로 사용됩니다. 따라서 한 계정의 키로 다른 계정을 열 수 없으며, 계정 간에 이동된 자격 증명 파일은 복호화에 실패합니다. 파일은 0700 디렉터리 내에서 0600이며, 게이트웨이는 그룹 또는 전역 읽기 가능 키를 읽지 않습니다.
정직한 범위: 저장 시 암호화는 백업, 우연한 복사본 및 디스크 이미지로부터 보호합니다. 게이트웨이 사용자로 코드를 이미 실행하고 있는 공격자로부터는 방어하지 않습니다. 해당 공격자는 마스터 키를 읽을 수 있습니다. 파일 시스템 권한이 여전히 주요 경계입니다.
로그는 비밀을 유출할 수 없습니다. 모든 로그 레코드는 Google 액세스 또는 갱신 토큰, 클라이언트 비밀, Bearer 헤더, JWT 또는 자격 증명 이름의 필드처럼 보이는 모든 것을 메시지, 인수 및 예외 텍스트에서 다시 쓰는 필터를 거칩니다. stdio에서는 로그가 stderr로 이동합니다. stdout은 MCP 와이어이기 때문입니다.
입력이 검증됩니다. 초안 수신자는 엄격한 패턴과 일치하는 bare 주소여야 합니다. 헤더 값의 CR, LF 또는 NUL은 헤더 주입 시도로 거부됩니다. 초안은 형식화된 필드에서 조립됩니다. 게이트웨이는 클라이언트로부터 원시 RFC 5322를 절대 허용하지 않습니다. 배치, 페이지 크기, 본문 길이, 첨부 파일 크기 및 수신자 수는 모두 제한되며, 계정별 토큰 버킷은 대기열에 넣지 않고 retry_after_seconds 힌트와 함께 빠르게 실패합니다.
이것이 보호하지 않는 것
게이트웨이 사용자로 코드를 실행할 수 있는 운영자.
허용된 기능을 나쁘게 사용하는 합법적인 클라이언트(예: 대량 보관, 오해의 소지가 있는 초안 작성). 보관 및 레이블 지정은 되돌릴 수 있고 감사됩니다. 초안은 여전히 사람이 보내야 합니다.
Google 측의 손상 또는 악의적인 OAuth 클라이언트 구성.
TLS 없이 HTTP 전송을 노출하는 경우 트래픽 가로채기. 루프백에서 유지하거나 앞에 TLS 종료 프록시를 두십시오.
신뢰성
토큰 갱신: 자동이며, 계정별 잠금으로 동시 호출이 한 번만 갱신됩니다.
401은 정확히 한 번의 갱신 및 재시도를 트리거합니다.갱신 실패:
invalid_grant는 계정을needs_reauth로 표시하고 이를 수정할 CLI 명령을 명명하는 구조화된 오류를 반환합니다.속도 제한 및 5xx: 전체 지터가 있는 지수 백오프,
Retry-After준수, 최대max_attempts까지.네트워크 오류 및 시간 초과: 재시도 후 내부 세부 정보 없이
network_error또는timeout으로 보고됩니다.페이지 매김:
next_page_token이 클라이언트에 반환되므로 서버에 커서 상태가 남지 않습니다.중복 요청:
client_request_id는 24시간 동안 반복을 억제합니다. 동시 반복은 프로세스 내에서 직렬화됩니다. 다른 인수로 ID를 재사용하면 오류가 발생하며, 조용히 잘못된 답변을 반환하지 않습니다.역압력: Gmail 호출은 구성 가능한 동시성 세마포어를 공유하며, 각 계정에는 독립적인 토큰 버킷이 있습니다. 따라서 대규모 검색이나 바쁜 계정이 무제한 업스트림 동시성을 생성할 수 없습니다.
확장 및 배포 토폴로지
주어진 데이터 및 비밀 디렉터리에 대해 하나의 게이트웨이 프로세스를 실행합니다. SQLite 상태, 자격 증명 파일, 토큰 갱신 잠금 및 진행 중인 멱등성 조정은 의도적으로 로컬입니다. 여러 복제본을 동일한 볼륨으로 지정하는 것은 안전한 액티브-액티브 작동을 제공하지 않습니다.
더 큰 설치의 경우, 각각 자체 구성, 데이터, 비밀, Bearer 토큰 및 루프백 포트를 가진 독립적인 게이트웨이 인스턴스에 계정을 샤딩합니다. 이렇게 하면 오류, 속도 제한, 감사 추적 및 자격 증명이 격리되면서도 각 인스턴스가 동시 클라이언트를 처리할 수 있습니다. Gmail 할당량 사용량과 호스트 용량을 관찰한 후에만 limits.max_concurrency를 늘리십시오. 기본값 8은 보수적입니다. 클라이언트가 하나의 공유 네트워크 주소를 필요로 하는 경우 앞에 TLS 인증 라우팅 계층을 두고 각 계정 별칭을 자체 인스턴스로 라우팅하십시오.
동일한 계정에 대한 액티브-액티브 복제본은 SQLite 및 로컬 자격 증명/멱등성 상태를 조정된 외부 저장소로 대체해야 합니다. 이는 현재 게이트웨이의 보안 모델 범위를 벗어납니다. 단순히 작업자를 추가하거나 볼륨을 공유하여 확장하지 마십시오.
테스트
uv sync --all-extras
uv run pytest -q # 334 tests, no Google account needed
uv run pytest tests/test_security_boundary.py -v # just the guaranteetest_security_boundary.py는 금지된 URL이 요청되면 실패하는 모의 Gmail을 통해 모든 지원되는 작업을 구동한 다음, 사용 가능한 모든 경로를 통해 휴지통, 스팸 및 전송을 시도합니다.
계정이 인증되면 실제 사서함에 대해 테스트합니다. 스크립트는 MCP 클라이언트가 정확히 하는 것처럼 stdio를 통해 연결하고, 읽기 전용 둘러보기를 실행한 다음 금지된 작업이 거부되는지 확인합니다:
uv run python scripts/try-it.py --account personal
uv run python scripts/try-it.py --account personal --draft # also drafts a reply
uv run python scripts/try-it.py --account personal --archive # archive round trip변경 플래그를 전달하지 않으면 읽기 전용이며, 수행하는 모든 변경은 되돌릴 수 있습니다. 생성하는 초안은 사용자가 삭제해야 합니다. 게이트웨이는 할 수 없습니다.
대화형으로 둘러보려면:
npx @modelcontextprotocol/inspector .venv/bin/gmail-mcp-gateway serve --transport stdio레이아웃
src/gmail_mcp_gateway/
├── mcpsrv/server.py the tool surface — the complete client-facing API
├── mcpsrv/http.py Streamable HTTP transport, bearer auth, bind safety
├── service.py the supported operations, and nothing else
├── gmail/allowlist.py the endpoint allowlist ← security boundary
├── gmail/labels.py label policy (blocks TRASH/SPAM) ← security boundary
├── gmail/client.py the only code that talks to Gmail
├── gmail/parse.py MIME → structured data, sanitization
├── gmail/compose.py draft assembly from typed fields
├── security/ validation, rate limiting, path confinement
├── auth/oauth.py OAuth 2.0 + PKCE, refresh, revoke
├── accounts.py account registry
├── crypto.py envelope encryption for credentials
├── audit.py audit log
└── cli.py administration지원되는 작업을 추가한다는 것은: allowlist.py의 Endpoint, service.py의 메서드, mcpsrv/server.py의 도구, EXPOSED_TOOLS의 항목 및 테스트를 의미합니다. EXPOSED_TOOLS와 FORBIDDEN_TOOLS는 실행 중인 서버에 대해 단언되므로, 도구를 선언하지 않고 추가하거나 금지된 도구를 추가하면 테스트 스위트가 실패합니다. 게이트웨이를 Gmail에 집중시키십시오. 다른 Google 제품은 더 넓은 범위가 아닌 별도의 MCP 서비스에 속합니다.
문제 해결
no OAuth client configured — 빠른 시작 3단계. secrets/oauth_client.json(모드 0600)을 배치하거나 GMAIL_MCP_OAUTH_CLIENT_ID 및 GMAIL_MCP_OAUTH_CLIENT_SECRET을 설정하십시오.
Google did not return a refresh token — 이 앱을 이전에 인증한 적이 있습니다. https://myaccount.google.com/permissions에서 액세스를 제거하고 accounts auth <alias>를 다시 실행하십시오.
consent screen did not grant every required permission — 권한 상자가 선택 해제되었습니다. 인증을 다시 실행하고 모두 선택된 상태로 두십시오. 게이트웨이는 반쯤 작동하는 계정을 남기지 않기 위해 의도적으로 여기서 실패합니다.
계정이 매주 needs_reauth가 됨 — OAuth 앱이 여전히 "테스트" 상태이며, Google은 7일 후에 갱신 토큰을 만료시킵니다. 앱을 게시하십시오(빠른 시작 2.4단계).
stored credential failed authentication — GMAIL_MCP_MASTER_KEY가 변경되었거나 키 파일이 교체되었습니다. 원래 키를 복원하거나 각 계정에 대해 accounts reauth <alias>를 실행하십시오.
<file> is accessible to other users — 게이트웨이는 그룹 또는 전역 읽기 가능 비밀을 읽지 않습니다. 해당 파일에 chmod 600을 실행하십시오.
refusing to bind …: it is not a loopback address — 의도적입니다. 127.0.0.1에 바인딩하고 SSH 터널을 사용하거나, 정말 신뢰할 수 있는 사설 인터페이스인 경우 GMAIL_MCP_ALLOW_REMOTE_BIND=true를 설정하십시오. 인터넷 라우팅 가능 주소는 관계없이 거부됩니다.
serve --transport stdio가 멈춘 것처럼 보임 — 맞습니다. stdin에서 JSON-RPC를 기다리고 있습니다. MCP 클라이언트가 실행하도록 하거나 scripts/try-it.py를 사용하십시오.
사서함에 무언가 변경이 있었고, 그 내용을 알고 싶습니다 —
gmail-mcp-gateway audit --limit 50. 모든 상태 변경 사항이 여기에 있으며, 거부된 요청도 포함됩니다.
라이선스
MIT
This server cannot be installed
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
- Alicense-qualityAmaintenanceAn open-source MCP server that provides AI agents with secure access to read, search, and manage emails via Microsoft 365 and Gmail. It features security-first defaults like recipient allowlists and markdown content conversion to facilitate safe agent interaction with mailboxes.4Apache 2.0
- Alicense-qualityBmaintenanceRead-only MCP server for IMAP email access, enabling AI agents to read, search, and monitor email without sending or deleting messages.47MIT
- AlicenseCqualityCmaintenanceMulti-account Gmail MCP server that lets assistants scan inbox, read threads, draft and send emails only after human approval, and manage follow-up reminders.4268MIT
- Flicense-qualityDmaintenanceEnables AI agents to interact with Gmail through a standardized MCP server interface, allowing for natural language email management and automation.
Related MCP Connectors
Hosted email MCP for AI agents with inboxes, send/receive, memory, recovery, and credits.
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/systheno/gmail-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server