Skip to main content
Glama

sheetcraft-mcp

Google Sheets MCP server + CLI for AI agents — 34 tools across 6 opt-in toolsets. One shared engine, two surfaces:

  • MCP server — for chat agents (Claude Desktop, Claude Code, OpenCode, any MCP client). Tools appear in the agent's tool list and are permission-gateable.

  • CLI (sheets) — for scripts, pipes, and bulk work. Same 34 operations, same auth, same errors, one process per command.

Designed for agent reliability: teaching errors (a bad range returns an example + the list of available sheets, not a stack trace), token-efficient reads (CSV defaults, hard cell caps, explicit truncation notices), and write echoes (updatedRange/updatedCells on every write so the agent closes its own loop without a verification read).


Requirements

  • Node ≥ 20

  • A Google account, and either an OAuth Client ID (recommended — see Option A) or a service account key (see Option B)

  • Works on Linux, macOS, and Windows (all paths resolve under your home directory)

Related MCP server: Google Sheets MCP Server

Install

# Run directly with npx — no install step
npx sheetcraft-mcp@latest --help

# or install globally — then use the `sheets` and `sheets-mcp` commands
npm install -g sheetcraft-mcp

Three commands are installed:

Command

What it is

sheets

The CLI

sheets-mcp

The MCP server (stdio)

sheetcraft-mcp

Both — with arguments it runs the CLI, with none it starts the MCP server. This is what MCP configs use (npx sheetcraft-mcp@latest).

Quick start

1. Add the MCP config (OpenCode example; Claude Desktop and others in MCP configuration):

// opencode.json
{
  "mcp": {
    "sheets": {
      "type": "local",
      "command": ["npx", "-y", "sheetcraft-mcp@latest"],
      "enabled": true
    }
  }
}

2. Authenticate once (in a terminal — see Authentication for details):

npx sheetcraft-mcp@latest auth login

A browser opens → you consent → done. Tokens persist and auto-refresh; the MCP config itself contains no secrets.

3. Use it. In agents with terminal access (OpenCode, Claude Code), the agent can do this whole setup itself: the first Sheets tool call without credentials returns a teaching message that says exactly what to run. Tools appear as sheets_get_values, sheets_update_values, etc.


Authentication

Two modes. Pick one.

Option A: OAuth

Option B: Service account

Acts as

You (your Google account)

A robot account

Can create/copy spreadsheets

✅ Yes

❌ No (Google gives SAs a 0-byte storage quota)

Setup

Browser consent, once

Env vars + manual sharing of each file

Recommended for

Personal use, agents that create files

CI, servers, headless setups

The two-file mental model

OAuth confuses everyone exactly once — when they see two JSON files. Here is the whole thing:

client_secret_xxx.json   your APP's identity with Google  → used ONCE by `auth login`
oauth-tokens.json        YOUR logged-in session           → created automatically, auto-refreshes

The client_secret_*.json you download from Google is not a credential for the MCP config or env — it's the key fob that lets the tool open a login flow. It's consumed once by auth login; after that the saved token does all the work and you can even delete the JSON.

1. In Google Cloud Console:

  • Enable Google Sheets API and Google Drive API

  • Create Credentials → OAuth client ID → Desktop app → download the JSON

2. Hand the file to auth login — any one of these three ways:

# (a) zero file moves — point at the download directly:
npx sheetcraft-mcp@latest auth login --client ~/Downloads/client_secret_xxx.json

# (b) or park it in the config dir once, then plain login forever after:
mkdir -p ~/.config/sheetcraft-mcp
cp ~/Downloads/client_secret_xxx.json ~/.config/sheetcraft-mcp/oauth-client.json
npx sheetcraft-mcp@latest auth login

# (c) or skip the file — set the values it contains as env vars:
#     GOOGLE_OAUTH_CLIENT_ID=…xxx.apps.googleusercontent.com
#     GOOGLE_OAUTH_CLIENT_SECRET=…
npx sheetcraft-mcp@latest auth login

3. Browser opens → consent → done. Verify:

npx sheetcraft-mcp@latest auth status

Tokens persist at ~/.config/sheetcraft-mcp/oauth-tokens.json (permissions 0600) and auto-refresh on every use.

Useful auth commands:

npx sheetcraft-mcp@latest auth status   # which mode is active, which email
npx sheetcraft-mcp@latest auth logout   # delete stored tokens

Switching accounts: run auth logout first — auth login refuses to overwrite an existing session otherwise (pass --force to override).

Option B: Service account — edit-only on shared files

  1. In Cloud Console: create a service account, create a JSON key for it, enable the Sheets API.

  2. Point the server at the key:

