npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@arvoretech/gmail-mcp

v1.0.0

Published

Gmail MCP Server — read, send, and manage Gmail messages via OAuth user flow

Readme

@arvoretech/gmail-mcp

MCP server for Gmail — read, send, and manage messages from your AI assistant. OAuth user flow (no service account required).

Tools

| Tool | Description | | ----------------- | -------------------------------------------------------------------- | | messages_list | List messages with Gmail search syntax (from:, is:unread, etc.) | | messages_get | Get a message with parsed headers and body | | threads_get | Get an entire email thread end-to-end | | drafts_list | List existing drafts | | drafts_create | Create a draft (always available, even when sending is disabled) | | drafts_send | Send an existing draft (requires GMAIL_MCP_ALLOW_SEND=true) | | messages_send | Send an email immediately (requires GMAIL_MCP_ALLOW_SEND=true) | | messages_modify | Add/remove labels (mark read, archive, star, etc.) | | messages_trash | Move a message to trash | | labels_list | List system + user labels | | profile_get | Get the authenticated user's profile |

Reply threading: messages_send and drafts_create accept replyToMessageId and automatically populate In-Reply-To, References, and threadId so replies show up correctly in Gmail.

Setup

1. Create OAuth Client in Google Cloud Console

  1. Open the Cloud Console
  2. Select or create a project
  3. Enable the Gmail API
  4. Open OAuth consent screen:
    • User type: External
    • Add yourself under Test users (required while the app is in testing mode)
  5. Open CredentialsCreate CredentialsOAuth client ID:
    • Application type: Desktop app
    • Save the client_id and client_secret

2. Authorize

export GMAIL_MCP_CLIENT_ID="your-client-id"
export GMAIL_MCP_CLIENT_SECRET="your-client-secret"

npx @arvoretech/gmail-mcp auth login

This opens your browser, you sign in and approve scopes, and the MCP captures the refresh token. Credentials are encrypted at rest (AES-256-GCM) with the key stored in:

  • macOS: the system keychain (security utility)
  • Other platforms: a file at ~/.config/arvoretech-gmail-mcp/.encryption_key (mode 0600)

3. Use as MCP server

Add to your MCP client config (Kiro, Claude Desktop, Cursor, etc.):

{
  "mcpServers": {
    "gmail": {
      "command": "npx",
      "args": ["-y", "@arvoretech/gmail-mcp"],
      "env": {
        "GMAIL_MCP_CLIENT_ID": "your-client-id",
        "GMAIL_MCP_CLIENT_SECRET": "your-client-secret",
        "GMAIL_MCP_ALLOW_SEND": "false"
      }
    }
  }
}

By default the MCP runs in read + draft modemessages_send and drafts_send are not registered. Set GMAIL_MCP_ALLOW_SEND=true only when you trust the agent to send mail without human review.

Subcommands

| Command | Description | | ------------------------- | ---------------------------------------- | | gmail-mcp auth login | Browser-based OAuth flow | | gmail-mcp auth logout | Revoke refresh token and clear credentials | | gmail-mcp auth status | Print current auth status | | gmail-mcp (no args) | Run as MCP stdio server |

Environment Variables

| Variable | Required | Description | | ------------------------------ | -------- | ---------------------------------------------------------------------- | | GMAIL_MCP_CLIENT_ID | Yes | OAuth client ID from Google Cloud Console | | GMAIL_MCP_CLIENT_SECRET | Yes | OAuth client secret | | GMAIL_MCP_ALLOW_SEND | No | Set to true to enable messages_send and drafts_send tools | | GMAIL_MCP_REFRESH_TOKEN | No | Bypass the token store and use a refresh token directly (CI / Docker) | | GMAIL_MCP_CONFIG_DIR | No | Override config directory (default: ~/.config/arvoretech-gmail-mcp) | | GMAIL_MCP_REDIRECT_PORT | No | Force a specific port for the OAuth callback (default: random) | | GMAIL_MCP_LOGIN_HINT | No | Pre-fill the email address in the consent screen |

OAuth Scopes

The MCP requests these scopes (well within Google's 25-scope limit for unverified apps):

  • https://www.googleapis.com/auth/gmail.readonly — read messages and labels
  • https://www.googleapis.com/auth/gmail.send — send mail
  • https://www.googleapis.com/auth/gmail.modify — modify labels (mark read, archive, star, trash)
  • https://www.googleapis.com/auth/gmail.compose — create drafts

To grant fewer permissions, edit DEFAULT_SCOPES in src/oauth.ts before auth login and re-authorize.

Headless / CI usage

For environments without a browser or keychain (Docker, EKS, GitHub Actions):

  1. Run gmail-mcp auth login once on a machine with a browser.
  2. Read the refresh token from the saved credentials and pass it through:
export GMAIL_MCP_CLIENT_ID="..."
export GMAIL_MCP_CLIENT_SECRET="..."
export GMAIL_MCP_REFRESH_TOKEN="ya29..."
gmail-mcp

When GMAIL_MCP_REFRESH_TOKEN is set, the disk store is bypassed entirely.

Development

pnpm install
pnpm build
pnpm test
pnpm lint

Security notes

  • Refresh tokens are long-lived. Treat them like passwords.
  • The encryption key never leaves your machine — it lives in the macOS keychain or a 0600 file.
  • messages_send is gated behind GMAIL_MCP_ALLOW_SEND so an agent can't send mail unless you opt in.
  • Always prefer drafts_create for AI-generated emails — humans review before sending.

License

MIT