Skip to content

RobinGase/gmail-skill

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

gmail-skill

CI License: MIT OR Apache-2.0

A Claude Code skill for Gmail OAuth, search, draft, send, and fetch. Drop the repo into ~/.claude/skills/gmail/, build the bundled Rust CLI once, run a one-time OAuth flow against your own Google client, and Claude can:

  • Send email (gmail-skill send --to ... --subject ... --body ...).
  • Draft email for later review.
  • Search the inbox with full Gmail query syntax.
  • Fetch the full body of any message by id.
  • Send a draft by id.

It is also installable as a stand-alone CLI for use outside Claude Code.

Install

As a Claude Code skill

git clone https://github.com/RobinGase/gmail-skill ~/.claude/skills/gmail
cd ~/.claude/skills/gmail/cli
cargo build --release

As a stand-alone CLI

cargo install --git https://github.com/RobinGase/gmail-skill gmail-skill --bin gmail-skill

Configure

You provide your own Google OAuth credentials. The skill never ships them.

  1. Open https://console.cloud.google.com/apis/credentials.

  2. Enable the Gmail API for the project.

  3. Create credentials → OAuth client ID → application type Desktop app.

  4. Add http://127.0.0.1:9876/callback as an authorized redirect URI.

  5. Export the client id + secret:

    export GMAIL_OAUTH_CLIENT_ID="xxxx.apps.googleusercontent.com"
    export GMAIL_OAUTH_CLIENT_SECRET="GOCSPX-..."
Variable Required Purpose
GMAIL_OAUTH_CLIENT_ID (or GOOGLE_OAUTH_CLIENT_ID) yes OAuth client ID.
GMAIL_OAUTH_CLIENT_SECRET (or GOOGLE_OAUTH_CLIENT_SECRET) yes OAuth client secret.
GMAIL_OAUTH_REDIRECT_URI no Defaults to http://127.0.0.1:9876/callback.
GMAIL_OAUTH_STORE_PATH no Where tokens are saved. Default: platform data dir (%APPDATA%\gmail-skill\ on Windows, ~/.local/share/gmail-skill/ on Linux).
GMAIL_API_BASE_URL no Override for testing. Default https://gmail.googleapis.com/gmail/v1.
SKILL_WORKSPACE_ROOT no Root for resolving relative attachment paths. Default: cwd.

OAuth flow

gmail-skill connect          # default: spawns loopback listener on 127.0.0.1:9876
gmail-skill status           # verify

For headless servers:

gmail-skill connect --manual                   # prints URL, exits
# (open URL in a browser, copy the `code` query param from the redirect)
gmail-skill complete --code <auth-code>

Use

gmail-skill status

gmail-skill search --query "from:foo@bar.com newer_than:7d" --limit 5
gmail-skill fetch --id 18b7e9d2c4a56789

gmail-skill send \
  --to alice@example.com \
  --subject "Quick update" \
  --body "Hi,\n\nQuick note...\n\nThanks." \
  --attachment data/leads.csv

gmail-skill draft --to alice@example.com --subject "..." --body "..."
gmail-skill send-draft --id <draft-id>

gmail-skill disconnect       # clear stored tokens

JSON-stdin mode for orchestrators:

echo '{"command":"run","operation":"send","args":{"to":["a@b.c"],"subject":"hi","body":"hi"}}' \
  | gmail-skill --json-stdin

How it works

  • OAuth: Installed-app PKCE flow against accounts.google.com/o/oauth2/v2/auth and oauth2.googleapis.com/token. State + code-verifier are stored in a gmail_pending.json file alongside the token store; --manual mode persists pending state so complete can finish the exchange.
  • Token refresh: On every API call the access token is checked for expiry (60 s skew). If expired and a refresh token is present, it's refreshed automatically and re-saved.
  • RFC 822 builder: Plain-text bodies stay single-part. With attachments, the message becomes multipart/mixed with one binary part per attachment, base64-encoded with the standard 76-char line-wrap.
  • Body decoding (fetch): Walks the MIME tree, prefers text/plain, falls back to a stripped-tag text/html, then to Gmail's snippet.

What the skill is not

  • Not a multi-account manager. The token store is single-account.
  • Not a label/filter/rule editor. Send/draft/search/fetch only.
  • Not a webhook receiver. It's a one-shot CLI; orchestrators poll via search.

Migration from KaizenMAX

The token store path search includes data/oauth/gmail_tokens.json and ../data/oauth/gmail_tokens.json (KaizenMAX's location) as low-priority fallbacks. Run gmail-skill from inside a KaizenMAX workspace and your existing tokens are discovered automatically. Or set GMAIL_OAUTH_STORE_PATH explicitly.

Development

cd cli
cargo build --release
cargo test
cargo clippy --all-targets -- -D warnings
cargo fmt --all

Rust 2024 edition (MSRV 1.88).

License

Dual-licensed under either of:

at your option. Contributions are accepted under the same dual licence unless noted otherwise.

About

Claude Code skill: Gmail OAuth + search + draft + send + fetch via the Google Gmail API. Drop into ~/.claude/skills/gmail/

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages