Free SKILL.md scraped from GitHub. Clone the repo or copy the file directly into your Claude Code skills directory.
npx versuz@latest install vivekkarmarkar-claude-code-os-skills-emailgit clone https://github.com/VivekKarmarkar/claude-code-os.gitcp claude-code-os/SKILL.MD ~/.claude/skills/vivekkarmarkar-claude-code-os-skills-email/SKILL.md---
name: email
description: Send emails via Gmail using the GWS CLI. Use this skill whenever the user wants to send an email, reply to an email, forward an email, draft an email, or says things like "email them", "send a message to", "reply to that", "shoot them an email", "let them know via email", "write back to", "follow up with", or references composing any kind of email. Also triggers on "/email". This skill handles both fresh emails and replies, inferring as much as possible from conversation context so the user doesn't have to spell everything out.
---
# Email — Send via Gmail (GWS CLI)
You send emails through the user's Gmail account using the `gws` CLI directly. Your job is to be genuinely helpful — figure out as much as you can from context and JUST SEND IT. No drafts, no confirmations, no asking "ready to send?"
## Philosophy
The whole point of this skill is ZERO friction. The user says "email X about Y" and the email gets sent. Period. No drafts shown, no confirmation asked, no back-and-forth. Infer everything you can from conversation context and common sense.
## Sender
The sender is always: `vivekkmk.assistant@gmail.com`
If you need to verify, run:
```bash
gws gmail users getProfile --params '{"userId": "me"}'
```
## Workflow
### Step 1: Figure out what's happening
Read the conversation context carefully. Determine:
- **Fresh email or reply?** If there's a recent email visible in the conversation (from a Gmail lookup, or the user said "reply to that"), it's a reply. Otherwise it's fresh.
- **Who's the recipient?** Check conversation context for names, email addresses, or references ("email Adi back", "tell the AgentMail guy"). If you looked up emails earlier in the session, use those From/Reply-To addresses.
- **What's the content?** The user might give you the gist ("say I'm interested"), a detailed message, or just a vague intent ("follow up"). For vague intents, draft something reasonable based on context.
- **Subject line?** For replies, use "Re: [original subject]". For fresh emails, infer from the content.
### Step 2: Fill in gaps (only if you must)
Only ask the user if you genuinely cannot figure out:
- The recipient's email address (if no email is visible anywhere in context)
- The core intent of the message (if it's truly ambiguous)
Do NOT ask about:
- Subject lines (infer them)
- Formatting preferences (just write it well)
- Sign-off style (keep it natural and casual unless context suggests formality)
- CC/BCC (unless the user mentioned others who should be included)
- Confirmation to send — NEVER ask "ready to send?" Just send it.
### Step 3: Encode and send immediately
**Do NOT show a draft. Do NOT ask for confirmation. Just send.**
**For a fresh email:**
```bash
RAW=$(python3 ~/.claude/skills/email/scripts/encode_email.py \
--from "vivekkmk.assistant@gmail.com" \
--to "recipient@example.com" \
--subject "Subject here" \
--body "Email body here") && \
gws gmail users messages send --params '{"userId": "me"}' --json "{\"raw\": \"$RAW\"}"
```
**For a reply** (need thread ID and Message-Id from the original):
```bash
RAW=$(python3 ~/.claude/skills/email/scripts/encode_email.py \
--from "vivekkmk.assistant@gmail.com" \
--to "recipient@example.com" \
--subject "Re: Original subject" \
--body "Reply body here" \
--in-reply-to "<original-message-id>" \
--references "<original-message-id>") && \
gws gmail users messages send --params '{"userId": "me"}' --json "{\"raw\": \"$RAW\", \"threadId\": \"<original-thread-id>\"}"
```
### Step 4: Report delivery
After sending, briefly confirm: "Sent to X" with the message ID. Keep it short. If it fails, explain the error and suggest fixes.
## Fetching emails for reply context
If the user says "reply to that email" but you haven't seen the email content yet, fetch it:
```bash
gws gmail users messages list --params '{"userId": "me", "maxResults": 5}'
gws gmail users messages get --params '{"userId": "me", "id": "<msg-id>", "format": "full"}'
```
Extract: From, Reply-To (prefer Reply-To if present), Subject, Message-Id header, threadId, and the body text.
## Writing style
- Match the formality of the context. Replying to a newsletter pitch? Casual. Replying to a professor? More formal.
- Keep it concise. Nobody likes a wall of text in email.
- Don't add flowery language the user didn't ask for. "I'm interested in learning more" beats "I would be absolutely delighted and honored to explore the wonderful opportunity."
- Use the user's first name (Vivek) as the sign-off name unless context suggests otherwise.
## HTML emails
If the user asks for a formatted/rich email, use the `--html` flag:
```bash
RAW=$(python3 ~/.claude/skills/email/scripts/encode_email.py \
--from "vivekkmk.assistant@gmail.com" \
--to "recipient@example.com" \
--subject "Subject" \
--body "Plain text fallback" \
--html "<h2>Rich version</h2><p>With formatting</p>") && \
gws gmail users messages send --params '{"userId": "me"}' --json "{\"raw\": \"$RAW\"}"
```
## Troubleshooting
- **"Access denied / No credentials"**: GWS auth is expired. User needs to run `gws auth login` in their terminal.
- **"Scope error"**: The `gws` CLI may need updating: `npm update -g @googleworkspace/cli`
- **Send fails with 400**: Usually a malformed `raw` field. Re-run the encode script and check the output.
- **"Delegation denied"**: The Gmail account may not have the send scope authorized. Re-run `gws auth login` with the full scope set.