export GOOGLE_SERVICE_ACCOUNT_CREDENTIALS="$(cat service-account.json)"
# or: export GOOGLE_SERVICE_ACCOUNT_FILE=/path/to/key.json
  1. Share spreadsheets with the SA's email like any collaborator. It can read and edit but cannot create files — use OAuth for that.

Which mode wins

If both are configured: SHEETS_AUTH_MODE=oauth|service-account forces a mode; otherwise service-account env credentials win, then stored OAuth tokens.

Your OAuth app stays in "Testing" mode until Google verifies it. Expect these two screens:

What you see

What it means

Fix

"Access blocked … Error 403: access_denied"

The Google account you're logging in with is not a test user of your own app

Cloud Console → APIs & Services → OAuth consent screen → Audience / Test users → Add users → add that account. Takes effect immediately.

"Google hasn't verified this app" warning

Normal for your own unverified app

Advanced → Go to <app name> (unsafe) → Allow

If you'd rather not touch the consent screen at all, use a service account.


MCP configuration

OpenCode

// opencode.json
{
  "mcp": {
    "sheets": {
      "type": "local",
      "command": ["npx", "-y", "sheetcraft-mcp@latest"],
      "environment": {
        "SHEETS_TOOLSETS": "core,drive"
      },
      "enabled": true
    }
  }
}

Gate destructive tools in agent config so the agent asks before acting:

{ "tools": { "sheets_delete_sheet": "ask", "sheets_batch_update": "ask", "sheets_trash_spreadsheet": "ask" } }

Claude Desktop / any standard MCP client

{
  "mcpServers": {
    "sheets": {
      "command": "npx",
      "args": ["-y", "sheetcraft-mcp@latest"],
      "env": { "SHEETS_TOOLSETS": "core,drive" }
    }
  }
}

Notes for all clients:

  • OAuth login done via the CLI is picked up automatically (same token store) — configure the server first, log in after, no restart dance needed.

  • The tool prefix comes from your config key: "sheets"sheets_get_values, sheets_update_values, …

  • Credentials are never put in this config. The server reads them from ~/.config/sheetcraft-mcp/ (OAuth) or env vars (service account).


Toolsets

34 tools ship in 6 opt-in groups. Select with the SHEETS_TOOLSETS environment variable — default is core,drive.

Toolset

Tools

Register when the agent needs to…

core (default)

15

Read/write values, manage sheets/tabs, find & replace

drive (default)

7

Create/copy/search/share/trash/export spreadsheets

formatting

5

Style cells, merge, freeze, conditional formatting

charts

3

Create/edit/delete embedded charts

pivot

2

Build pivot tables (see limitations)

power

2

Raw batchUpdate escape hatch + range sorting

all

34

Everything

SHEETS_TOOLSETS=core                     # 15 tools  (~4K tokens of schema)
SHEETS_TOOLSETS=core,drive               # 22 tools  (default)
SHEETS_TOOLSETS=core,drive,formatting,charts
SHEETS_TOOLSETS=all                      # 34 tools  (~10K tokens of schema)

Unknown names hard-fail at startup. Keep the list small — every tool's schema costs standing tokens in every conversation.


Tool catalog

