Gmail MCP
Provides tools to manage Gmail, including sending mail, managing drafts, labels, archiving, marking read/unread, starring, and trashing emails.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Gmail MCPCan you draft an email to Jessica about the meeting tomorrow?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Gmail MCP
Private multi-account Gmail MCP server for Codex.
Development
Open this repository through Remote SSH and choose Dev Containers: Reopen in
Container. The container exposes only this repository, runs as the unprivileged
vscode user, and uses a repository-specific Codex home on the VM.
Its sole Docker security override relaxes seccomp because the real Codex
workspace sandbox was verified to require nested user namespaces on this VM.
No capabilities, privileged mode, AppArmor override, or Docker socket are used.
The central development image provides Python, uv, Codex, and generic build
tools. Project dependencies are installed from the checked-in uv.lock into
this repository's ignored .venv. The devcontainer creates that environment
automatically and keeps it isolated from every other repository and worktree.
The project commands are:
uv lock --check
uv sync --frozen --group dev
uv run --frozen pytest
uv run --frozen flake8 src tests
uv buildThe first time this repository is opened, authenticate its isolated Codex state
with the primary development ChatGPT account by running codex login in the
container. Do not put API keys in the devcontainer configuration.
Related MCP server: gmail-mcp
Google Cloud configuration
This server accesses each Gmail account with a user-authorized OAuth 2.0 Web application client. It does not use an API key or a service account. Complete these steps in the Google Cloud console before starting the server.
Create and select a project. Use a dedicated project for this server; keeping development and production projects separate makes it less likely that test credentials or consent-screen settings leak into production.
Enable the Gmail API. Open APIs & Services > Library, search for Gmail API, select it, and click Enable. The OAuth client cannot request Gmail scopes until this API is enabled.
Configure the OAuth consent screen. Open Google Auth platform and complete the setup screens (the first visit may show Get started):
On Branding, provide an accurate application name, a user-support email address, and developer contact email. Do not use Google trademarks or a Google product logo in the app name or logo.
On Audience, choose Internal only when every account is in the same Google Workspace organization. Otherwise choose External. For a private personal or development deployment, leave an External app in Testing and add every Gmail account to Test users.
On Data Access, use Add or remove scopes and add the scopes this service requests:
https://www.googleapis.com/auth/gmail.modify https://www.googleapis.com/auth/gmail.compose https://www.googleapis.com/auth/gmail.sendThe service requests these by default; retain the same list if you set
GOOGLE_OAUTH_SCOPESyourself.gmail.modifypermits reading and changing mailbox state,gmail.composemanages drafts and sending, andgmail.sendpermits sending. Do not add broader scopes such ashttps://mail.google.com/unless the code is deliberately changed to need them.
Create the OAuth client. Open Google Auth platform > Clients, click Create client, choose Web application, and give it a descriptive name such as
gmail-mcp-local.Under Authorized redirect URIs, add exactly:
http://localhost:8080/admin/oauth/callbackNo Authorized JavaScript origin is needed for this server-side flow. The value in Google Cloud must exactly equal
GOOGLE_REDIRECT_URI, including its scheme, host, port, path, case, and trailing slash. Aredirect_uri_mismatcherror means those values differ.httpis permitted forlocalhostduring local development. For any non-localhost hostname, use a domain you control and an HTTPS callback endpoint (normally behind a TLS reverse proxy); do not register a raw LAN IP address as the callback. Add that same HTTPS URL both here and inGOOGLE_REDIRECT_URI.Copy the client ID and client secret. After creating the client, copy its values from the client details page. Treat the secret as a password: keep it out of Git, the repository, shell history, and screenshots. You will place the values in the VM-only secrets file in the next section.
Testing versus production
The Gmail scopes above are sensitive or restricted. For an External app in Testing, Google allows only the Gmail addresses listed as test users and their authorizations (including offline refresh tokens) expire after seven days; re-run the account authorization flow when that happens. This is the simplest path for a private deployment.
To authorize arbitrary external users without the testing limit, publish the app and complete Google's OAuth verification. Restricted scopes can require scope justification, a demo video, and—when restricted data is stored on or transmitted through servers—a security assessment. An Internal Workspace app does not require public OAuth verification, but its Workspace administrator may still need to allow the app's Gmail access. Review Google's Gmail scope classifications, app audience guidance, and verification requirements before publishing.
LAN deployment and account authorization
The server may run on a LAN VM while the browser and Codex client run on a different computer. Do not expose the unencrypted Docker port to an untrusted network: both the admin token and MCP bearer token are credentials.
Choose one of these deployment models:
SSH tunnel (recommended for a private deployment): no DNS, certificate, or application changes. The service stays on the LAN VM, while the Windows workstation reaches it securely as
localhostthrough SSH. This is the simplest way to use the normal Google OAuth flow.LAN HTTPS endpoint: use this when multiple clients must reach the service directly. Use a domain that you control, LAN DNS, a TLS reverse proxy, and a publicly trusted certificate obtained with DNS-01. This is also required if Google OAuth must redirect directly to the LAN endpoint rather than through an SSH tunnel.
Option 1: Windows SSH tunnel (recommended)
This option does not move the service to the Windows PC. It securely
forwards the Windows PC's localhost:8080 to the VM's localhost:8080. Google
therefore sees the allowed http://localhost callback, and the VM receives the
callback over the tunnel.
On the VM, keep the standard localhost callback in both Google Cloud and
~/.config/dev-secrets/gmail_mcp.env:GOOGLE_REDIRECT_URI=http://localhost:8080/admin/oauth/callbackStart the service on the VM as described in Quick Start. The current Compose configuration publishes port 8080 on the VM, which also makes it reachable at the VM's loopback address for SSH forwarding.
On the Windows workstation, open PowerShell or Windows Terminal. Verify the built-in OpenSSH client is available:
ssh -VIf the command is unavailable, install OpenSSH Client from Settings > System > Optional features. Do not install or configure an SSH server on Windows for this workflow; Windows is the SSH client and the LAN VM is the SSH server. See Microsoft's OpenSSH overview if the optional feature is managed by your organization.
Create the tunnel. Replace the placeholder with the SSH user and LAN DNS name or private IP address of the VM:
ssh -N -o ExitOnForwardFailure=yes -L 127.0.0.1:8080:127.0.0.1:8080 <vm-user>@<vm-host-or-ip>Keep this terminal open.
-Nopens no remote shell, and binding the local side to127.0.0.1prevents other LAN devices from using the tunnel.If TCP port 8080 is already in use on Windows, use a different local port, such as
18080, in the command and change the registered callback andGOOGLE_REDIRECT_URItohttp://localhost:18080/admin/oauth/callback.In a second PowerShell window, confirm that the tunnel reaches the service:
curl.exe http://127.0.0.1:8080/healthComplete account authorization in a browser on the Windows workstation:
http://localhost:8080/admin/oauth/start?alias=personal&token=<ADMIN_TOKEN>Google redirects the browser to
localhost; SSH delivers that request to the VM, which exchanges the authorization code and stores the refresh token. The tunnel need only be present whenever an account is added or reauthorized.To keep normal MCP traffic encrypted without setting up LAN TLS, leave the tunnel running and add the MCP server from Windows PowerShell:
$env:MCP_BEARER_TOKEN = "<same MCP_BEARER_TOKEN from the VM secrets file>" codex mcp add gmail --url http://localhost:8080/mcp --bearer-token-env-var MCP_BEARER_TOKEN$env:sets the token for the current PowerShell session only. Do not usesetxfor this secret. Stop the tunnel withCtrl+Cwhen it is no longer needed.
Option 2: Direct LAN HTTPS endpoint
Use this model only when clients must reach the server without an SSH tunnel.
Google requires a non-localhost OAuth callback to use HTTPS and a domain name;
do not register a raw LAN IP address or an internal-only suffix such as
.local.
Choose a domain that you control, for example
gmail-mcp.example.com. Configure LAN (split-horizon) DNS so that name resolves to the VM's private IP address for every client that will use it.Put a TLS reverse proxy such as Caddy on the VM. Obtain a publicly trusted certificate using the DNS-01 challenge through your DNS provider's API. The challenge proves control of the DNS name with a TXT record, so the VM does not need to accept connections from the public internet. Caddy needs the DNS provider module for the provider you use; follow that provider module's installation guidance. See Caddy's automatic HTTPS and
tlsdirective documentation.A representative Caddyfile (shown with Cloudflare's DNS module) is:
gmail-mcp.example.com { tls { dns cloudflare {env.CLOUDFLARE_API_TOKEN} } reverse_proxy 127.0.0.1:8080 }Keep Caddy's DNS API token outside this repository. If Caddy runs on the VM host, bind the Compose application port to loopback so the unencrypted backend cannot bypass Caddy:
ports: - "127.0.0.1:8080:8080"Alternatively, enforce the same restriction with the VM firewall: permit LAN TCP/443 to Caddy and deny LAN TCP/8080. Caddy terminates TLS; the loopback connection from Caddy to this application is plain HTTP.
Register this exact redirect URI in Google Cloud and set the same value in the VM secrets file:
GOOGLE_REDIRECT_URI=https://gmail-mcp.example.com/admin/oauth/callback MCP_ALLOWED_HOSTS=gmail-mcp.example.com,gmail-mcp.example.com:443Restart the application after changing its environment, and reload Caddy after changing its configuration.
Authorize an account and connect Codex using the HTTPS hostname:
https://gmail-mcp.example.com/admin/oauth/start?alias=personal&token=<ADMIN_TOKEN>$env:MCP_BEARER_TOKEN = "<same MCP_BEARER_TOKEN from the VM secrets file>" codex mcp add gmail --url https://gmail-mcp.example.com/mcp --bearer-token-env-var MCP_BEARER_TOKENMCP_ALLOWED_ORIGINSremains empty for a native Codex client. Set it only when intentionally allowing a browser-based MCP client, and restrict it to the exact browser origin or origins.
Authorization alternatives
The standard OAuth flow above is the only supported path in this repository for personal Gmail accounts and the server's full feature set (mailbox access, labels, drafts, and sending). A Gmail API key cannot access private mailbox data, and a standalone service account does not have a personal Gmail mailbox.
A Google Workspace service account with domain-wide delegation can avoid per-user consent screens, but only a Workspace super administrator can grant it and the application must be changed to impersonate each mailbox. It is not configured by this project and gives the service broad administrative authority.
Google Workspace SMTP relay can send mail based on the server's allowed IP address, but it cannot read mail or manage Gmail labels and drafts. It would require a send-only redesign.
IMAP/SMTP app passwords are static credentials with account and policy restrictions. They do not work with the current Gmail API implementation and would also require a redesign. Do not put an account password in this service.
Quick Start
For a Windows workstation connecting to a LAN VM, follow either deployment
option above when completing steps 5 and 6. The localhost URLs below are the
default for a browser and Codex running on the same machine as the service.
Complete the Google Cloud configuration and record the OAuth client ID and secret.
Generate the remaining server secrets:
uv run --frozen python - <<'PY'
from cryptography.fernet import Fernet
import secrets
print("GMAIL_MCP_ENCRYPTION_KEY=" + Fernet.generate_key().decode())
print("ADMIN_TOKEN=" + secrets.token_urlsafe(32))
print("MCP_BEARER_TOKEN=" + secrets.token_urlsafe(32))
PYOn the VM (not inside the dev container), create
~/.config/dev-secrets/gmail_mcp.envfrom.env.example. SetGOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET, andGOOGLE_REDIRECT_URIfrom the Google Cloud steps, then add the generated values. Set mode0600.Start the server with command-scoped secret injection:
./scripts/dev-compose up --buildAdd accounts through the admin OAuth flow. Use a browser that can reach the callback URL registered in Google Cloud, then sign in as a listed test user (or an allowed Internal/verified user):
http://localhost:8080/admin/oauth/start?alias=personal&token=<ADMIN_TOKEN>Connect Codex:
export MCP_BEARER_TOKEN="<same token>"
codex mcp add gmail --url http://localhost:8080/mcp --bearer-token-env-var MCP_BEARER_TOKENRequired Environment
GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGOOGLE_REDIRECT_URIGMAIL_MCP_ENCRYPTION_KEYADMIN_TOKENMCP_BEARER_TOKEN
Optional:
DATABASE_URL, defaultsqlite:////data/gmail_mcp.sqlite3MCP_ALLOWED_HOSTS, comma-separated, defaultlocalhost,localhost:*,127.0.0.1,127.0.0.1:*MCP_ALLOWED_ORIGINS, comma-separated, default emptyLOG_LEVEL, defaultINFO
Safety Model
Draft creation happens immediately. Sending mail, sending drafts, label changes, archive, mark read/unread, star/unstar, and trash create pending actions first. A caller must execute gmail_pending_action_confirm with the returned pending_action_id before Gmail state changes.
The committed .env.example is a variable-name contract only. Real values stay
outside Git and are passed to Docker Compose only for the command being run.
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 Connectors
Read, search, send, organize, draft and schedule email across your inboxes from any MCP client.
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Email inboxes for AI agents: send, receive, reply, search, and manage threaded email over MCP.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables interaction with Gmail through the MCP protocol, supporting sending, reading, searching, replying, forwarding, managing drafts and labels, and saving attachments.153MIT
- FlicenseNot gradedqualityCmaintenanceEnables interacting with multiple Gmail accounts through a single MCP server, supporting search, labels, drafts, and thread management with per-account OAuth.
- AlicenseNot gradedqualityDmaintenanceEnables Gmail operations such as reading, sending, searching, and managing emails, threads, labels, and drafts via MCP tools.1MIT
- FlicenseNot gradedqualityCmaintenanceEnables searching, reading, and drafting emails across multiple Gmail accounts through a single MCP server.
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/pyrodie18/gmail_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server