google-gmail
The `google-gmail` skill wraps the Gmail v1 API to read, search, send, reply, forward, draft, label, and triage Gmail messages directly from the terminal. Use it when you need structured, JSON-formatted email operations that compose cleanly with shell tools like `jq`, provided `gws` is installed, authenticated, and granted the appropriate OAuth scopes (gmail.readonly for read-only, gmail.send for sending, gmail.modify for replies and drafts).
git clone --depth 1 https://github.com/Lilac-Labs/gini-agent /tmp/google-gmail && cp -r /tmp/google-gmail/skills/google/google-gmail ~/.claude/skills/google-gmailSKILL.md
# Google Gmail Use `gws gmail` to read, search, send, reply, forward, draft, label, and triage Gmail directly from the terminal. The CLI wraps the Gmail v1 API and produces structured JSON, so it composes cleanly with `jq` and other shell tooling. ## Prerequisites - `gws` installed and authenticated. If `gws` is not on PATH OR `gws auth status` reports no authenticated user, do NOT silently call setup. Instead, in a single short reply to the user: 1. State plainly what's missing — e.g. "Google Workspace access isn't set up on this machine yet" or "your Google sign-in has expired." 2. Ask one sentence: "Want me to walk you through setting it up?" Wait for the user's answer. 3. If they say yes, call `read_skill` with name `google-workspace-setup` and run that skill's onboarding flow turn-by-turn. If they say no or ask to defer, acknowledge briefly and stop — do not retry the original request. - Apply the same flow when any `gws gmail ...` call fails mid-task with `command not found` / ENOENT, HTTP 401, "no credentials", or "scope required". Don't report the failure as a dead end — surface the missing prerequisite and ask if the user wants to set it up before moving on. - The OAuth scopes the user picked at login must cover the verbs the agent will use: - Read-only triage: `gmail.readonly` - Send a new message: `gmail.send` - Reply, reply-all, forward: `gmail.modify` — upstream helpers fetch the original message to thread `In-Reply-To` / `References` headers, which `gmail.send` alone cannot do - Drafts and labels: `gmail.modify` (or `https://mail.google.com/` for full access including permanent delete) - Watch for new mail (`+watch`): `gmail.modify` AND `https://www.googleapis.com/auth/pubsub` — Cloud Pub/Sub is a separate Google API and its scope must be granted alongside the Gmail scope ## Selecting a Google account The connected Google accounts (each with its tag, email, and config dir) are listed in your system context under **"Connected Google accounts"**. To target a specific account, prefix the command with its config dir: ```bash GOOGLE_WORKSPACE_CLI_CONFIG_DIR="<configDir>" gws gmail +triage ``` Selection rule: one account connected → just use it. Two or more: - The user named or clearly implied one account (a tag, an email, or unambiguous context) → use only that account. - A read/lookup/search the user didn't tie to an account (e.g. listing events, searching mail, finding a doc) → run it against **every** connected account (one `gws` call per config dir) and aggregate, labeling each result by its tag and email. Don't pick just one, and don't ask — the user wants the whole picture across accounts. - A write (send, create, edit, delete) with no account named → ASK which account first; never guess. If no accounts are connected yet, fall back to the setup flow in Prerequisites (`read_skill` with `google-workspace-setup`). ## When to Use - The user asks Gini to send, draft, read, search, label, reply to, or forward email. - Summarizing or triaging the inbox (latest unread, by-sender, by-label digests). - Saving an attachment from a thread, or pulling a message body into another workflow. - Watching for new messages and streaming them as NDJSON (`gws gmail +watch`). ## When NOT to Use - Agent-internal scratch notes or transient state — use the `memory` tool, not email-to-self. - Personal to-dos that should appear on the user's iPhone — use `apple-reminders`. - Cross-device personal note-taking — use `apple-notes` or `obsidian`. - Calendar invites and meeting scheduling — use `google-calendar` (a Gmail invite is still a Calendar event). - Bulk outbound mail (newsletters, marketing) — personal Gmail has aggressive sending limits and Google will throttle or suspend the account. Tell the user to use a transactional provider. ## Quick Reference The Gmail surface in `gws` is split into auto-generated API methods (`gws gmail users messages list`, `gws gmail users labels create`, …) plus a small set of curated helpers (`+send`, `+reply`, `+read`, `+triage`, …) that handle MIME encoding, threading, and base64 for you. Prefer the helpers for everyday tasks. The raw API is rooted at the `users` resource — every `--params` JSON must include `"userId": "me"` (or another delegated address). ### Send ```bash gws gmail +send --to alice@example.com --subject 'Hello' --body 'Hi Alice!' # CC, BCC, alias send-from gws gmail +send --to alice@example.com --cc bob@example.com \ --subject 'Status' --body 'See below.' --from alias@example.com # Attachments (repeatable, 25 MB total) gws gmail +send --to alice@example.com --subject 'Report' \ --body 'See attached.' -a report.pdf -a notes.txt # HTML body gws gmail +send --to alice@example.com --subject 'Update' \ --body '<b>Bold</b> text' --html # Save as draft instead of sending gws gmail +send --to alice@example.com --subject 'Draft' --body 'WIP' --draft ``` ### Show a saved draft to the user After you save a draft (`--draft`), show it to the user inline so they can read it right in the chat — never tell them to open Gmail and search for it. Lead with one short sentence, then render the draft as a fenced `email-draft` block: optional `To:` / `Cc:` / `Subject:` header lines, a blank line, then the exact body you saved. ````text I drafted this reply for you: ```email-draft To: support@plaud.ai Subject: Follow-up on your Request #527545 Hi there, I still haven't received the package, and the delivery photo shows it was left inside a publicly accessible gate. Could you reopen the case and coordinate a replacement or refund? Thanks ``` ```` Use the same recipient, subject, and body you passed to `gws gmail +send … --draft` so the card matches the saved draft. The app renders the `email-draft` block as a draft card; any non-rendering client degrades it to a readable code block. ### Read ```bash gws gmail +read --id <MESSAGE_ID> # plain-text body gws gmail +read --id <MESSAGE_ID> --headers # inc
Delegate coding work to Claude Code CLI for repository edits, reviews, and multi-turn implementation sessions.
Delegate coding work to the OpenAI Codex CLI for repository changes, reviews, and focused fixes.
Gini's self-knowledge: how Gini configures, extends, and operates on its own state via /api/* and registered tools. Load when the user asks Gini about its own capabilities or asks Gini to modify its own configuration.
Manage Apple Notes via memo CLI: create, search, edit.
Apple Reminders via remindctl: add, list, complete.
Move bytes between Gini upload space, external URLs, and workspace files. Used by every attachment / file-upload / file-download flow regardless of the target system (Linear, GitHub, S3, Notion, etc.).
File a locally-captured, already-redacted Gini crash report as a GitHub issue, with the user's consent. Reads the pending crash queue and delegates the actual filing to the github-issues skill.
Create, search, triage, label, assign, comment on, and close GitHub issues using the gh CLI, with a curl REST fallback.