Skip to content

enw/gmail-access-skill

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

gmail-access

A Claude Code skill that reads Gmail using Chrome's cached session cookies — no OAuth setup required.

How It Works

Chrome stores Google session cookies in a local SQLite database, encrypted with a key from the macOS Keychain. This skill:

  1. Reads the Chrome cookies database at ~/Library/Application Support/Google/Chrome/Default/Cookies
  2. Decrypts cookie values using the Chrome Safe Storage key from macOS Keychain
  3. Authenticates to Gmail's Atom feed (mail.google.com/mail/feed/atom/) using those cookies
  4. Parses and returns unread messages

No OAuth flow. No API key. No app registration. Just reuses credentials Chrome already has.

Requirements

  • macOS (tested on macOS 15+)
  • Google Chrome with Gmail logged in
  • Python 3.8+
  • pycryptodome library
pip install pycryptodome
# If that fails (Python 3.12+ externally managed):
pip install pycryptodome --break-system-packages

Usage

Command Line

# List 5 most recent unread messages (default account)
python3 ~/.claude/skills/gmail-access/gmail_unread.py

# For second Google account in Chrome
python3 ~/.claude/skills/gmail-access/gmail_unread.py 1

As a Library

from gmail_unread import get_google_cookies, fetch_unread

cookies = get_google_cookies()
messages = fetch_unread(cookies, account=0, max_results=5)

for msg in messages:
    print(f"{msg['from_name']} <{msg['from_email']}>: {msg['subject']}")

From Claude

Ask Claude to read your Gmail:

"Check my Gmail for unread messages" "What's in my inbox?" "Do I have any unread emails?"

Claude will invoke the gmail-access skill automatically.

Output Example

=== 5 Most Recent Unread Messages ===

1. GitHub <noreply@github.com>
   Subject: [repo] PR #42 merged
   Preview: Your pull request was merged into main.

2. Stripe <receipts@stripe.com>
   Subject: Your receipt from March 5
   Preview: Thanks for your payment of $29.00...

Troubleshooting

Problem Solution
Chrome Safe Storage key not found Open Chrome and ensure you're logged into Gmail
No Google cookies found Log into Gmail in Chrome, then retry
401 Auth failed / no messages Cookies may be expired — visit Gmail in Chrome to refresh
Database is locked Chrome may be running. Try quitting Chrome first, or it may work anyway (WAL mode)
ImportError: No module named 'Crypto' Run pip install pycryptodome
Could not decrypt cookie Chrome may have updated its format. See docs/chrome-encryption.md

Files

gmail-access/
  SKILL.md              # Claude skill metadata and quick reference
  gmail_unread.py       # Main script (also importable as a library)
  README.md             # This file
  docs/
    chrome-encryption.md  # Chrome cookie encryption format (deep dive)
    gmail-atom-feed.md    # Gmail Atom feed API reference

Technical Notes

Chrome Encryption (Chrome 127+ on macOS)

Chrome 145 (and likely 127+) uses a new format on macOS:

[v10][32-byte metadata][AES-128-CBC encrypted value]

Older Chrome used:

[v10][AES-128-CBC encrypted value]

The script handles both formats by trying both offsets. See docs/chrome-encryption.md for a full breakdown including how this was discovered.

Gmail Atom Feed vs REST API

The Atom feed (/mail/feed/atom/) is used instead of the Gmail REST API (googleapis.com/gmail/v1/) because:

  • REST API requires OAuth2 Bearer tokens (not available from cookie cache)
  • Atom feed accepts browser session cookies directly
  • Atom feed supports Gmail search operators via the q parameter

See docs/gmail-atom-feed.md for full Atom feed documentation including search operators and response format.

Security

  • Cookies are read-only; the script never modifies browser data
  • The temp copy of the cookies DB is deleted immediately after reading
  • Cookies are sent only to mail.google.com over HTTPS
  • The Chrome Safe Storage key is accessed via security find-generic-password, which may prompt for Keychain access

Limitations

  • macOS + Chrome only — relies on macOS Keychain and Chrome's specific storage format
  • Read-only — cannot send mail, archive, or modify messages via the Atom feed
  • Unread only (by default) — change q=is:unread to search other messages
  • No full body — Atom feed provides a ~200-char summary, not the complete email
  • Cookies must be valid — if you've been logged out of Gmail in Chrome, re-login first

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages