atrislabs/atris/email-agent

Claude Code and agent skill by atrislabs/atris

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Gmail integration via AtrisOS API. Read, send, archive emails. Use when user asks about email, inbox, or wants to send/check messages.

Install

npx vskill@latest install atrislabs/atris/email-agent

SKILL.md

Email Agent

Drop this in ~/.claude/skills/email-agent/SKILL.md and Claude Code becomes your email assistant.

choosing a google account

Run atris google accounts to see connected accounts and defaults. Use atris google connect [name] for one sign-in, and add --only mail,calendar,drive to choose products. Use atris google use <name-or-email> to save a default, or add --business <slug> to choose the account for a business. Use atris google disconnect <name-or-email> --approved to disconnect after confirmation, with --only to remove selected products.

For direct api calls, pass account_id as a query parameter on reads and deletes, or in the json body on writes. Pass the business id or slug in the X-Business-Id header when working for a business. Calendar reads without an account include all accounts; account_id=all also requests all calendars. Calendar writes need one account. The old sign-in and api examples below still work on older servers.

Bootstrap (ALWAYS Run First)

Before any email operation, run this bootstrap to ensure everything is set up:

bash
#!/bin/bash
set -e
# 1. Check if atris CLI is installed
if ! command -v atris &> /dev/null; then
echo "Installing atris CLI..."
npm install -g atris
fi
# 2. Check if logged in to AtrisOS
if [ ! -f ~/.atris/credentials.json ]; then
echo "Not logged in to AtrisOS."
echo ""
echo "Option 1 (interactive): Run 'atris login' and follow prompts"
echo "Option 2 (non-interactive): Get token from https://atris.ai/auth/cli"
echo " Then run: atris login --token YOUR_TOKEN"
echo ""
exit 1
fi
# 3. Extract token (try node first, then python3, then jq)
if command -v node &> /dev/null; then
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
elif command -v python3 &> /dev/null; then
TOKEN=$(python3 -c "import json,os; print(json.load(open(os.path.expanduser('~/.atris/credentials.json')))['token'])")
elif command -v jq &> /dev/null; then
TOKEN=$(jq -r '.token' ~/.atris/credentials.json)
else
echo "Error: Need node, python3, or jq to read credentials"
exit 1
fi
# 4. Check Gmail connection status (also validates token)
STATUS=$(curl -s "https://api.atris.ai/api/integrations/gmail/status" \
-H "Authorization: Bearer $TOKEN")
# Check for token expiry
if echo "$STATUS" | grep -q "Token expired\|Not authenticated"; then
echo "Token expired. Please re-authenticate:"
echo " Run: atris login --force"
echo " Or get new token from: https://atris.ai/auth/cli"
exit 1
fi
# Parse connected status
if command -v node &> /dev/null; then
CONNECTED=$(node -e "console.log(JSON.parse('$STATUS').connected || false)")
elif command -v python3 &> /dev/null; then
CONNECTED=$(echo "$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin).get('connected', False))")
else
CONNECTED=$(echo "$STATUS" | jq -r '.connected // false')
fi
if [ "$CONNECTED" != "true" ] && [ "$CONNECTED" != "True" ]; then
echo "Gmail not connected. Getting authorization URL..."
AUTH=$(curl -s -X POST "https://api.atris.ai/api/integrations/gmail/start" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}')
if command -v node &> /dev/null; then
URL=$(node -e "console.log(JSON.parse('$AUTH').auth_url || '')")
elif command -v python3 &> /dev/null; then
URL=$(echo "$AUTH" | python3 -c "import sys,json; print(json.load(sys.stdin).get('auth_url', ''))")
else
URL=$(echo "$AUTH" | jq -r '.auth_url // empty')
fi
echo ""
echo "Open this URL to connect your Gmail:"
echo "$URL"
echo ""
echo "After authorizing, run your email command again."
exit 0
fi
echo "Ready. Gmail is connected."
export ATRIS_TOKEN="$TOKEN"

Important: Run this script ONCE before email operations. If it exits with instructions, follow them, then run again.


API Reference

Base: https://api.atris.ai/api/integrations/gmail

All requests require: -H "Authorization: Bearer $TOKEN"

Get Token (after bootstrap)
bash
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
List Emails
bash
curl -s "https://api.atris.ai/api/integrations/gmail/messages?query=in:inbox&max_results=20" \
-H "Authorization: Bearer $TOKEN"

Query syntax (Gmail search):

  • in:inbox: inbox only
  • in:inbox newer_than:1d: today's emails
  • is:unread: unread only
  • from:someone@example.com: from specific sender
  • subject:invoice: subject contains word
  • has:attachment: emails with attachments
Read Single Email
bash
curl -s "https://api.atris.ai/api/integrations/gmail/messages/{message_id}" \
-H "Authorization: Bearer $TOKEN"
Send Email
bash
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "Subject line",
"body": "Email body text"
}'

With CC/BCC:

bash
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"cc": "copy@example.com",
"bcc": ["hidden1@example.com", "hidden2@example.com"],
"subject": "Subject line",
"body": "Email body text"
}'

Reply in thread (IMPORTANT: use this for all replies):

To reply within an existing email thread, you MUST pass thread_id and reply_to_message_id. Without these, Gmail creates a new thread.

