mcpField
G
google-workspace

google-workspace

github.com/nousresearch生产力258.1k583 次安装今天更新
代码仓库

关于 google-workspace

google-workspace 是 Hermes 技能,通过 OAuth 和命令行封装访问 Gmail、Calendar、Drive、Contacts、Sheets 和 Docs。安装了 gws 时优先使用它,否则回退到内置 Python 客户端,并以 JSON 返回操作结果。

主要功能

  1. 01搜索和读取 Gmail 邮件
  2. 02列出并创建 Calendar 日程
  3. 03搜索、上传和管理 Drive 文件
  4. 04管理 Contacts、Sheets 和 Docs
  5. 05配置 OAuth 并管理令牌
  6. 06通过命令行输出 JSON

适用场景

  1. 01查看未读或需要及时处理的邮件
  2. 02检查日程并准备会议
  3. 03查找和管理 Drive 文件
  4. 04读取或创建电子表格和文档

安装

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

$npx skills add https://github.com/nousresearch/hermes-agent --skill google-workspace

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

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
daily-brief.md
gmail-search-syntax.md
scripts/
_hermes_home.py
google_api.py
gws_bridge.py
setup.py

详细介绍

Google Workspace

通过 Hermes 管理的 OAuth 和轻量 CLI 封装程序使用 Gmail、Calendar、Drive、Contacts、Sheets 和 Docs。安装 gws 后,该技能会将其作为执行后端,以支持更广泛的 Google Workspace 功能;否则会回退到内置的 Python 客户端实现。

参考资料

  • references/gmail-search-syntax.md — Gmail 搜索运算符(is:unread、from:、newer_than: 等)
  • references/daily-brief.md — 每日/晨间简报流程:Gmail 和 Calendar 中的日程+冲突+会议准备+紧急邮件。当用户要求生成晨间简报、进行会议准备,或询问“我的日程上有哪些安排、哪些邮件需要处理”时,请加载此文件。

脚本

  • scripts/setup.py — OAuth2 设置(运行一次以授权)
  • scripts/google_api.py — 兼容性 CLI 封装程序。可用时优先使用 gws 执行操作,同时保留 Hermes 现有的 JSON 输出约定。

首次设置

整个设置过程无需交互——您可以逐步操作,因此它适用于 CLI、Telegram、Discord 或任何平台。

请在 Hermes 环境中使用 Python 运行设置脚本,不要使用无关的 系统 Python。--install-deps 会通过 PM 同步 Hermes 声明的 Google 附加依赖; 同步后,重启 Hermes 并重新运行 OAuth 命令。如果无法导入 Hermes, 请先使用 hermes setup,而不是通过 pip 安装软件包。

先定义一个简写:

GSETUP="python ${HERMES_HOME:-$HOME/.hermes}/skills/productivity/google-workspace/scripts/setup.py"
第 0 步:检查是否已设置
$GSETUP --check

如果输出 AUTHENTICATED,请跳转到使用说明——设置已完成。

第 1 步:初步判断——询问用户需求

在开始 OAuth 设置前,向用户询问两个问题:

问题 1:“您需要哪些 Google 服务?仅使用电子邮件,还是还需要 Calendar/Drive/Sheets/Docs?”

  • 仅电子邮件 → 完全不需要此技能。请改用 himalaya 技能 ——它使用 Gmail 应用密码(设置 → 安全 → 应用密码), 只需 2 分钟即可完成设置,无需 Google Cloud 项目。请加载 himalaya 技能并遵循其设置说明。

  • 电子邮件 + Calendar → 继续使用此技能,但授权时使用 --services email,calendar,使同意页面仅请求实际需要的权限范围。

  • 仅 Calendar/Drive/Sheets/Docs → 继续使用此技能,并使用类似 calendar,drive,sheets,docs 的更精简 --services 设置。

  • 完整 Workspace 访问权限 → 继续使用此技能,并使用默认的 all 服务集。

