
Gmail Skill
Let your agent search, read, send, label, and archive Gmail across multiple OAuth accounts from a Python CLI skill.
Overview
Gmail Skill is an agent skill most often used in Build (also Grow, Operate) that reads, searches, sends, and manages Gmail and contacts via a multi-account OAuth Python CLI.
Install
npx skills add https://github.com/idanbeck/claude-skills --skill gmail-skillWhat is this skill?
- CLI subcommands: search, read, list, labels, send, mark-read, mark-done, contacts, accounts, logout
- Multi-account Gmail with browser OAuth flow and per-account scoping flags
- Contact search and Google contacts access alongside mailbox operations
- Mark-done archives messages (Gmail archive shortcut behavior)
- Email body wrapping at 72 characters for readable agent output
- Email output wrapped at 72 characters for readability
- Ten primary CLI operation groups documented in the module header
Adoption & trust: 715 installs on skills.sh; 12 GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You need your agent to act on real email threads—search, read, reply, archive—without building a custom Gmail integration from scratch.
Who is it for?
Indie builders who live in Gmail for support or sales and want scripted, account-scoped agent access with OAuth login.
Skip if: Teams needing Microsoft 365 mail, bulk cold-email automation without human review, or no-Google-workspace environments.
When should I use this skill?
User needs to read, search, send, label, archive Gmail, manage multiple Gmail accounts via OAuth, or query Google contacts from an agent.
What do I get? / Deliverables
You run documented Python commands to query mail, mutate labels/archive state, send messages, and list or search contacts per authenticated account.
- Retrieved or sent Gmail messages per command
- Updated read/archive state on message IDs
- Contact search results and authenticated account listings
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Primary shelf is Build integrations because the skill is a concrete Gmail API bridge you wire into agent workflows. Subphase integrations reflects OAuth multi-account setup and command-style email operations—not marketing lifecycle strategy.
Where it fits
Authenticate two founder inboxes and expose search/read commands to your support agent prototype.
Search for a customer thread, read the latest message, and draft a reply payload before you approve send.
Mark operational alert threads done and archive them after an incident is resolved.
List labels and pull recent conversations to seed a weekly user feedback summary.
How it compares
Python Gmail integration skill—not an MCP server package or a visual inbox client like Superhuman.
Common Questions / FAQ
Who is gmail-skill for?
Solo builders and tiny teams who want agents to query and act on Gmail and contacts through a documented Python CLI with multi-account OAuth.
When should I use gmail-skill?
During Build when wiring email into agent workflows; during Grow support or lifecycle outreach; during Operate when archiving or marking done on operational threads.
Is gmail-skill safe to install?
Review the Security Audits panel on this page; sending mail and OAuth tokens are sensitive—use least-privilege Google scopes and never commit credentials.
SKILL.md
READMESKILL.md - Gmail Skill
#!/usr/bin/env python3 """ Gmail Skill - Read, search, send, and manage Gmail emails. Access Google contacts. Supports multiple accounts with seamless OAuth browser flow. Usage: python gmail_skill.py search "query" [--account EMAIL] python gmail_skill.py read EMAIL_ID [--account EMAIL] python gmail_skill.py list [--account EMAIL] python gmail_skill.py labels [--account EMAIL] python gmail_skill.py send --to EMAIL --subject "..." --body "..." [--account EMAIL] python gmail_skill.py mark-read EMAIL_ID [--account EMAIL] python gmail_skill.py mark-done EMAIL_ID [--account EMAIL] # Archive (Gmail 'e') python gmail_skill.py contacts [--account EMAIL] python gmail_skill.py search-contacts "query" [--account EMAIL] python gmail_skill.py accounts # List authenticated accounts python gmail_skill.py logout [--account EMAIL] # Remove account """ import argparse import base64 import hashlib import json import os import re import sys import textwrap import webbrowser from datetime import datetime from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from http.server import HTTPServer, BaseHTTPRequestHandler from pathlib import Path from typing import Optional from urllib.parse import urlencode, parse_qs, urlparse import threading import secrets # Email line width for readability (matches Superhuman style) EMAIL_LINE_WIDTH = 72 # Check for required libraries try: from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from googleapiclient.discovery import build from googleapiclient.errors import HttpError import requests except ImportError: print("Error: Required libraries not installed.") print("Install with: pip install google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client requests") sys.exit(1) # Paths SKILL_DIR = Path(__file__).parent TOKENS_DIR = SKILL_DIR / "tokens" CREDENTIALS_FILE = SKILL_DIR / "credentials.json" ACCOUNTS_META_FILE = SKILL_DIR / "accounts.json" # Scopes - includes send and modify capabilities SCOPES = [ "https://www.googleapis.com/auth/gmail.readonly", "https://www.googleapis.com/auth/gmail.send", # For sending (REQUIRES USER CONFIRMATION) "https://www.googleapis.com/auth/gmail.modify", # For mark-read, archive, etc. "https://www.googleapis.com/auth/contacts.readonly", "https://www.googleapis.com/auth/contacts.other.readonly", "https://www.googleapis.com/auth/userinfo.email", # To get email address ] # Google OAuth endpoints GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth" GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token" GOOGLE_USERINFO_URL = "https://www.googleapis.com/oauth2/v2/userinfo" # Default OAuth client - user can override with their own credentials.json # This is a "Desktop app" type client, where the secret is not truly secret DEFAULT_CLIENT_CONFIG = { "installed": { "client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com", "client_secret": "YOUR_CLIENT_SECRET", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "redirect_uris": ["http://localhost"] } } def get_client_config() -> dict: """Load OAuth client configuration.""" if CREDENTIALS_FILE.exists(): with open(CREDENTIALS_FILE) as f: return json.load(f) # Check if default config has been configured if DEFAULT_CLIENT_CONFIG["installed"]["client_id"].startswith("YOUR_"): print("\n" + "="*60) print("FIRST-TIME SETUP REQUIRED") print("="*60) print("\nTo use Gmail Reader, you need to create a Google Cloud OAuth client.") print("This is a one-time setup that takes ~2 minutes:\n") print("1. Go to: https://console.cloud.google.com/apis/credentials") print("2. Create a project (or select existing)") p