·

Google Sheets MCP With OpenCode

Set up Google Sheets MCP in OpenCode so your AI agent can read and write spreadsheet data right from your editor.

OpenCode's MCP support is functional but younger than Claude Code's, and Google Sheets is a good integration to test that maturity against, since it exercises tool-call payload sizes, OAuth-flow subprocess handling, and multi-step tool chaining all at once. This topic covers wiring it up, the day-to-day read/write loop, a full worked example building a requirements traceability matrix, and — honestly — where OpenCode currently falls short of Claude Code for this particular MCP.

Installing and Connecting Google Sheets MCP to OpenCode

OpenCode reads MCP server definitions from opencode.json (project-level) or ~/.config/opencode/opencode.json (global). Add the Google Sheets server as a local MCP type since it runs as a subprocess over stdio:

{
  "mcp": {
    "google-sheets": {
      "type": "local",
      "command": ["npx", "-y", "@gongrzhe/server-gsheets-mcp"],
      "environment": {
        "GOOGLE_CREDENTIALS_PATH": "/Users/you/.config/google-sheets-mcp/credentials.json",
        "GOOGLE_TOKEN_PATH": "/Users/you/.config/google-sheets-mcp/token.json"
      },
      "enabled": true
    }
  }
}

If you're on the Python server instead, swap the command array:

{
  "mcp": {
    "google-sheets": {
      "type": "local",
      "command": ["uvx", "mcp-google-sheets"],
      "environment": {
        "SERVICE_ACCOUNT_PATH": "/Users/you/.config/google-sheets-mcp/service-account.json"
      },
      "enabled": true
    }
  }
}

Unlike Claude Code, OpenCode doesn't have a first-class /mcp inspector command in every version — check tool availability by opening a session and asking directly:

List the MCP tools you currently have access to for google-sheets.

If nothing comes back, the most common cause in OpenCode specifically is the subprocess failing to start because of a relative path in command — use absolute paths for credential files in the environment block; OpenCode's working directory when it spawns the MCP subprocess isn't always your shell's cwd, and a relative ./credentials.json resolves against the wrong directory more often than you'd expect.

Complete the OAuth consent flow the same way as any other client: run the server binary once directly from your terminal before wiring it into OpenCode, so the browser consent screen fires in an environment where it's not competing with OpenCode's own process management.

npx -y @gongrzhe/server-gsheets-mcp

Tips
- Use absolute paths everywhere in the environment block for this server — OpenCode's subprocess cwd handling is the single most common cause of "server won't start" reports for local MCP servers.
- Run the server binary standalone once to complete OAuth before ever wiring it into OpenCode's config — debugging a failed browser consent flow through OpenCode's process management is much harder than debugging it directly.
- Keep opencode.json project-scoped (checked in with placeholder env values) separate from your global config holding real credential paths, the same separation you'd want in Claude Code's .mcp.json.


Reading and Updating Sheet Data from OpenCode

The read/write loop in OpenCode works the same at the protocol level as any other client — the differences are in how reliably OpenCode chains multi-step tool sequences without you re-stating context.

Read range Tracker!A2:E80 from spreadsheet 1AbCdEfGhIjKlMnOpQrStUvWxYz.
Column B is status (values: Open, In Progress, Done, Blocked).
Count rows by status and tell me which rows are Blocked, including
their row number.

OpenCode handles single reads and single writes reliably. Where it's noticeably less consistent than Claude Code is multi-step chains that require it to hold intermediate results across several tool calls without restating them — a prompt like "read this range, compute X, then read a second range, cross-reference, then write" is more likely to drop or garble an intermediate value partway through in OpenCode, depending on model and version. The practical mitigation: break multi-hop workflows into explicit numbered steps in the prompt itself, and confirm each step's output before moving to the next, rather than relying on the agent to self-sequence a complex chain silently.

Step 1: Read Tracker!A2:E80. Show me the raw table.
Step 2: From that table, list rows where status = "Blocked".
Step 3: For those rows only, write "ESCALATED" into column F
of the matching row numbers.

For writes, the same guardrails from earlier topics apply without modification — narrow ranges, confirm the destination is empty or matches expectation, use RAW for computed values:

Write "ESCALATED" to F5, F12, F31 in the Tracker sheet.
Confirm each cell was empty before writing — if any already has a value,
tell me instead of overwriting.

Tips
- Break multi-hop read-compute-read-write workflows into explicit numbered steps in the prompt — OpenCode is noticeably more reliable per-step than as a single implicit chain.
- Confirm intermediate outputs (row counts, filtered lists) in chat before letting a subsequent step act on them — cheap insurance against a dropped intermediate value.
- For anything beyond a handful of target cells, use batch_update_cells in one call rather than issuing many single-cell update_cells calls — fewer round trips means fewer chances for a chain to lose its place.


Practical Example: Building a Requirements Traceability Matrix