问题 2:“您的 Google 账户是否启用了 Advanced Protection(登录时需要硬件 安全密钥)?如果不确定,您很可能没有 启用——这是您必须明确加入后才会有的一项功能。”

  • 否/不确定 → 正常设置。请继续下方的步骤。
  • 是 → 在第 4 步生效前,其 Workspace 管理员必须将 OAuth 客户端 ID 添加到组织的允许应用列表中。 请提前告知用户。
第 2 步:创建 OAuth 凭据(一次性,约 5 分钟)

告知用户:

你需要一个 Google Cloud OAuth 客户端。这是一次性设置:

  1. 创建或选择项目: https://console.cloud.google.com/projectselector2/home/dashboard
  2. 从 API 库启用所需 API: https://console.cloud.google.com/apis/library 启用:Gmail API、Google Calendar API、Google Drive API、 Google Sheets API、Google Docs API、People API
  3. 在此创建 OAuth 客户端: https://console.cloud.google.com/apis/credentials 凭据 → 创建凭据 → OAuth 2.0 客户端 ID
  4. 应用类型:“桌面应用”→ 创建
  5. 如果应用仍处于“测试”状态,请在此将用户的 Google 账号添加为测试用户: https://console.cloud.google.com/auth/audience 受众群体 → 测试用户 → 添加用户
  6. 下载 JSON 文件并告知我文件路径

Hermes CLI 重要说明:如果文件路径以 / 开头,请勿在 CLI 中仅将裸路径作为一条独立消息发送,因为它可能会被误认为斜杠命令。请改为放在一个句子中发送,例如: JSON 文件路径是:~/Downloads/client_secret_....json

收到路径后:

$GSETUP --client-secret /path/to/client_secret.json

如果他们粘贴的是原始客户端 ID/客户端密钥值,而不是文件路径, 请自行编写有效的桌面 OAuth JSON 文件,并将其明确保存到某个位置 (例如 ~/Downloads/hermes-google-client-secret.json),然后针对该文件运行 --client-secret。

第 3 步:获取授权 URL

使用第 1 步中选定服务集合。示例:

$GSETUP --auth-url --services email,calendar --format json
$GSETUP --auth-url --services calendar,drive,sheets,docs --format json
$GSETUP --auth-url --services all --format json

这会返回带有 auth_url 字段的 JSON,并将确切的 URL 保存到 ~/.hermes/google_oauth_last_url.txt。

此步骤的 Agent 规则:

  • 提取 auth_url 字段,并将该确切 URL 作为单独一行发送给用户。
  • 告知用户,批准后浏览器访问 http://localhost:1 时很可能会失败,这是预期现象。
  • 告知用户从浏览器地址栏复制完整的重定向 URL。
  • 如果用户收到 Error 403: access_denied,直接引导用户访问 https://console.cloud.google.com/auth/audience,将自己添加为测试用户。
第 4 步:交换代码

用户会回传一个类似 http://localhost:1/?code=4/0A...&scope=... 的 URL, 或仅粘贴代码字符串。两者均可。--auth-url 步骤会在本地存储临时的 待处理 OAuth 会话,以便 --auth-code 稍后完成 PKCE 交换, 即使在无界面系统上也是如此:

$GSETUP --auth-code "THE_URL_OR_CODE_THE_USER_PASTED" --format json

如果 --auth-code 失败,原因可能是代码已过期、已被使用,或代码来自 较旧的浏览器标签页,则它现在会返回一个新的 fresh_auth_url。在这种情况下, 立即将新 URL 发送给用户,并让用户仅使用最新的浏览器重定向 URL 重试。

第 5 步:验证
$GSETUP --check

应输出 AUTHENTICATED。设置已完成——从现在起令牌会自动刷新。

备注
  • 令牌存储在 ~/.hermes/google_token.json 中,并会自动刷新。
  • 待处理 OAuth 会话状态/验证器会临时存储在 ~/.hermes/google_oauth_pending.json 中,直至交换完成。
  • 如果已安装 gws,google_api.py 会将其指向同一个 ~/.hermes/google_token.json 凭据文件。用户无需运行单独的 gws auth login 流程。
  • 要撤销授权:$GSETUP --revoke

