Skip to main content
Glama

gmail-mcp

A minimal Model Context Protocol server for one Gmail account, served over stdio. It gives an MCP client such as Claude Code the ability to search, read, label, draft and send mail using your own Google OAuth client.

Why

Google's hosted Gmail MCP endpoint only accepts a pre-registered OAuth client and rejects dynamic client registration, so generic MCP clients cannot connect to it directly. This server sidesteps that by talking to the Gmail API itself with a Desktop-app OAuth client that you create in your own Google Cloud project. No third party sits between the client and your mailbox.

Related MCP server: Gmail Local MCP

Scope and safety

The server requests a single scope, gmail.modify: read, label, draft and send. It cannot permanently delete mail, and nothing in the tool surface bypasses Trash.

gmail.modify is the narrowest scope that covers marking read and archiving, since both are label mutations. It also includes sending, so the scope alone is not the safety boundary. The tool surface is, and sending is deliberately split in two:

  • create_draft writes to Drafts and sends nothing. Prefer it.

  • send_message delivers immediately and is irreversible.

Pin send_message to an "ask" rule in your MCP client so it prompts on every call regardless of the session's permission mode. In Claude Code that is a line in .claude/settings.local.json of the project where the server is registered:

{
  "permissions": {
    "ask": ["mcp__gmail__send_message"]
  }
}

The tool name prefix is mcp__<server name>__, so adjust it to whatever name you register the server under.

Tools

Tool

Effect

search_threads

Gmail-syntax search; returns sender, subject, date, snippet

get_message

One message in full, including plain-text body

list_labels

Label list

create_draft

Save to Drafts. Sends nothing. Threads replies via replyToMessageId

send_message

Sends. Irreversible. Pin to an ask rule

mark_read / mark_unread

Add or remove UNREAD, batched

archive / unarchive

Add or remove INBOX, batched. Reversible; deletes nothing

Files

File

Purpose

server.js

The MCP server

auth.js

One-time OAuth consent flow; writes the token file

config.js

File locations and scope, overridable through environment variables

credentials.json

OAuth client from Google Cloud Console. Gitignored, never commit it

token.json

Refresh token, written with mode 600. Gitignored, never commit it

Setup

Requires Node.js 20 or newer.

  1. In Google Cloud Console, signed in as the Google account you want to expose: create a project and enable the Gmail API.

  2. Configure the OAuth consent screen as External and add that same account as a test user.

  3. Create an OAuth client ID of type Desktop app and download its JSON to credentials.json in this directory.

  4. Install dependencies and run the consent flow:

    npm install
    npm run auth

    A browser opens on the Google consent screen. When it finishes, the script prints which account the token belongs to. Set GMAIL_MCP_ACCOUNT to the expected address if you want a warning when the wrong account was used.

  5. Register the server with your MCP client. For Claude Code, from the project where you want it available:

    claude mcp add gmail -- node /absolute/path/to/gmail-mcp/server.js

Configuration

Everything defaults to files next to the code. Override with environment variables when the server runs from elsewhere or when several accounts share one checkout.

Variable

Default

Meaning

GMAIL_MCP_CREDENTIALS

./credentials.json

Path to the OAuth client JSON

GMAIL_MCP_TOKEN

./token.json

Path where the refresh token is stored

GMAIL_MCP_ACCOUNT

unset

Expected address; auth.js warns if the token belongs to another account

To change the scope, edit SCOPES in config.js and re-run npm run auth. An existing token keeps its old scopes, and API calls fail with insufficient authentication scopes until it is reissued.

Notes

  • Staying in OAuth "Testing" status is fine for personal use; no Google verification is needed. Refresh tokens for unverified apps expire after 7 days of disuse, so re-run npm run auth if calls start failing with invalid_grant.

  • credentials.json and token.json are secrets. They are gitignored here, but treat any copy of them like a password.

License

MIT. See LICENSE.

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    Multi-account Google MCP server providing read access to Gmail and Calendar via stdio. Supports secure authentication for personal and work accounts with OAuth and keychain token storage.
    4
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Local stdio MCP server that mirrors the public Gmail MCP server tool surface while calling the Gmail REST API directly, enabling email management tasks like creating drafts, searching threads, and managing labels.
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides MCP clients with safe local access to read, search, and send Gmail messages using token-efficient outputs and explicit permissions.
    -
  • A
    license
    A
    quality
    C
    maintenance
    A minimal MCP server for sending plain-text emails and managing Gmail user labels over stdio, using only gmail.send and gmail.labels OAuth scopes.
    4
    141 npm
    MIT