
gogcli 的 MCP Server 实战指南用类型化、白名单化的工具安全接入 Google Workspace Agent【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcligog mcp是 gogcliGoogle Workspace in your terminal内置的 Model Context ProtocolMCP服务器它通过 stdio 运行向 LLM 驱动的 Agent 客户端暴露一组类型化、白名单化的 Google Workspace 工具例如gmail_search、docs_get、sheets_read_range。读完本文你将掌握如何启动只读/可写 MCP 服务、用--allow-tool与持久化策略收窄工具面、配置主流 MCP 客户端、理解结构化输出与安全模型并在真实环境里排查认证与工具不可见问题。为什么是gog mcp而不是通用的命令执行工具MCP 客户端的调用方通常是 LLM如果暴露一个通用的 run this command 工具等于把 CLI 当前和未来的所有行为都通过一个宽泛能力交出去其中可能包含从未针对 MCP 使用场景评审过的命令。因此gog mcp采用更窄的契约对应实现见 internal/cmd/mcp.go没有通用命令执行工具没有模型提供的 argv 直通测试TestMCPToolBuildArgsTypedOnly证明即使模型传入args字段也会被固定 schema 拦截见 internal/cmd/mcp_test.go每个工具拥有固定 schema在命令执行前完成校验包括必填字段、类型检查与未知字段拒绝测试TestMCPServerValidatesToolInputSchema验证了 unknown field / wrong type / missing required field 三种场景见 internal/cmd/mcp_test.go默认只暴露只读工具写工具必须显式通过服务启动参数开启保留现有的gog账户、认证、dry-run、no-input 以及命令安全相关的根参数。这样既让 Agent 能实际使用 Google Workspace又把权限面在服务启动时就完整、可见地暴露出来。快速开始为单一账户启动一个只读 MCP 服务gog --account youexample.com mcp列出该服务将暴露的工具并退出不会真正启动服务gog --account youexample.com mcp --list-tools把服务限制到 Gmail 搜索和 Docs 读取gog --account youexample.com mcp \ --allow-tool gmail_search,docs_get暴露 Docs 的读/写工具gog --account youexample.com mcp \ --allow-write \ --allow-tool docs.*--allow-write是写工具的必要条件即使某个写工具匹配了--allow-tool只要没有--allow-write它仍然会被隐藏。唯一的例外是显式的持久化 MCP 策略——它可以在不重复写--allow-write的前提下授权一个窄范围的写面而运行时参数只能在该已配置范围上继续收窄。如果最终启用的工具集为空服务会直接报错no MCP tools enabled并拒绝启动对应 internal/cmd/mcp.go。工具选择--allow-tool与选择器语法默认情况下所有只读工具都会被注册写工具被隐藏。--allow-tool用于收窄注册集合值可以是逗号分隔也可以重复传参gog mcp --allow-tool gmail_search --allow-tool docs_get gog mcp --allow-tool gmail_search,docs_get支持的选择器对应匹配逻辑mcpToolAllowed见 internal/cmd/mcp.go选择器含义gmail_search精确匹配单个工具gmail风险模式允许下的全部 Gmail 工具gmail.*风险模式允许下的全部 Gmail 工具read全部只读工具write全部写工具仅当同时设置了--allow-write才生效*或all风险模式允许下的全部工具使用示例# 只读的 Gmail 工具。 gog mcp --allow-tool gmail # 仅 Docs 工具含写入。 gog mcp --allow-write --allow-tool docs.* # 只读服务但只保留 Calendar 和 Sheets 读取。 gog mcp --allow-tool calendar,sheets # 当前全部写工具。未显式选择时不含读工具。 gog mcp --allow-write --allow-tool write持久化能力策略config.json 中的 mcp 块当有多个 MCP 客户端或多个账户时可以把最大注册工具面写进config.json的mcp块而不是在每个客户端定义里重复能力参数。注意没有mcp块时行为不变——所有只读工具可用、写操作需要--allow-write、--allow-tool继续过滤。配置结构定义见 internal/config/config.go。{ mcp: { allow_tools: [read], allow_write: false, accounts: { personalexample.com: { allow_tools: [read, docs.*, calendar.*], allow_write: true }, workexample.com: { allow_tools: [read], allow_write: false } } } }关键规则由 internal/cmd/mcp_policy.go 的实现与测试TestMCPPolicyAccountReplacesGlobalAndEnablesNarrowWrites等印证见 internal/cmd/mcp_test.go账户条目是对全局策略的完整替换而不是部分合并。选中某账户后只会使用该账户自己的策略。账户键在解析别名与自动账户选择之后做大小写不敏感匹配然后把解析出的账户固定用于每个 MCP 子命令。按账户的策略要求已存储的账户凭据直接访问令牌access token和 ADCApplication Default Credentials只能用全局策略——因为在这些模式下账户标签无法证明已认证主体测试TestMCPPolicyAccountResolutionPinsAliasAndRejectsUnverifiableIdentity验证了这一点。allow_tools缺省时默认为[read]显式空列表会被拒绝。allow_write: true要求显式给出工具列表避免笔误意外暴露全部写工具。重复的账户键忽略大小写与空白后会报错所有选择器必须能匹配到至少一个工具包括未被选中的账户里的无效选择器也会在校验阶段被拒绝见 internal/cmd/mcp_test.go。已配置的策略是上限--allow-tool只能与它求交集得到更小的运行时集合--readonly会移除所有写操作--allow-write不能扩大一个只读策略--allow-write cannot widen the configured MCP policy。烘焙的安全配置baked safety profiles见 safety-profiles 目录下的agent-safe.yaml、readonly.yaml、full.yaml始终是最外层不可变上限。未知的选择器和试图扩大写权限的操作都会在 MCP 服务启动前失败。用与生产环境相同的账户和参数运行gog mcp --list-tools即可检查最终注册面。初始工具集只读工具默认注册工具用途gmail_search用 Gmail 查询语法搜索邮件。gmail_get_message按 ID 读取单封邮件默认开启净化内容。gmail_get_thread按 ID 读取单个邮件线程默认开启净化内容。drive_search按文本或 Drive 查询语言搜索文件。drive_get按 ID 读取 Drive 文件元数据。docs_get以包装文本形式读取 Google Doc可选单标签页或全部标签页。sheets_read_range读取 Sheets 某个范围的值。calendar_events列出日历事件。写工具隐藏除非设置--allow-write工具用途docs_write追加或替换 Google Docs 文本可选 Markdown 格式。sheets_update_range以字面 JSON 二维数组更新 Sheets 某个范围的值。每个工具的固定 schema参数名、必填项、默认值、取值范围都定义在 internal/cmd/mcp_tools.go 中例如gmail_search必填querymax默认 10、范围 1–100可选include_body。docs_get必填document_idtab与all_tabs互斥max_bytes默认 2000000、上限 20000000。docs_write必填document_id与textappend与replace互斥appendfalse且未replace时直接报错markdown可选。sheets_read_range必填spreadsheet_id与rangerender枚举FORMATTED_VALUE/UNFORMATTED_VALUE/FORMULA。sheets_update_range必填values_json必须是字面 JSON 二维数组input默认USER_ENTERED。服务自身的生成版命令参考是 gog mcp其中列出了全部可用 flag 及其默认值。MCP 客户端通过协议标准的tools/list请求发现注册面启动前想在 shell 侧检查则用gog mcp --list-tools服务不会额外添加一个可由模型调用的发现工具。客户端配置MCP 客户端通常需要一个 command 与参数列表。账户选择和安全策略应放在服务命令上而不是放进工具调用里。最小 stdio 配置{ command: gog, args: [--account, youexample.com, mcp] }只读的 Docs 与 Sheets 配置同时用命令白名单收窄{ command: gog, args: [ --account, youexample.com, --enable-commands-exact, mcp,docs.cat,sheets.get, mcp, --allow-tool, docs_get,sheets_read_range ] }Docs 读写配置{ command: gog, args: [ --account, youexample.com, --enable-commands-exact, mcp,docs.cat,docs.write, --no-input, mcp, --allow-write, --allow-tool, docs.* ] }无头服务场景在 MCP 客户端进程或服务单元上设置GOG_KEYRING_BACKENDfile和GOG_KEYRING_PASSWORD。一次成功的交互式 shell 检查并不能证明 MCP 客户端继承了这些变量务必通过启动服务器的同一个进程管理器来验证。mcporter 使用示例列出已注册工具及其 schemamcporter list \ --stdio gog \ --stdio-arg --account \ --stdio-arg youexample.com \ --stdio-arg mcp \ --stdio-arg --allow-tool \ --stdio-arg docs.* \ --schema \ --json通过 MCP 对 Docs 写入做 dry-runmcporter call \ --stdio gog \ --stdio-arg --account \ --stdio-arg youexample.com \ --stdio-arg --dry-run \ --stdio-arg mcp \ --stdio-arg --allow-write \ --stdio-arg --allow-tool \ --stdio-arg docs_write \ docs_write \ {document_id:DOCUMENT_ID,text:MCP smoke test\n,append:true}读取一个 Sheet 范围mcporter call \ --stdio gog \ --stdio-arg --account \ --stdio-arg youexample.com \ --stdio-arg mcp \ --stdio-arg --allow-tool \ --stdio-arg sheets_read_range \ sheets_read_range \ {spreadsheet_id:SPREADSHEET_ID,range:Sheet1!A1:C10}更新一个 Sheet 范围mcporter call \ --stdio gog \ --stdio-arg --account \ --stdio-arg youexample.com \ --stdio-arg mcp \ --stdio-arg --allow-write \ --stdio-arg --allow-tool \ --stdio-arg sheets_update_range \ sheets_update_range \ {spreadsheet_id:SPREADSHEET_ID,range:Sheet1!A1:B1,values_json:[[\status\,\ok\]],input:RAW}注意sheets_update_range.values_json必须是字面 JSON。MCP 侧会拒绝file、-与-展开形式防止模型让服务进程读取任意本地文件或 stdin实现见requireMCPLiteralValuesJSONinternal/cmd/mcp_tools.go测试TestMCPSheetsUpdateRejectsFileExpansion、TestMCPSheetsUpdatePreservesLargeJSONNumbers、TestMCPSheetsUpdateRejectsTrailingJSON见 internal/cmd/mcp_test.go。同时该函数会对 JSON 做规范化canonicalize并拒绝尾随内容。安全模型子进程、根参数与双重白名单工具调用以同一个gog可执行文件的子进程方式运行exec.CommandContext见 internal/cmd/mcp.goargv 来自类型化工具 schema 而非模型提供的 shell 文本。服务器会给每个子命令附加一个面向 Agent 的非交互根上下文--json--wrap-untrusted--no-input--colornever同时保留选定的父级根参数mcpParentRootArgs见 internal/cmd/mcp.go--account--client--home--dry-run--results-only--select直接访问令牌通过环境变量GOG_ACCESS_TOKEN传递并保留命令安全参数mcpParentSafetyArgs见 internal/cmd/mcp.go--gmail-no-send--enable-commands--enable-commands-exact--disable-commands当服务暴露给不可信或半可信的 Agent 时应同时使用MCP 工具白名单和命令白名单gog --account youexample.com \ --enable-commands-exact mcp,docs.cat,docs.write \ --disable-commands gmail.send,gmail.drafts.send \ --gmail-no-send \ mcp \ --allow-write \ --allow-tool docs.*如果某个工具映射到的命令被禁用工具调用会返回非零退出码并把子命令错误写入stderr。输出结构成功的调用返回结构化 MCP 内容形如{ tool: docs_get, service: docs, risk: read, exit_code: 0, stdout: { documentId: ... }, stderr: }如果子命令输出合法 JSONstdout会被解析为 JSON 且保留数字字面量UseNumber否则以字符串返回空 stdout 会被省略parseMCPStdout见 internal/cmd/mcp.go。如果子命令非零退出MCP 结果会被标记为错误并包含同样的结构化字段exit_code与stderr。超时场景退出码为 124。上述结构化结果的 Go 定义是mcpCommandResult见 internal/cmd/mcp.go其字段包括工具名、服务、风险等级、退出码、stdout 与 stderr。限制与超时每次工具调用都有子进程超时与受限的 stdout/stderr 捕获gog mcp --timeout-seconds 30 --max-output-bytes 262144默认值超时60 秒捕获的 stdout/stderr 上限各 102400 字节超出上限的内容会被截断并追加... [output truncated]标记mcpLimitedBuffer还保证只输出合法 UTF-8见 internal/cmd/mcp.go测试TestMCPLimitedBufferCapsDuringWrite见 internal/cmd/mcp_test.go。此外建议使用命令级限制例如docs_get有max_bytes参数搜索类工具有max参数。认证MCP 服务器使用常规的gog认证。在接线客户端之前先从 shell 验证同一个账户与 scopegog --account youexample.com auth doctor --check gog --account youexample.com mcp --list-tools然后再通过 MCP 客户端入口验证。在服务与桌面 MCP 客户端中大多数认证失败本质上是环境继承问题缺少GOG_ACCOUNT、缺少文件型 keyring 密码、不同的GOG_HOME或由--client选择了不同的 OAuth 客户端。故障排查no MCP tools enabled--allow-tool过滤排除了所有工具或只选了写工具却没有--allow-write。command ... is disabledMCP 工具已注册但子gog命令被--enable-commands、--enable-commands-exact、--disable-commands或烘焙的安全配置拦截。客户端里看不到工具用相同参数运行gog mcp --list-tools。如果工具不在列表里修正--allow-tool或对写工具加--allow-write如果工具在列表里刷新或重启 MCP 客户端。终端里认证正常但 MCP 客户端里失败对比启动 MCP 服务器的进程中的--account、--client、--home、GOG_HOME、GOG_KEYRING_BACKEND、GOG_KEYRING_PASSWORD。大输出被截断调大--max-output-bytes收窄请求或使用工具的max、max_bytes、日期范围、Drive 字段掩码等参数。小结gog mcp的核心设计是把模型可调用的工具面与CLI 的全部能力面彻底解耦固定 schema 的类型化工具、默认只读、显式开启写、持久化策略做天花板、运行时参数只能收窄、每个调用以带超时与输出上限的子进程运行并叠加命令级白名单。对于需要在 Agent 场景中使用 Gmail、Docs、Sheets、Drive 与 Calendar又不希望给模型一把通用 shell 的开发者来说这套机制既实用又可在启动时审计。相关实现、测试与配置参考internal/cmd/mcp.go、internal/cmd/mcp_tools.go、internal/cmd/mcp_policy.go、internal/cmd/mcp_test.go、internal/config/config.go、safety-profiles。【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考