使用方法

所有命令都通过 API 脚本执行。将 GAPI 设为简写:

GAPI="python ${HERMES_HOME:-$HOME/.hermes}/skills/productivity/google-workspace/scripts/google_api.py"
Gmail
# Search (returns JSON array with id, from, subject, date, snippet)
$GAPI gmail search "is:unread" --max 10
$GAPI gmail search "from:[email protected] newer_than:1d"
$GAPI gmail search "has:attachment filename:pdf newer_than:7d"

# Read full message (returns JSON with body text)
$GAPI gmail get MESSAGE_ID

# Send
$GAPI gmail send --to [email protected] --subject "Hello" --body "Message text"
$GAPI gmail send --to [email protected] --subject "Report" --body "<h1>Q4</h1><p>Details...</p>" --html
$GAPI gmail send --to [email protected] --subject "Hello" --from '"Research Agent" <[email protected]>' --body "Message text"

# Reply (automatically threads and sets In-Reply-To)
$GAPI gmail reply MESSAGE_ID --body "Thanks, that works for me."
$GAPI gmail reply MESSAGE_ID --from '"Support Bot" <[email protected]>' --body "Thanks"

# Labels
$GAPI gmail labels
$GAPI gmail modify MESSAGE_ID --add-labels LABEL_ID
$GAPI gmail modify MESSAGE_ID --remove-labels UNREAD
Calendar
# List events (defaults to next 7 days)
$GAPI calendar list
$GAPI calendar list --start 2026-03-01T00:00:00Z --end 2026-03-07T23:59:59Z

# Create event (ISO 8601 with timezone required)
$GAPI calendar create --summary "Team Standup" --start 2026-03-01T10:00:00-06:00 --end 2026-03-01T10:30:00-06:00
$GAPI calendar create --summary "Lunch" --start 2026-03-01T12:00:00Z --end 2026-03-01T13:00:00Z --location "Cafe"
$GAPI calendar create --summary "Review" --start 2026-03-01T14:00:00Z --end 2026-03-01T15:00:00Z --attendees "[email protected],[email protected]"

# Delete event
$GAPI calendar delete EVENT_ID
Drive
# Search existing files
$GAPI drive search "quarterly report" --max 10
$GAPI drive search "mimeType='application/pdf'" --raw-query --max 5

# Get metadata for a single file
$GAPI drive get FILE_ID

# Upload a local file (auto-detects MIME type)
$GAPI drive upload /path/to/report.pdf
$GAPI drive upload /path/to/image.png --name "Logo.png" --parent FOLDER_ID

# Download (binary files download as-is; Google-native files export to a
# sensible default — Docs→pdf, Sheets→csv, Slides→pdf, Drawings→png)
$GAPI drive download FILE_ID
$GAPI drive download DOC_ID --output ~/doc.pdf
$GAPI drive download DOC_ID --export-mime text/plain --output ~/doc.txt

# Create a folder
$GAPI drive create-folder "Reports"
$GAPI drive create-folder "Q4" --parent FOLDER_ID

# Share
$GAPI drive share FILE_ID --email [email protected] --role reader
$GAPI drive share FILE_ID --email [email protected] --role writer --notify
$GAPI drive share FILE_ID --type anyone --role reader        # anyone with link
$GAPI drive share FILE_ID --type domain --domain example.com --role reader

# Delete — defaults to trash (reversible). Use --permanent to skip the trash.
$GAPI drive delete FILE_ID
$GAPI drive delete FILE_ID --permanent
Contacts
$GAPI contacts list --max 20
Sheets
# Create a new spreadsheet
$GAPI sheets create --title "Q4 Budget"
$GAPI sheets create --title "Inventory" --sheet-name "Stock"

# Read
$GAPI sheets get SHEET_ID "Sheet1!A1:D10"

# Write
$GAPI sheets update SHEET_ID "Sheet1!A1:B2" --values '[["Name","Score"],["Alice","95"]]'