bash
# 1. First, get the message you're replying to (extract thread_id and id)
curl -s "https://api.atris.ai/api/integrations/gmail/messages/{message_id}" \
-H "Authorization: Bearer $TOKEN"
# Response includes: id, thread_id, subject, from, etc.
# 2. Send reply in the same thread
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "original-sender@example.com",
"subject": "Re: Original Subject",
"body": "Your reply text here",
"thread_id": "THREAD_ID_FROM_STEP_1",
"reply_to_message_id": "MESSAGE_ID_FROM_STEP_1"
}'
  • thread_id: The thread ID from the original message. Tells Gmail which thread to add this to.
  • reply_to_message_id: The message ID you're replying to. The backend uses this to set In-Reply-To and References headers so Gmail threads it correctly.
  • subject: Must match the original subject with "Re: " prefix.

With attachments:

bash
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "With attachment",
"body": "See attached.",
"attachments": [{"filename": "report.txt", "content": "base64-encoded-content", "mime_type": "text/plain"}]
}'
Drafts

List drafts:

bash
curl -s "https://api.atris.ai/api/integrations/gmail/drafts?max_results=20" \
-H "Authorization: Bearer $TOKEN"

Read a draft:

bash
curl -s "https://api.atris.ai/api/integrations/gmail/drafts/{draft_id}" \
-H "Authorization: Bearer $TOKEN"

Create a draft:

bash
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/drafts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "Subject line",
"body": "Draft body text"
}'

Supports same fields as send: cc, bcc, attachments, plus thread_id to attach to an existing thread.

Update a draft:

bash
curl -s -X PUT "https://api.atris.ai/api/integrations/gmail/drafts/{draft_id}" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "Updated subject",
"body": "Updated body"
}'

Send a draft:

bash
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/drafts/{draft_id}/send" \
-H "Authorization: Bearer $TOKEN"

Delete a draft:

bash
curl -s -X DELETE "https://api.atris.ai/api/integrations/gmail/drafts/{draft_id}" \
-H "Authorization: Bearer $TOKEN"
Mark as Read / Unread
bash
# Mark as read
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/messages/{message_id}/read" \
-H "Authorization: Bearer $TOKEN"
# Mark as unread
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/messages/{message_id}/unread" \
-H "Authorization: Bearer $TOKEN"
Archive Email
bash
# Single message
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/messages/{message_id}/archive" \
-H "Authorization: Bearer $TOKEN"
# Batch archive
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/messages/batch-archive" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"message_ids": ["id1", "id2", "id3"]}'
Trash Email
bash
# Single message
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/messages/{message_id}/trash" \
-H "Authorization: Bearer $TOKEN"
# Batch trash
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/messages/batch-trash" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"message_ids": ["id1", "id2", "id3"]}'
Check Status
bash
curl -s "https://api.atris.ai/api/integrations/gmail/status" \
-H "Authorization: Bearer $TOKEN"
Disconnect Gmail
bash
curl -s -X DELETE "https://api.atris.ai/api/integrations/gmail" \
-H "Authorization: Bearer $TOKEN"

Workflows

"Check my emails"
  1. Run bootstrap
  2. List messages: GET /messages?query=in:inbox%20newer_than:1d&max_results=20
  3. Display: sender, subject, snippet for each
"Send email to X about Y"
  1. Run bootstrap
  2. Draft email content
  3. Show user the draft for approval
  4. On approval: POST /send with {to, subject, body}
  5. Confirm: "Email sent!"
"Reply to this email"
  1. Run bootstrap
  2. Read the message: GET /messages/{message_id}, extract id, thread_id, from, subject
  3. Draft reply content
  4. Show user the reply for approval
  5. On approval: POST /send with {to, subject: "Re: ...", body, thread_id, reply_to_message_id}
  6. Verify: response thread_id matches original thread_id (if it doesn't, something went wrong)
"Clean up my inbox"
  1. Run bootstrap
  2. List: GET /messages?query=in:inbox&max_results=50
  3. Identify archivable emails (see rules below)
  4. Show user what will be archived, get approval
  5. Batch archive: POST /batch-archive
"Show my drafts"
  1. Run bootstrap
  2. List drafts: GET /gmail/drafts?max_results=20
  3. Display: to, subject, snippet for each
"Draft an email to X about Y"
  1. Run bootstrap
  2. Compose email content
  3. Show user the draft for review
  4. On approval: POST /gmail/drafts with {to, subject, body}
  5. Confirm: "Draft saved! You can find it in Gmail."
"Send draft about X"
  1. Run bootstrap
  2. List drafts: GET /gmail/drafts
  3. Find matching draft by subject/recipient
  4. Show user the draft content, confirm they want to send it
  5. Send: POST /gmail/drafts/{draft_id}/send
"Archive all from [sender]"
  1. Run bootstrap
  2. Search: GET /messages?query=from:{sender}
  3. Collect message IDs
  4. Confirm with user: "Found N emails from {sender}. Archive all?"
  5. Batch archive

Auto-Archive Rules

Safe to suggest archiving:

  • From: noreply@, notifications@, newsletter@, no-reply@
  • Subject contains: digest, newsletter, notification, weekly update, daily summary
  • Marketing: promotional, unsubscribe link present

NEVER auto-archive (always keep):

  • Subject contains: invoice, receipt, payment, urgent, action required, password, verification, security
  • From known contacts (check if user has replied to them)
  • Flagged/starred messages

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
58
Repository forks
2
Repository npm downloads, 7 days
256
7-day trend score
36

Stars and forks are for the whole GitHub repository, not this skill alone. Downloads are for the repository's npm package. Refreshed 20 Mar 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/atrislabs/atris/email-agent/badge)](https://verified-skill.com/skills/atrislabs/atris/email-agent)

Something wrong with this skill or its page? Tell us.