Every data operation takes a spreadsheetId (bare ID, or paste a full URL — it's parsed), and sheet parameters accept a quoted name ('My Sheet') or gid:N. Every write echoes updatedRange/updatedCells. Every read is capped (default 5,000 cells) with an explicit truncation notice.

core — values and sheets (15)

Tool

What it does

Key parameters / defaults

get_values

Read a range. Returns CSV by default (most token-efficient)

format: csv · tsv · grid (2D JSON array) · records (header-joined objects)

batch_get_values

Read multiple ranges in one call

ranges — each result labeled with its A1

update_values

Write a 2D array to a range

input: USER_ENTERED (default — strings starting with = become formulas, dates parse) or RAW

batch_update_values

Write multiple ranges in one API call (one quota unit)

prefer over several update_values calls

append_rows

Append rows below the existing table (auto-detected)

default INSERT_ROWSnever overwrites rows below the table

clear_values

Clear values, keep formatting

destructive

get_spreadsheet_info

List tabs with titles, gids, dimensions, frozen state

call this first when all you have is a URL

add_sheet / delete_sheet / duplicate_sheet / rename_sheet

Tab management

delete is destructive; add_sheet accepts freezeRows/freezeCols

move_rows_columns

Move rows/columns to a new position in place — data, formatting, formulas move intact

the right way to reorder columns; never delete-and-recreate

insert_delete_dimensions

Insert/delete rows or columns

indices are 0-based (0 = first row/column)

find_replace

Find & replace across a sheet, range, or whole spreadsheet

replacement is required (omitting it would erase matches)

set_data_validation

Dropdowns (ONE_OF_LIST/ONE_OF_RANGE), checkboxes, number/text constraints; clearValidation=true removes rules

dropdown options via literal list or a range on an existing sheet

drive — file lifecycle (7)

Tool

What it does

Notes

create_spreadsheet

New empty spreadsheet

owned by whoever is logged in; in SA mode pass shareWith or it's invisible to humans

copy_spreadsheet

Copy data, formulas, formatting (not sharing)

find_spreadsheets

Search by name → candidate IDs, never auto-selected

sees files the authenticated identity can access

share_spreadsheet

Grant an account access

in SA mode, required after create_spreadsheet

trash_spreadsheet

Move to Drive trash (restorable)

permanent=true bypasses trash — cannot be undone

export_spreadsheet

Download whole file as xlsx / pdf / ods

per-sheet CSV: use get_values instead

resolve_target

Parse a URL → spreadsheetId + gid

also accepts bare IDs

formatting (5)

Tool

What it does

Notes

format_cells

Bold/italic/strikethrough, font size/color, background, number format, alignment, wrapping

only provided properties change; colors are #RRGGBB

merge_cells

Merge a range (ALL / COLUMNS / ROWS)

unmerge=true to undo

freeze_rows_columns

Sticky headers

pass 0 to unfreeze

conditional_format

Add/delete highlight rules

use get_formatting to find rule indices

get_formatting

Read formatting as run-length-encoded ranges + merges + rules

far cheaper than reading the full grid

charts (3)

Tool

What it does

Notes

create_chart

Embedded chart: COLUMN, BAR, LINE, AREA, SCATTER, COMBO, STEPPED_AREA

from a domain range + series ranges; returns chartId

update_chart

Change type, ranges, title, legend, stacking

patch semantics — fetch, merge, send

delete_chart

Delete by id

pivot (2) ⚠️

Tool

What it does

Notes

create_pivot

Grouped summaries (SUM/COUNT/AVERAGE/…) by row/column fields

Google's API silently drops pivot writes (verified; see limitations). The tool verifies persistence and warns honestly when the write didn't take

delete_pivot

Clear the cell holding the definition

power (2)

Tool

What it does

Notes

batch_update

Raw spreadsheets.batchUpdate — pass the API's requests array verbatim

covers banding, named ranges, protection, data validation, tables, slicers, and more; atomic (one bad request aborts the batch)

sort_range

Sort rows by one or more columns

the entire range sorts in place — exclude headers from the range


The CLI

The CLI runs the same 34 operations as subcommands — for scripting, piping, and bulk work. Same auth, same errors; any failure prints the same teaching message the MCP tools return and exits 1.

# discovery
npx sheetcraft-mcp@latest list                  # all 33 ops by toolset
npx sheetcraft-mcp@latest help get_values       # one op's full JSON schema

# operations — args as key=value pairs
npx sheetcraft-mcp@latest resolve_target url="https://docs.google.com/spreadsheets/d/…/edit"
npx sheetcraft-mcp@latest get_values spreadsheetId=<id> range="'My Sheet'!A1:D10"
npx sheetcraft-mcp@latest get_values spreadsheetId=<id> range="'My Sheet'!A1:D10" format=records

# structured output and stdin JSON (for 2D arrays with quotes/formulas)
npx sheetcraft-mcp@latest get_values spreadsheetId=<id> range=A:D --json | jq .
npx sheetcraft-mcp@latest append_rows spreadsheetId=<id> sheet=Data --stdin-json < rows.json

Flag

Purpose

--json

Force JSON output (reads print compact text by default)

--stdin-json

Read the whole args object as JSON from stdin — the safe way to pass rows containing quotes, apostrophes, newlines, or formulas

Auth: sheets auth login [--client <path>], sheets auth status, sheets auth logout. Every op is also available as sheets <op> … when installed globally.

Reads compose with standard tooling; writes are better done through MCP tools (the agent UI handles quoting and permission gating for you).

Agent skill

The npm package bundles a skill that teaches agents the CLI conventions (quoting, stdin JSON, exit codes, pitfalls) without trial and error:

# Claude Code:
ln -s "$(npm root -g)/sheetcraft-mcp/skills/managing-google-sheets" \
      ~/.claude/skills/managing-google-sheets

# OpenCode (`skill`, singular):
cp -r "$(npm root -g)/sheetcraft-mcp/skills/managing-google-sheets" \
      ~/.config/opencode/skill/managing-google-sheets

Environment variables

Variable

Purpose

Default

SHEETS_TOOLSETS

Which toolsets register: core, drive, formatting, charts, pivot, power, all, or a comma list

core,drive

GOOGLE_SERVICE_ACCOUNT_CREDENTIALS

Service-account key JSON (raw)

GOOGLE_SERVICE_ACCOUNT_FILE

Service-account key JSON (path)

SHEETS_AUTH_MODE

Force oauth or service-account

auto-resolved

GOOGLE_OAUTH_CLIENT_ID / GOOGLE_OAUTH_CLIENT_SECRET

OAuth client values (alternative to the client JSON file)

SHEETS_OAUTH_CLIENT_FILE

Custom path to the OAuth client JSON

~/.config/sheetcraft-mcp/oauth-client.json

GOOGLE_OAUTH_TOKEN_FILE

Custom token-store path

~/.config/sheetcraft-mcp/oauth-tokens.json

SHEETS_MAX_CELLS

Read cap per call

5000

SHEETS_RETRY_ATTEMPTS / SHEETS_RETRY_BASE_MS / SHEETS_RETRY_MAX_MS

Retry tuning for 429/5xx/network errors (exponential backoff + jitter)

3 / 300 / 8000

Troubleshooting

Symptom

Cause / fix

Tool call returns "No credentials configured"

Nothing is set up yet. Run npx sheetcraft-mcp@latest auth login, or set service-account env vars. The message lists both options verbatim

auth login → browser → "Access blocked / 403 access_denied"

Your account isn't a test user of your own OAuth app → add it under OAuth consent screen → Test users (see consent-screen gotchas)

"Already logged in as …" when switching accounts

Run auth logout first, or pass --force

Sheet "Data 2" not found. Sheets: "Sheet1"(gid:0), …

Teaching error — quote names with spaces: 'My Sheet'!A1:B2

Write landed in the wrong place

append_rows inserts below the table (never overwrites); update_values writes exactly the range you name — check updatedRange in the echo

find_replace erased text

replacement was empty/omitted. It's required for this reason

Sorting scrambled headers

sort_range sorts the whole range — exclude the header row from the range

Agent says a parameter "doesn't exist" or recalls a tool failing

Its tool list/schema may be stale (server updated mid-session). Re-check with help <op> / a fresh tools list — and never work around tools by reading the token store; that's out of bounds

Known limitations

  • Pivot tables via the API are unreliable — Google's API accepts the write but silently drops the definition (verified 2026-08-28, re-verified 2026-08-29 against Google's own documented request shape). create_pivot verifies persistence and warns when the write didn't take. For summaries, prefer get_values + update_values.

  • Cells in Google Tables (typed columns) reject data validation — if a tab is a Google Table (column chips with types), set_data_validation on its columns fails with "This operation is not allowed on cells in typed columns" (Google blocks it in the UI too). Use the table's column-chip menu in the UI instead, or convert the table to a normal range first.

  • Service accounts cannot create files — Google policy (0-byte storage quota). Use OAuth for create_spreadsheet / copy_spreadsheet.

  • Drive CSV export covers only the first sheet — use get_values for per-sheet CSV.

  • update_values writes in ROWS orientation — arrays are row-major.

Design notes for agent reliability

  • ID-first — every op takes spreadsheetId (full URLs parsed); sheet params accept 'Name' or gid:N.

  • Errors teach — bad ranges quote an example and list available sheets; rate-limit errors say that retries already happened.

  • Reads are cappedSHEETS_MAX_CELLS with an explicit notice telling the model how to get the rest.

  • Batching is encouragedbatch_update_values / batch_update = one API call per quota unit.

  • Cell contents are data, not instructions — sheet content is never echoed into error messages or prompts.

  • Retry + backoff built in — 429/5xx/network errors retry with exponential backoff + jitter before surfacing.

License

MIT — see LICENSE.

Maintenance

ActivityMaintained
ResponsivenessSyncing

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Provides a secure bridge for AI assistants to interact with the Google Sheets API via 31 tools for spreadsheet management, data manipulation, and table-level operations. It supports both Service Account and OAuth 2.0 authentication for tasks including batch updates, CSV imports, and conditional formatting.
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to create, read, update, and manage Google Sheets data and structure using tools like create, listSheets, sheetData, updateCells, and shareSpreadsheet, supporting OAuth2 and service-account authentication.
    5,268
    18
    MIT

Latest Blog Posts

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/P4rthPat3l/sheetcraft-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server