Reference

MCP server

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
  • fields, types, and rejection of unknown fields

  • read-only tools by default
  • write tools require explicit server startup flags
  • existing gog account, auth, dry-run, no-input, and command safety flags are
  • 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:

SelectorMeaning
gmail_searchOne exact tool
gmailAll Gmail tools allowed by risk mode
gmail.*All Gmail tools allowed by risk mode
readAll read tools
writeAll write tools, only when --allow-write is also set
* or allAll 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:

ToolPurpose
gmail_searchSearch Gmail messages with Gmail query syntax.
gmail_get_messageRead one Gmail message by ID. Sanitized content is on by default.
gmail_get_threadRead one Gmail thread by ID. Sanitized content is on by default.
drive_searchSearch Drive files by text or Drive query language.
drive_getRead Drive file metadata by ID.
docs_getRead a Google Doc as wrapped text, optionally one tab or all tabs.
sheets_read_rangeRead values from a Sheets range.
calendar_eventsList Calendar events.

Write tools, hidden unless --allow-write:

ToolPurpose
docs_writeAppend or replace Google Docs text, optionally as Markdown.
sheets_update_rangeUpdate 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.