# Append rows
$GAPI sheets append SHEET_ID "Sheet1!A:C" --values '[["new","row","data"]]'
Docs
# Read (a tabbed Doc returns a "tabs" array; single-tab and legacy Docs also return "body")
$GAPI docs get DOC_ID
$GAPI docs get DOC_ID --tab TAB_ID     # read one tab of a tabbed Doc

# Create a new Doc (optionally seeded with body text)
$GAPI docs create --title "Meeting Notes"
$GAPI docs create --title "Draft" --body "First paragraph..."

# Append text to the end of an existing Doc
$GAPI docs append DOC_ID --text "Additional content to append"
$GAPI docs append DOC_ID --tab TAB_ID --text "..."   # --tab required when the Doc has multiple tabs

输出格式

所有命令均返回 JSON。使用 jq 解析或直接读取。关键字段:

  • Gmail 搜索:[{id, threadId, from, to, subject, date, snippet, labels}]
  • Gmail 获取:{id, threadId, from, to, subject, date, labels, body}
  • Gmail 发送/回复:{status: "sent", id, threadId}
  • Calendar 列表:[{id, summary, start, end, location, description, htmlLink}]
  • Calendar 创建:{status: "created", id, summary, htmlLink}
  • Drive 搜索:[{id, name, mimeType, modifiedTime, webViewLink}]
  • Drive 获取:{id, name, mimeType, modifiedTime, size, webViewLink, parents, owners}
  • Drive 上传:{status: "uploaded", id, name, mimeType, webViewLink}
  • Drive 下载:{status: "downloaded", id, name, path, mimeType}
  • Drive 创建文件夹:{status: "created", id, name, webViewLink}
  • Drive 共享:{status: "shared", permissionId, fileId, role, type}
  • Drive 删除:{status: "trashed" | "deleted", fileId, permanent}
  • Contacts 列表:[{name, emails: [...], phones: [...]}]
  • Sheets 获取:[[cell, cell, ...], ...]
  • Sheets 创建:{status: "created", spreadsheetId, title, spreadsheetUrl}
  • Docs 创建:{status: "created", documentId, title, url}
  • Docs 追加:{status: "appended", documentId, inserted_at, characters}

规则

  1. 未经用户事先确认,绝不发送电子邮件、创建或删除 Calendar 事件、删除 Drive 文件、共享文件或修改 Docs/Sheets。 显示将要执行的操作(收件人、文件 ID、内容、共享角色)并请求批准。对于 drive delete,优先使用默认的移至回收站操作(可逆),而非 --permanent。
  2. 首次使用前检查身份验证——运行 setup.py --check。如果失败,指导用户完成设置。
  3. 对于复杂查询,使用 Gmail 搜索语法参考——通过 skill_view("google-workspace", file_path="references/gmail-search-syntax.md") 加载。
  4. Calendar 时间必须包含时区——始终使用带偏移量的 ISO 8601(例如,2026-03-01T10:00:00-06:00)或 UTC(Z)。
  5. 遵守速率限制——避免快速连续发起 API 调用。尽可能批量读取。

故障排除

问题解决方法
NOT_AUTHENTICATED运行上述设置步骤 2-5
REFRESH_FAILED令牌已被撤销或过期——重新执行步骤 3-5
HttpError 403: Insufficient Permission缺少 API 权限范围——运行 $GSETUP --revoke,然后重新执行步骤 3-5
AUTHENTICATED (partial) 或“缺少令牌权限范围”新增写入权限(Drive 写入/删除、Docs 创建/编辑)需要重新授权。运行 $GSETUP --revoke,然后重新执行步骤 3-5,以授予升级后的权限范围。
HttpError 403: Access Not ConfiguredAPI 未启用——用户需要在 Google Cloud Console 中启用
ModuleNotFoundError运行 $GSETUP --install-deps
Advanced Protection 阻止身份验证Workspace 管理员必须将 OAuth 客户端 ID 加入允许列表

撤销访问权限

$GSETUP --revoke

评论

支持 Markdown