MCP server
gog mcp runs a Model Context Protocol server over stdio. It is for agent clients that need Google Workspace tools but should not receive a generic shell or arbitrary gog command bridge.
The server registers a small set of typed tools such as gmail_search, docs_get, and sheets_read_range. Each tool has a fixed schema, maps to one specific gog operation, and returns a structured result containing the tool name, service, risk level, exit code, parsed stdout, and stderr.
#Quick start
Start a read-only server for one account:
gog --account you@example.com mcp
List the tools this server would expose and exit:
gog --account you@example.com mcp --list-tools
Limit the server to Gmail search and Docs reads:
gog --account you@example.com mcp \
--allow-tool gmail_search,docs_get
Expose Docs read/write tools:
gog --account you@example.com mcp \
--allow-write \
--allow-tool 'docs.*'
--allow-write is always required for write tools. A write tool that matches --allow-tool is still hidden until --allow-write is present.
#Why this is not gog_exec
MCP clients are often LLM-driven. A generic "run this command" tool would expose every current and future CLI behavior through one broad capability, including commands that were not reviewed for MCP use.
gog mcp uses a narrower contract:
- no generic command execution tool
- no model-supplied argv passthrough
- fixed tool schemas validated before command execution, including required
- read-only tools by default
- write tools require explicit server startup flags
- existing
gogaccount, auth, dry-run, no-input, and command safety flags are
fields, types, and rejection of unknown fields
preserved
This keeps MCP useful for agents while making the permission surface visible at server startup.
#Tool selection
By default, all read tools are registered and write tools are hidden.
Use --allow-tool to narrow the registered set. Values can be comma-separated or repeated:
gog mcp --allow-tool gmail_search --allow-tool docs_get
gog mcp --allow-tool gmail_search,docs_get
Accepted selectors:
| Selector | Meaning |
|---|---|
gmail_search | One exact tool |
gmail | All Gmail tools allowed by risk mode |
gmail.* | All Gmail tools allowed by risk mode |
read | All read tools |
write | All write tools, only when --allow-write is also set |
* or all | All tools allowed by risk mode |
Examples:
# Read-only Gmail tools.
gog mcp --allow-tool gmail
# Only Docs tools, including writes.
gog mcp --allow-write --allow-tool 'docs.*'
# Read-only server, but only Calendar and Sheets reads.
gog mcp --allow-tool calendar,sheets
# All current write tools. Read tools are not included unless also selected.
gog mcp --allow-write --allow-tool write
#Initial tools
Read tools:
| Tool | Purpose |
|---|---|
gmail_search | Search Gmail messages with Gmail query syntax. |
gmail_get_message | Read one Gmail message by ID. Sanitized content is on by default. |
gmail_get_thread | Read one Gmail thread by ID. Sanitized content is on by default. |
drive_search | Search Drive files by text or Drive query language. |
drive_get | Read Drive file metadata by ID. |
docs_get | Read a Google Doc as wrapped text, optionally one tab or all tabs. |
sheets_read_range | Read values from a Sheets range. |
calendar_events | List Calendar events. |
Write tools, hidden unless --allow-write:
| Tool | Purpose |
|---|---|
docs_write | Append or replace Google Docs text, optionally as Markdown. |
sheets_update_range | Update values in a Sheets range from a literal JSON 2D array. |
The generated command reference for the server itself is gog mcp.
MCP clients discover the registered surface through the protocol's standard tools/list request. For shell-side inspection before starting the server, use gog mcp --list-tools; no model-callable discovery tool is added.
#Client configuration
MCP clients usually need a command and an argument list. Put account selection and safety policy on the server command, not inside tool calls.
Minimal stdio configuration:
{
"command": "gog",
"args": ["--account", "you@example.com", "mcp"]
}
Read-only Docs and Sheets configuration:
{
"command": "gog",
"args": [
"--account", "you@example.com",
"--enable-commands-exact", "mcp,docs.cat,sheets.get",
"mcp",
"--allow-tool", "docs_get,sheets_read_range"
]
}
Docs read/write configuration:
{
"command": "gog",
"args": [
"--account", "you@example.com",
"--enable-commands-exact", "mcp,docs.cat,docs.write",
"--no-input",
"mcp",
"--allow-write",
"--allow-tool", "docs.*"
]
}
For headless services, set GOG_KEYRING_BACKEND=file and GOG_KEYRING_PASSWORD on the MCP client process or service unit. A successful interactive shell check does not prove the MCP client inherited those variables; verify through the same process manager that launches the server.
#mcporter examples
List registered tools and their schemas:
mcporter list \
--stdio gog \
--stdio-arg --account \
--stdio-arg you@example.com \
--stdio-arg mcp \
--stdio-arg --allow-tool \
--stdio-arg 'docs.*' \
--schema \
--json
Dry-run a Docs write through MCP:
mcporter call \
--stdio gog \
--stdio-arg --account \
--stdio-arg you@example.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}'
Read a Sheet range:
mcporter call \
--stdio gog \
--stdio-arg --account \
--stdio-arg you@example.com \
--stdio-arg mcp \
--stdio-arg --allow-tool \
--stdio-arg sheets_read_range \
sheets_read_range \
'{"spreadsheet_id":"SPREADSHEET_ID","range":"Sheet1!A1:C10"}'
Update a Sheet range:
mcporter call \
--stdio gog \
--stdio-arg --account \
--stdio-arg you@example.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 must be literal JSON. MCP rejects @file, @-, and - expansion forms so a model cannot cause the server process to read arbitrary local files or stdin.
#Safety model
Tool calls run as subprocesses of the same gog executable. The server adds a non-interactive, agent-oriented root context to every child command:
--json--wrap-untrusted--no-input--color=never
The server also preserves selected parent root flags:
--account--client--home--dry-run--results-only--select- direct access tokens
And it preserves command safety flags:
--gmail-no-send--enable-commands--enable-commands-exact--disable-commands
Use both MCP tool allowlists and command allowlists when the server is exposed to an untrusted or semi-trusted agent:
gog --account you@example.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.*'
If a tool maps to a disabled command, the tool call returns a non-zero exit code and the child command error in stderr.
#Output shape
Successful calls return structured MCP content shaped like:
{
"tool": "docs_get",
"service": "docs",
"risk": "read",
"exit_code": 0,
"stdout": {
"documentId": "..."
},
"stderr": ""
}
If a child command prints valid JSON, stdout is parsed as JSON with numeric literals preserved. Otherwise stdout is returned as a string. Empty stdout is omitted.
If the child command exits non-zero, the MCP result is marked as an error and includes the same structured fields with exit_code and stderr.
#Limits and timeouts
Each tool call has a subprocess timeout and bounded stdout/stderr capture:
gog mcp --timeout-seconds 30 --max-output-bytes 262144
Defaults:
- timeout: 60 seconds
- max captured stdout/stderr: 102400 bytes each
Use command-specific limits too. For example, docs_get has a max_bytes argument, and search tools have max arguments.
#Authentication
The MCP server uses normal gog auth. Before wiring a client, verify the same account and scopes from a shell:
gog --account you@example.com auth doctor --check
gog --account you@example.com mcp --list-tools
Then verify through the MCP client entrypoint. In services and desktop MCP clients, most auth failures are environment inheritance problems: missing GOG_ACCOUNT, missing file-keyring password, different GOG_HOME, or a different OAuth client selected by --client.
#Troubleshooting
no MCP tools enabled
: Your --allow-tool filters excluded everything, or you selected only write tools without --allow-write.
command "..." is disabled
: The MCP tool was registered, but the child gog command was blocked by --enable-commands, --enable-commands-exact, --disable-commands, or a baked safety profile.
Tool missing in the client
: Run gog mcp --list-tools with the same flags. If the tool is not listed, fix --allow-tool or add --allow-write for write tools. If it is listed, refresh or restart the MCP client.
Auth works in Terminal but not in the MCP client
: Compare --account, --client, --home, GOG_HOME, GOG_KEYRING_BACKEND, and GOG_KEYRING_PASSWORD in the process that starts the MCP server.
Large output is truncated
: Increase --max-output-bytes, narrow the request, or use tool arguments such as max, max_bytes, date ranges, or Drive field masks.