This is a genuinely good fit for Google Sheets MCP, because a requirements traceability matrix (RTM) is exactly the kind of structured-but-manually-maintained artifact where an agent reading source documents and populating a sheet saves real hours.

Setup: a spreadsheet with tabs Requirements (columns: req_id, description, priority) and Tests (columns: test_id, test_name, covers_req_id). You want a third tab, RTM, cross-referencing them.

Step 1: Read Requirements!A2:C60 and Tests!A2:C120.

Step 2: Build a traceability table where each row is one requirement,
with columns: req_id, description, priority, test_count (number of
tests where covers_req_id matches), test_ids (comma-separated list).
Flag priority="High" requirements with test_count=0 as "UNCOVERED".

Step 3: Show me the table in chat, specifically calling out any
UNCOVERED rows, before writing anything.

Review the UNCOVERED list — this is your actual finding, and it's worth pausing on before committing to a sheet. Then commit:

Step 4: Create a new tab called "RTM" if it doesn't exist.
Write headers "Requirement ID", "Description", "Priority", "Test Count",
"Test IDs", "Coverage Status" to RTM!A1:F1.
Write the table data starting at RTM!A2, one row per requirement.
Use valueInputOption RAW.

A refinement worth doing once you trust the base flow: source requirement descriptions from actual code or PR content rather than a manually maintained Requirements tab, closing the loop between what's shipped and what's tracked:

Cross-reference Requirements!A2:C60 against the last 90 days of merged
PRs in this repo (use git log --since="90 days ago" --merges).
For each requirement, note whether any merged PR title or description
mentions the req_id. Flag requirements with priority="High" and no
matching PR as "NO_IMPLEMENTATION_FOUND" in the RTM output.

That last prompt only works because OpenCode has both the Google Sheets MCP tools and local shell/git access in the same session — a genuinely multi-tool workflow that's hard to replicate manually.

Tips
- Always surface UNCOVERED / NO_IMPLEMENTATION_FOUND rows in chat before writing the RTM tab — that finding is usually the actual point of running this, not the spreadsheet artifact itself.
- Rebuild the RTM tab wholesale each run (clear then rewrite the whole tab) rather than trying to diff-update it in place — traceability matrices are cheap to regenerate and expensive to reconcile incrementally.
- When cross-referencing against git history or code, be explicit about the lookback window and matching heuristic (title mention vs. description mention vs. commit message) — vague matching criteria produce false negatives that look like real coverage gaps.


Known Limitations for Google Sheets MCP in OpenCode

Worth stating plainly rather than glossing over:

  • Multi-step chain reliability. As noted above, OpenCode is more prone than Claude Code to losing intermediate context across long tool-call chains, particularly with smaller or faster models configured for cost reasons. Explicit step-by-step prompting mitigates this but doesn't eliminate it entirely.
  • No built-in MCP tool inspector in some versions. You can't always list a server's tools and schemas without asking the agent to enumerate them conversationally, which is a worse debugging experience than Claude Code's /mcp.
  • Subprocess environment quirks. The absolute-path requirement noted earlier isn't documented consistently and cost real debugging time in practice — it's the top OpenCode-specific gotcha for this integration.
  • Large-range reads are more likely to silently truncate. Where Claude Code will sometimes surface a truncation notice, OpenCode's handling of oversized tool responses is less consistent about surfacing that fact — pair large reads with an explicit row-count sanity check (confirm you received exactly 1200 rows) rather than trusting silence.
  • No first-class secrets management. Credential paths live in plain JSON config; there's no equivalent to a managed secrets store, so the same discipline (gitignore, absolute paths outside the repo) applies as with any local MCP config.

None of these are disqualifying — OpenCode remains a fully viable client for this MCP — but they shift the risk profile toward "verify more, trust silent success less" compared to running the same workflows in Claude Code.

Tips
- Treat OpenCode + Google Sheets MCP as needing more explicit verification steps per workflow than Claude Code, not fewer — budget for it in how you write prompts.
- Add an explicit row-count confirmation step after any read over a few hundred rows, since truncation is less visibly signaled here.
- If a workflow becomes a recurring, high-stakes pipeline (not exploratory work), consider whether it belongs in a scripted pipeline calling the Sheets API directly rather than staying an ad hoc agent session — OpenCode's chain reliability caveat matters more the more often a workflow runs unattended.


Tips

OpenCode handles Google Sheets MCP well for single-step and short two-step workflows; it needs more explicit scaffolding than Claude Code for longer chains, and the setup friction is concentrated in subprocess path handling rather than the Sheets API itself.

Tips
- Use absolute paths in every OpenCode MCP environment variable pointing at a credential file — this single habit prevents most connection failures.
- Decompose multi-step spreadsheet workflows into explicit numbered prompt steps, and confirm each step's output before proceeding.
- Reserve OpenCode + Google Sheets MCP for exploratory and moderate-complexity workflows; graduate genuinely recurring, high-stakes pipelines to a scripted integration once the logic is proven.