Google Workspace MCP
Allows reading Google Docs and syncing their content as a single source of truth into Obsidian notes.
Allows reading Google Sheets with support for specifying sheet, range, and pagination.
Allows writing content to Obsidian notes and synchronizing Google Doc content into designated sync blocks.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Google Workspace MCPsync my meeting notes from Google Doc to Obsidian"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Google Workspace MCP
English version: README.en.md
文档同步约定:
以后修改本 README 中文内容时,请同时同步更新 README.en.md,保持两份文档结构和关键信息一致。
一个最小可运行的 MCP 项目骨架,先打通这条闭环:
从 Obsidian note 中识别 Google Doc SSOT 链接
调用 Google Docs API 读取正文
将同步内容写回 note 的专用同步区块
保留 note 自有内容,不覆盖人工内容
当前已实现
google_doc_readgoogle_doc_writegoogle_sheet_readgoogle_slide_readgoogle_slide_writegoogle_slide_apply_sheet_mappingsobsidian_note_writeobsidian_sync_google_docobsidian_sync_google_doc_ssot
Related MCP server: Google Drive MCP Server
License
Apache License 2.0. See LICENSE.
当前认证方式
默认支持本地 credential 文件:
service_accountaccess_token
如果使用 service_account,需要把目标 Google Doc / Google Sheet / Google Slide 分享给该服务账号邮箱。
如何获得 google-service-account.json
当前项目默认推荐用 service_account 做最小闭环,因为它最适合“本地放一个 credential 文件,然后 MCP 直接调用 Google Docs API”这种工作方式。
1. 准备一个 Google Cloud Project
打开 Google Cloud Console。
新建一个项目,或者选中你已有的项目。
后续所有 API、Service Account 和 key 都会绑定在这个项目下。
2. 启用 Google Docs API / Google Sheets API / Google Slides API
在当前项目里启用 Google Docs API。
如果你要使用当前已经支持的 Google Sheet 读取,也要启用 Google Sheets API。
如果你要使用当前已经支持的 Google Slide 读取和写入,也要启用 Google Slides API。
如果你在创建 key 时遇到 IAM 相关页面不可用,也可以顺手确认 IAM API 是否已启用。
3. 创建 Service Account
进入
IAM & Admin->Service Accounts。点击
Create service account。填写:
Service account name可选的
Description
点击
Done,或者按需继续给它分配项目级角色。
创建完成后,Google 会给这个 service account 分配一个邮箱,格式通常像:
your-service-account-name@your-project-id.iam.gserviceaccount.com后面你需要把目标 Google Doc / Google Sheet / Google Slide 分享给这个邮箱。
3.1 在创建 Service Account 时,Permissions 该怎么选
Google Cloud 的创建向导里,Grant this service account access to project 这一步本身就是可选的。对我们这个项目当前的最小闭环来说,我建议这样选:
推荐选择
Grant this service account access to project: 不选任何角色,直接继续Service account users role field: 不填Service account admins role field: 不填
为什么这样选
这个 MCP 当前只是:
用 Google Docs API 读取指定 Google Doc
然后把内容同步到 Obsidian note
这类访问更适合靠两件事来控制:
项目里启用 Google Docs API
把具体 Google Doc 共享给 service account 邮箱
而不是一上来就给这个 service account 宽泛的项目级 IAM 角色。
什么时候才需要在这里选角色
只有当你明确希望这个 service account 去访问你项目里的其他 Google Cloud 资源时,才需要在这一步给它加项目级 IAM 角色。比如它将来要访问 GCS、BigQuery、Cloud Run 之类的资源。
对于当前这个项目:
只读 Google Doc: 不需要在这里给项目角色
未来要改写 Google Doc: 仍然通常不需要在这里给项目角色;更重要的是把目标 Google Doc 共享给这个 service account,并在本项目配置中把 scope 从只读切到可编辑
你作为操作者自己需要的权限
这里要区分两类权限:
“service account 自己拥有什么权限”
“你有没有权限创建它、给它生成 key”
如果你是创建者,Google 官方列出的常见前置权限是:
创建 service account:
Create Service Accounts/roles/iam.serviceAccountCreator如果你想在创建时顺手给它项目角色:
Project IAM Admin/roles/resourcemanager.projectIamAdmin创建 service account key:
Service Account Key Admin/roles/iam.serviceAccountKeyAdmin启用 API:
Service Usage Admin/roles/serviceusage.serviceUsageAdmin
如果公司策略禁止创建 service account key,你可能即使能创建 service account,也看不到 Create new key,这时需要管理员额外放开组织策略。
4. 生成 JSON key 并下载
仍然在
Service Accounts页面里,点击你刚创建的 service account。打开
Keys标签页。点击
Add key->Create new key。选择
JSON。点击
Create。浏览器会下载一个 JSON 文件,这个文件就是我们要的 service account credential。
建议把下载下来的文件重命名为:
google-service-account.json然后放到仓库根目录下的:
secrets/google-service-account.json这样就能直接匹配当前默认配置。
5. 配置到本项目
确认 config/local.json 里这段路径是对的:
{
"google": {
"auth": {
"mode": "service_account",
"credentialPath": "../secrets/google-service-account.json"
}
}
}如果你把文件放在别的位置,改 credentialPath 就可以。
6. 把目标 Google Doc 分享给 Service Account
这一步很关键。
因为这个 MCP 之后是以 service account 身份访问 Google Docs API,所以如果目标文档本来不属于这个 service account,就需要把文档共享给它。
操作方式和给普通邮箱共享文档一样:
打开你的 Google Doc。
点击右上角
Share。把 service account 的邮箱加进去。
如果只是读取,至少给
Viewer权限;如果要支持Obsidian -> Google Doc覆盖写回,需要给Editor权限。
如果不做这一步,最常见结果就是调用 API 时返回 403 PERMISSION_DENIED。
7. 安全注意事项
这个 JSON key 下载后不能再次下载,所以建议立即备份到安全位置。
不要把
google-service-account.json提交到 git。不要把这个文件发到聊天工具、邮件或公共网盘。
如果你怀疑 key 泄漏,应该在 Google Cloud Console 里删除旧 key,然后重新创建一个新 key。
8. 常见问题
看不到 Create new key
通常是以下几种原因:
你没有足够的 Google Cloud 权限
当前组织策略禁止创建 service account key
你点开的不是具体 service account,而是列表页
先确认自己能进入该 service account 的 Keys 标签页。如果公司策略禁了 key,需要管理员放开,或者后面改成别的认证方案。
已经有 key,但读 Google Doc 还是报 403
优先检查:
目标 Google Doc 有没有共享给 service account 邮箱
Google Docs API 是否已启用
当前项目和你创建 key 的项目是否一致
报 404
通常检查:
Google Doc 链接是否正确
文档 ID 是否解析错了
当前 service account 是否真的有权访问这个文档
9. 官方文档
Create service accounts: https://cloud.google.com/iam/docs/service-accounts-create
Create and delete service account keys: https://cloud.google.com/iam/docs/keys-create-delete
Google Docs API quickstart: https://developers.google.com/workspace/docs/api/quickstart/nodejs
配置
直接编辑 config/local.json,或者参考 config/config.example.json:
Google 凭据路径
Obsidian vault 根目录
默认凭据路径指向仓库根目录下的 secrets/google-service-account.json。
如何把 google_workspace MCP 加到 ~/.codex/config.toml
如果你希望在 Codex 里直接把这个项目作为一个可调用的 MCP 使用,可以把它注册到全局 Codex 配置文件 ~/.codex/config.toml。
1. 打开全局 Codex 配置
找到这个文件:
~/.codex/config.toml如果文件已经存在,就在里面追加一个新的 mcp_servers.google_workspace 配置块。
2. 加入下面这段配置
把下面内容加入 ~/.codex/config.toml:
[mcp_servers.google_workspace]
command = "/opt/homebrew/bin/node"
args = ["/absolute/path/to/GoogleDoc MCP/src/index.js"]
startup_timeout_sec = 30.0
tool_timeout_sec = 120.0
[mcp_servers.google_workspace.env]
GOOGLE_WORKSPACE_MCP_CONFIG = "/absolute/path/to/GoogleDoc MCP/config/local.json"3. 按你的本机环境检查路径
上面这段配置里的 /absolute/path/to/GoogleDoc MCP 只是占位符。
请替换成你本机上这个项目的真实绝对路径,例如:
/Users/erik/Documents/GoogleDoc MCP请确认这几个路径在你机器上都成立:
command指向你本机可用的 Node 可执行文件args指向这个项目的 src/index.jsGOOGLE_WORKSPACE_MCP_CONFIG指向这个项目的 config/local.json
如果你的 Node 不在 /opt/homebrew/bin/node,可以先在终端里用 which node 找到真实路径,再替换掉这里的值。
4. 确认 config/local.json 已经可用
这个 MCP 启动时会读取:
/absolute/path/to/GoogleDoc MCP/config/local.json你需要确保里面至少配置好了:
Google 认证方式
credentialPathscopesObsidian vault 根目录
如果你使用 service_account,也要确认 credentialPath 对应的 JSON key 文件已经放好。
如果你要读取 Google Sheet,并支持 Google Doc / Google Slide 写入,scopes 至少要包含:
[
"https://www.googleapis.com/auth/documents",
"https://www.googleapis.com/auth/spreadsheets.readonly",
"https://www.googleapis.com/auth/presentations"
]5. 重启 Codex
改完 ~/.codex/config.toml 后,建议直接重启 Codex App。
这样最稳妥,因为新加的 MCP server 一般需要在 Codex 重新启动后才会被完整加载。
6. 验证是否接入成功
重启后,你就可以在 Codex 里尝试调用这个 MCP 提供的工具,例如:
google_doc_readgoogle_doc_writegoogle_sheet_readgoogle_slide_readgoogle_slide_writegoogle_slide_apply_sheet_mappingsobsidian_note_writeobsidian_sync_google_docobsidian_sync_google_doc_ssot
如果工具能被识别,说明 google_workspace MCP 已经接入成功。
8. 仓库里的本地文件说明
下面这些文件或目录默认不会提交到 git:
secrets/config/local.json.codex/.learnings/
这样做是为了避免把 service account key、本机调试配置和私有运行痕迹一起推到远端仓库。
7. 常见问题
配置改了,但 Codex 里还是看不到工具
优先检查:
~/.codex/config.toml里的 TOML 语法是否正确command的 Node 路径是否真实存在args里的src/index.js路径是否正确GOOGLE_WORKSPACE_MCP_CONFIG指向的local.json是否存在Codex 是否已经完全退出并重新打开
MCP 启动了,但调用 Google API 失败
优先检查:
credentialPath是否正确service account key 是否有效
目标 Google Doc 是否已经共享给 service account 邮箱
Google Docs API / Sheets API / Slides API 是否已经在对应 GCP 项目中启用
Google Sheet 读取
google_sheet_read 支持这几种最小输入方式:
直接传 Google Sheet URL
传 spreadsheet id
结合
sheet指定页签名结合
gid指定页签 id结合
range指定 A1 区间
示例:
{
"source": {
"url": "https://docs.google.com/spreadsheets/d/your-sheet-id/edit#gid=0"
}
}{
"source": {
"id": "your-sheet-id",
"sheet": "Sheet1",
"range": "A1:F20"
}
}返回结果里会包含:
titlesheetTitlesheetIdrequestedRangemarkdownplainTextrowsavailableSheets
Google Doc 读取与写入
google_doc_read 会返回:
titlemarkdownplainTexttabs
google_doc_write 会用传入的 markdown 或 text 覆盖 Google Doc 正文。
当前写入侧会优先保留这些结构:
Markdown 标题
普通段落
无序列表
有序列表
引用块
代码块
粗体、斜体、删除线
行内代码
Markdown 链接
Markdown 表格会退化成可读文本行
当前不做复杂结构保真:
Google Doc tabs 写回
更复杂的嵌套 markdown 组合样式
真正的 Google Doc 表格重建
示例:
{
"source": {
"url": "https://docs.google.com/document/d/your-doc-id/edit"
},
"markdown": "# Weekly Update\n\n- Item A\n- Item B"
}Google Slide 读取与写入
google_slide_read 会返回:
presentation 标题
revisionId每一页的
slideNumber每一页的
objectIdslide 内文本归一化后的
markdownslide 内 page element 的结构化信息
google_slide_write 当前支持三种最小写法:
replace_all_text适合按占位符批量替换文本,可选限定到某一页replace_shape_text适合按 shape 的object_id精准替换某一个文本框的全部内容replace_table_cell_text适合按 table 的object_id精准替换某个单元格的全部内容,row_index/column_index使用 0-based 索引
示例:
{
"source": {
"url": "https://docs.google.com/presentation/d/your-slide-id/edit"
}
}{
"source": {
"id": "your-slide-id"
},
"operations": [
{
"mode": "replace_all_text",
"match_text": "{{owner}}",
"replace_text": "Erik",
"slide_number": 2
},
{
"mode": "replace_shape_text",
"object_id": "g2b7c9d1e0f_0_12",
"text": "Updated content from MCP"
},
{
"mode": "replace_table_cell_text",
"object_id": "g3f23f6f4d08_0_3",
"row_index": 1,
"column_index": 3,
"text": "4/22"
}
]
}Google Sheet 驱动 Google Slide 更新
google_slide_apply_sheet_mappings 会先读取 Google Sheet,再把表格里的映射规则应用到 Google Slide。
默认推荐的最小表头:
mode | placeholder | value | slide | object_id | text | enabled使用规则:
mode = replace_all_text需要placeholder和valuemode = replace_shape_text需要object_id和textslide可填 slide number,例如2;也可直接填 slide 的objectIdenabled可填true/false
示例:
{
"presentation": {
"url": "https://docs.google.com/presentation/d/your-slide-id/edit"
},
"sheet": {
"url": "https://docs.google.com/spreadsheets/d/your-sheet-id/edit#gid=0",
"sheet": "Mappings",
"range": "A1:G20"
}
}这个工具适合做两类事情:
用 Sheet 统一管理 Slide 占位符替换
用 Sheet 精准指定某个文本框
object_id的最终内容
启动
node src/index.js两套同步模板
模板 1:Obsidian md 为主,Google Doc 为辅
当你调用 obsidian_sync_google_doc 时,会读取 marker 内的 markdown 内容,并直接覆盖 Google Doc 正文。
示例见:
模板写法:
---
google_doc_sync_url: https://docs.google.com/document/d/your-doc-id/edit
google_doc_sync_direction: obsidian_to_google_doc
google_doc_sync_heading: "## Obsidian Primary Sync"
google_doc_sync_start_marker: "<!-- google-doc-sync:start -->"
google_doc_sync_end_marker: "<!-- google-doc-sync:end -->"
---
# 我的笔记
这里是 Obsidian 自有内容,不参与同步。
## Obsidian Primary Sync
<!-- google-doc-sync:start -->
# 这一段以 Obsidian 为准
这里的内容会覆盖 Google Doc 正文。
<!-- google-doc-sync:end -->模板 2:Google Doc 为主,Obsidian md 为辅
当你调用 obsidian_sync_google_doc 时,会读取 Google Doc 最新内容,只更新 marker 内的区块,保留 Obsidian 其他人工内容。
示例见:
模板写法:
---
google_doc_sync_url: https://docs.google.com/document/d/your-doc-id/edit
google_doc_sync_direction: google_doc_to_obsidian
google_doc_sync_heading: "## Google Doc Primary Sync"
google_doc_sync_start_marker: "<!-- google-doc-sync:start -->"
google_doc_sync_end_marker: "<!-- google-doc-sync:end -->"
---
# 我的笔记
这里是 Obsidian 自有内容,不会被覆盖。
## Google Doc Primary Sync
<!-- google-doc-sync:start -->
<!-- google-doc-sync:end -->模板 3:只比较,不改任一边文档
当你调用 obsidian_sync_google_doc 且方向为 compare_only 时,MCP 会读取 Google Doc 与 Obsidian marker 区块内容,输出差异总结,但不会修改 Google Doc,也不会修改 Obsidian note。
示例见:
模板写法:
---
google_doc_sync_url: https://docs.google.com/document/d/your-doc-id/edit
google_doc_sync_direction: compare_only
google_doc_sync_heading: "## Compare Only Sync"
google_doc_sync_start_marker: "<!-- google-doc-sync:start -->"
google_doc_sync_end_marker: "<!-- google-doc-sync:end -->"
---
# 我的笔记
这里是 Obsidian 自有内容,不参与比较结果写回。
## Compare Only Sync
<!-- google-doc-sync:start -->
# 当前 Obsidian 区块
只做差异比较,不做同步覆盖。
<!-- google-doc-sync:end -->返回结果会包含:
comparison.exactMatch:两边是否完全一致comparison.comparisonStatus:match、different或managed-block-missingcomparison.hunks:差异分段预览,便于后续人工判断要不要同步modifiedTargets: []:明确表示这次没有改动任何目标
调用方式
推荐直接调用:
{
"note_path": "/absolute/path/to/your-note.md"
}工具会自动读取 note frontmatter 里的:
google_doc_sync_urlgoogle_doc_sync_directiongoogle_doc_sync_start_markergoogle_doc_sync_end_markergoogle_doc_sync_heading
如果你想临时覆盖方向,也可以显式传:
{
"note_path": "/absolute/path/to/your-note.md",
"direction": "obsidian_to_google_doc"
}比较模式也可以这样显式调用:
{
"note_path": "/absolute/path/to/your-note.md",
"direction": "compare_only"
}旧版 SSOT 模板
---
google_doc_ssot_url: https://docs.google.com/document/d/your-doc-id/edit
---
# 我的笔记
这里是我自己维护的内容,不会在同步时被覆盖。
## Google Doc SSOT Sync
<!-- google-doc-ssot:start -->
<!-- google-doc-ssot:end -->同步行为
obsidian_sync_google_doc_ssot 现在是兼容旧调用的别名:
如果 note 没配置方向,默认按
Google Doc -> Obsidian如果 note 明确配置了
google_doc_sync_direction: obsidian_to_google_doc,也会按该方向执行,不再强制覆盖成Google Doc -> Obsidiannote 其他内容保持不变
如果没有同步区块,会自动在文末追加
如果检测到这次更新只是 Doc 尾部新增内容,会在返回结果里标记为
append-only
obsidian_sync_google_doc 是更通用的新入口:
当
google_doc_sync_direction = google_doc_to_obsidian时,行为类似旧版obsidian_sync_google_doc_ssot当
google_doc_sync_direction = obsidian_to_google_doc时,会把 marker 区块内容覆盖写回 Google Doc当
google_doc_sync_direction = compare_only时,只返回 Google Doc 与 Obsidian marker 区块的差异总结,不修改任一边文档
当前 MCP 不做后台文件监听。
“修改后直接同步”指的是调用 MCP 工具时立即按模板方向同步
不会在你编辑 note 或 Google Doc 的瞬间自动后台触发
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/erikwu/GoogleDocMCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server