email-agent について
Atris CLI と API を使って Gmail を管理する Claude Code スキルです。メールや下書きを操作でき、送信やアーカイブの前に承認を求めます。
主な機能
- 01Gmail メールの検索と閲覧
- 02メール送信とスレッド返信
- 03下書きの作成と管理
- 04既読設定、アーカイブ、ゴミ箱移動
- 05送信とアーカイブ前の承認
- 06初期設定と接続時の問題対応
活用シーン
- 01最近のメールや未読メールの確認
- 02承認用の返信文の準備
- 03下書きの保存と送信
- 04確認を得たうえでのメール整理
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ atrislabs/ atris --skill email-agentインストール後、Claude Code で/email-agentを入力して読み込まれたか確認します。
詳細
メールエージェント
これを
~/.claude/skills/email-agent/SKILL.mdに配置すると、Claude Code がメールアシスタントになります。
ブートストラップ(必ず最初に実行)
メール関連の操作を行う前に、すべてがセットアップされていることを確認するため、このブートストラップを実行します。
#!/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"
重要:メール関連の操作を行う前に、このスクリプトを一度だけ実行します。手順が表示された場合はそれに従い、その後もう一度実行してください。
API リファレンス
ベース URL:https://api.atris.ai/api/integrations/gmail
すべてのリクエストで必要です:-H "Authorization: Bearer $TOKEN"
トークンを取得(ブートストラップ後)
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
メールを一覧表示
curl -s "https://api.atris.ai/api/integrations/gmail/messages?query=in:inbox&max_results=20" \
-H "Authorization: Bearer $TOKEN"
検索構文(Gmail 検索):
in:inbox— 受信トレイのみin:inbox newer_than:1d— 今日のメールis:unread— 未読のみfrom:[email protected]— 特定の送信者からsubject:invoice— 件名に単語を含むhas:attachment— 添付ファイルのあるメール
メールを 1 件読む
curl -s "https://api.atris.ai/api/integrations/gmail/messages/{message_id}" \
-H "Authorization: Bearer $TOKEN"
メールを送信
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "[email protected]",
"subject": "Subject line",
"body": "Email body text"
}'
CC/BCC を指定する場合:
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "[email protected]",
"cc": "[email protected]",
"bcc": ["[email protected]", "[email protected]"],
"subject": "Subject line",
"body": "Email body text"
}'
スレッド内で返信する(重要 — すべての返信でこれを使用):
既存のメールスレッド内で返信するには、thread_id と reply_to_message_id を必ず指定します。これらがない場合、Gmail は新しいスレッドを作成します。
# 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": "[email protected]",
"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— 元のメッセージのスレッド ID です。メッセージを追加するスレッドを Gmail に伝えます。reply_to_message_id— 返信するメッセージの ID です。バックエンドはこれを使ってIn-Reply-ToおよびReferencesヘッダーを設定し、Gmail が正しくスレッドにまとめられるようにします。subject— 元の件名に「Re: 」を付けたものと一致させる必要があります。
添付ファイルを指定する場合:
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "[email protected]",
"subject": "With attachment",
"body": "See attached.",
"attachments": [{"filename": "report.txt", "content": "base64-encoded-content", "mime_type": "text/plain"}]
}'
下書き
下書きを一覧表示:
curl -s "https://api.atris.ai/api/integrations/gmail/drafts?max_results=20" \
-H "Authorization: Bearer $TOKEN"
下書きを読む:
curl -s "https://api.atris.ai/api/integrations/gmail/drafts/{draft_id}" \
-H "Authorization: Bearer $TOKEN"
下書きを作成:
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/drafts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"to": "[email protected]",
"subject": "Subject line",
"body": "Draft body text"
}'
送信時と同じフィールド(cc、bcc、attachments)に加えて、既存のスレッドに紐付けるための thread_id に対応しています。
下書きを更新:
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": "[email protected]",
"subject": "Updated subject",
"body": "Updated body"
}'
下書きを送信:
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/drafts/{draft_id}/send" \
-H "Authorization: Bearer $TOKEN"
下書きを削除:
curl -s -X DELETE "https://api.atris.ai/api/integrations/gmail/drafts/{draft_id}" \
-H "Authorization: Bearer $TOKEN"
既読/未読にする
# 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"
メールをアーカイブ
# 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"]}'
メールをゴミ箱に移動
# 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"]}'
ステータスを確認
curl -s "https://api.atris.ai/api/integrations/gmail/status" \
-H "Authorization: Bearer $TOKEN"
Gmail の接続を解除
curl -s -X DELETE "https://api.atris.ai/api/integrations/gmail" \
-H "Authorization: Bearer $TOKEN"
ワークフロー
「メールを確認して」
- ブートストラップを実行
- メッセージを一覧表示:
GET /messages?query=in:inbox%20newer_than:1d&max_results=20 - 各メールについて、送信者、件名、スニペットを表示
「X に Y についてメールを送って」
- ブートストラップを実行
- メール本文を作成
- 承認を得るため、下書きをユーザーに表示
- 承認後:
POST /sendに{to, subject, body}を指定 - 確認:「メールを送信しました!」
「このメールに返信して」
- ブートストラップを実行
- メッセージを読む:
GET /messages/{message_id}—id、thread_id、from、subjectを抽出 - 返信文を作成
- 承認を得るため、返信文をユーザーに表示
- 承認後:
POST /sendに{to, subject: "Re: ...", body, thread_id, reply_to_message_id}を指定 - 確認:レスポンスの
thread_idが元のthread_idと一致することを確認(一致しない場合は何か問題が起きています)
「受信トレイを整理して」
- ブートストラップを実行
- 一覧表示:
GET /messages?query=in:inbox&max_results=50 - アーカイブ可能なメールを特定(以下のルールを参照)
- アーカイブするメールをユーザーに表示し、承認を得る
- 一括アーカイブ:
POST /batch-archive
「下書きを表示して」
- ブートストラップを実行
- 下書きを一覧表示:
GET /gmail/drafts?max_results=20 - 各下書きについて、宛先、件名、スニペットを表示
「X に Y についてメールの下書きを作成して」
- ブートストラップを実行
- メール本文を作成
- 確認してもらうため、下書きをユーザーに表示
- 承認後:
POST /gmail/draftsに{to, subject, body}を指定 - 確認:「下書きを保存しました!Gmail で確認できます。」
「X についての下書きを送信して」
- ブートストラップを実行
- 下書きを一覧表示:
GET /gmail/drafts - 件名/宛先で該当する下書きを探す
- 下書きの内容をユーザーに表示し、送信してよいか確認
- 送信:
POST /gmail/drafts/{draft_id}/send
「[送信者] からのメールをすべてアーカイブして」
- ブートストラップを実行
- 検索:
GET /messages?query=from:{sender} - メッセージ ID を収集
- ユーザーに確認:「{sender} からのメールが N 件見つかりました。すべてアーカイブしますか?」
- 一括アーカイブ
自動アーカイブのルール
アーカイブを提案しても安全なもの:
- 差出人:
noreply@、notifications@、newsletter@、no-reply@ - 件名に含まれる語句:digest、newsletter、notification、weekly update、daily summary
- マーケティング:宣伝目的で、配信停止リンクがある
自動アーカイブは絶対にしない(常に残す):
- 件名に含まれる語句:invoice、receipt、payment、urgent、action required、password、verification、security
- 既知の連絡先からのメッセージ(ユーザーがその相手に返信したことがあるか確認してください)
- フラグ付き/スター付きのメッセージ
アーカイブする前に、必ず確認してください。 ユーザーの明示的な承認なしにアーカイブしてはいけません。
エラー処理
| エラー | 意味 | 解決方法 |
|---|---|---|
Token expired | AtrisOS のセッションが期限切れです | atris login を実行してください |
Gmail not connected | OAuth が完了していません | bootstrap を再実行し、OAuth フローを完了してください |
401 Unauthorized | トークンが無効または期限切れです | atris login を実行してください |
400 Gmail not connected | Gmail の認証情報がありません | bootstrap を使用して OAuth を完了してください |
429 Rate limited | リクエストが多すぎます | 60 秒待ってから再試行してください |
Invalid grant | Google がアクセスを取り消しました | bootstrap を使用して Gmail を再接続してください |
セキュリティモデル
-
ローカルトークン(
~/.atris/credentials.json):AtrisOS の認証トークンです。600 権限でローカルに保存されます。AWS CLI、GitHub CLI と同じモデルです。 -
Gmail の認証情報:Gmail のリフレッシュトークンは、AtrisOS の暗号化されたボールトにサーバー側で保存されます。ローカルマシンに保存されることはありません。
-
アクセス制御:AtrisOS API により、自分のメールのみアクセスできます。ユーザー間のアクセスはできません。
-
OAuth スコープ:必要な Gmail 権限(読み取り、送信、ラベルの変更)のみを要求します。
-
HTTPS のみ:すべての API 通信は転送中に暗号化されます。
クイックリファレンス
# Setup (one time)
npm install -g atris && atris login
# Get token
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
# Check connection
curl -s "https://api.atris.ai/api/integrations/gmail/status" -H "Authorization: Bearer $TOKEN"
# List inbox
curl -s "https://api.atris.ai/api/integrations/gmail/messages?query=in:inbox&max_results=10" -H "Authorization: Bearer $TOKEN"
# Send new email
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"to":"[email protected]","subject":"Hi","body":"Hello!"}'
# Reply in thread (pass thread_id + reply_to_message_id)
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/send" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"to":"[email protected]","subject":"Re: Original","body":"Reply text","thread_id":"THREAD_ID","reply_to_message_id":"MSG_ID"}'
# List drafts
curl -s "https://api.atris.ai/api/integrations/gmail/drafts" -H "Authorization: Bearer $TOKEN"
# Create draft
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/drafts" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"to":"[email protected]","subject":"Hi","body":"Draft text"}'
# Mark as read
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/messages/{message_id}/read" -H "Authorization: Bearer $TOKEN"
# Trash an email
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/messages/{message_id}/trash" -H "Authorization: Bearer $TOKEN"
# Send a draft
curl -s -X POST "https://api.atris.ai/api/integrations/gmail/drafts/{draft_id}/send" \
-H "Authorization: Bearer $TOKEN"