mcpField
E
email-agent

email-agent

github.com/atrislabs生产力7165 次安装1 天前更新
代码仓库

关于 email-agent

通过 Atris CLI 和 API 管理 Gmail 的 Claude Code 技能,支持处理邮件和草稿,并要求发送或归档前先获批准。

主要功能

  1. 01搜索和读取 Gmail 邮件
  2. 02发送邮件及在线程中回复
  3. 03创建和管理草稿
  4. 04标记、归档和移至垃圾箱
  5. 05发送与归档前征求批准
  6. 06初始化与连接故障排查

适用场景

  1. 01查看近期或未读收件箱邮件
  2. 02准备回复并等待批准
  3. 03保存并发送草稿
  4. 04经确认后整理邮件

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/atrislabs/atris --skill email-agent

安装后在 Claude Code 中输入/email-agent确认已加载。

详细介绍

邮件 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 — 带附件的邮件
阅读单封邮件
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"
  }'

添加抄送/密送:

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"

工作流

“检查我的邮件”
  1. 运行初始化脚本
  2. 列出邮件:GET /messages?query=in:inbox%20newer_than:1d&max_results=20
  3. 显示每封邮件的发件人、主题和摘要
“给 X 发一封关于 Y 的邮件”
  1. 运行初始化脚本
  2. 起草邮件内容
  3. 向用户展示草稿以供审批
  4. 获得批准后:使用 {to, subject, body} 调用 POST /send
  5. 确认:“邮件已发送!”
“回复这封邮件”
  1. 运行初始化脚本
  2. 阅读邮件:GET /messages/{message_id} — 提取 id、thread_id、from、subject
  3. 起草回复内容
  4. 向用户展示回复以供审批
  5. 获得批准后:使用 {to, subject: "Re: ...", body, thread_id, reply_to_message_id} 调用 POST /send
  6. 验证:响应中的 thread_id 与原始 thread_id 相同(若不同,则表示出现问题)
“整理我的收件箱”
  1. 运行初始化脚本
  2. 列出邮件:GET /messages?query=in:inbox&max_results=50
  3. 找出可归档的邮件(见下方规则)
  4. 向用户展示将要归档的邮件,并征求批准
  5. 批量归档:POST /batch-archive
“显示我的草稿”
  1. 运行初始化脚本
  2. 列出草稿:GET /gmail/drafts?max_results=20
  3. 显示每封草稿的收件人、主题和摘要
“起草一封给 X 的关于 Y 的邮件”
  1. 运行初始化脚本
  2. 撰写邮件内容
  3. 向用户展示草稿以供审核
  4. 获得批准后:使用 {to, subject, body} 调用 POST /gmail/drafts
  5. 确认:“草稿已保存!你可以在 Gmail 中找到它。”
“发送关于 X 的草稿”
  1. 运行初始化脚本
  2. 列出草稿:GET /gmail/drafts
  3. 按主题/收件人查找匹配的草稿
  4. 向用户展示草稿内容,并确认是否要发送
  5. 发送:POST /gmail/drafts/{draft_id}/send
“归档所有来自 [发件人] 的邮件”
  1. 运行初始化脚本
  2. 搜索:GET /messages?query=from:{sender}
  3. 收集邮件 ID
  4. 向用户确认:“找到来自 {sender} 的 N 封邮件。全部归档吗?”
  5. 批量归档

自动归档规则

可以安全地建议归档:

  • 发件人:noreply@、notifications@、newsletter@、no-reply@
  • 主题包含:摘要、新闻简报、通知、每周更新、每日摘要
  • 营销邮件:促销内容,且包含退订链接

绝不自动归档(始终保留):

  • 主题包含:发票、收据、付款、紧急、需要采取行动、密码、验证、安全
  • 来自已知联系人的邮件(检查用户是否回复过对方)
  • 已加旗标或星标的邮件

归档前始终询问。 未经用户明确批准,绝不归档。


错误处理

错误含义解决方案
Token expiredAtrisOS 会话已过期运行 atris login
Gmail not connected尚未完成 OAuth重新运行 bootstrap,完成 OAuth 流程
401 Unauthorized令牌无效或已过期运行 atris login
400 Gmail not connected没有 Gmail 凭据通过 bootstrap 完成 OAuth
429 Rate limited请求过多等待 60s 后重试
Invalid grantGoogle 已撤销访问权限通过 bootstrap 重新连接 Gmail

安全模型

  1. 本地令牌(~/.atris/credentials.json):你的 AtrisOS 身份验证令牌,以 600 权限存储在本地。与 AWS CLI、GitHub CLI 使用相同的模型。

  2. Gmail 凭据:你的 Gmail 刷新令牌存储在 AtrisOS 加密保管库的服务端。绝不会存储在本地计算机上。

  3. 访问控制:AtrisOS API 确保你只能访问自己的电子邮件。无法跨用户访问。

  4. OAuth 权限范围:仅请求必要的 Gmail 权限(读取、发送、修改标签)。

  5. 仅使用 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"

评论

支持 Markdown