Skip to main content
Glama
README.md
# Sheets MCP

**Give Claude Desktop the ability to read, write, and manage Google Sheets — directly in conversation.**

[![Node](https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js&logoColor=white)](https://nodejs.org)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![MCP](https://img.shields.io/badge/protocol-MCP-6b4fbb)](https://modelcontextprotocol.io)

---

## Overview

Claude has no built-in way to talk to Google Sheets. **Sheets MCP** is a small local server that sits between Claude Desktop and the Google Sheets/Drive APIs, speaking the [Model Context Protocol](https://modelcontextprotocol.io) so Claude can call it like any other tool.

Ask Claude things like:

> "List my Google Sheets"
> "Read A1:D10 from my Budget spreadsheet"
> "Add a row to my Tasks sheet with today's date and 'Follow up with client'"

...and it actually happens, live, in your real spreadsheet.

## How it works

```
 You  <──chat──>  Claude Desktop  <──MCP (stdio)──>  Sheets MCP server  <──REST──>  Google Sheets / Drive API
```

Claude Desktop starts the server locally, sends it tool calls over stdio, and the server translates those into real Google API requests using a saved OAuth login.

## Tools

| Tool | Description | Required arguments |
|---|---|---|
| `list_sheets` | Find spreadsheets by name | `query` *(optional)* |
| `read_range` | Read cell values from a range | `spreadsheetId`, `range` |
| `write_range` | Overwrite cell values in a range | `spreadsheetId`, `range`, `values` |
| `append_row` | Add row(s) to the end of a sheet | `spreadsheetId`, `sheetName`, `values` |

The `spreadsheetId` is the long string in a sheet's URL, between `/d/` and `/edit`:
```
https://docs.google.com/spreadsheets/d/1XUqH2AumsmusdvsavsdvadsvewrvVAFAvEMcWzUmrlg/edit
                                       └──────────── spreadsheetId ─────────────┘
```
In practice you can just ask Claude in plain English (e.g. "read my Budget sheet") and it'll use `list_sheets` to find the ID for you — you don't have to paste it yourself.

## Prerequisites

- [Node.js](https://nodejs.org) 18 or newer
- [Claude Desktop](https://claude.ai/download) already installed
- A Google account with access to the Sheets you want Claude to use

## Setup

### 0. Clone this repo

```bash
git clone https://github.com/Luchitha7/sheets-mcp.git
cd sheets-mcp
```

### 1. Create Google OAuth credentials

All of this happens in [Google Cloud Console](https://console.cloud.google.com), logged into the Google account you want Claude to access sheets as.

1. **Create a project** — top-left project dropdown → New Project → name it (e.g. `sheets-mcp`) → Create, then make sure it's selected as the active project.
2. **Enable two APIs** — use the top search bar to find and enable, one at a time:
   - `Google Sheets API`
   - `Google Drive API` (needed so the server can look up a spreadsheet by name, not just by ID)
3. **Set up the consent screen** — left sidebar → *Google Auth Platform* → *Branding* (older docs may call this "OAuth consent screen," it's the same thing).
   - User type: **External** (unless you're on a Google Workspace org)
   - Fill in app name + your email, click through the wizard (Audience, Contact Information, Finish)
   - On the **Audience** page, scroll to **Test users** → **Add users** → add your own Google account email. Skip this and Google will block your login later with an `access_denied` error, since unpublished apps only allow pre-approved accounts to sign in.
4. **Create the OAuth Client ID** — left sidebar → *Clients* → **Create OAuth client**
   - Application type: **Desktop app** (not "Web application" — a desktop app client is built for a local script doing its own login, not a website with a public redirect URL)
   - Name it anything, e.g. `Sheets MCP Desktop`, click Create
5. **Download the credentials** — a popup shows a Client ID and Client Secret. If clicking "Download JSON" there doesn't produce a file (a known quirk), instead go to *Clients* → click your new client → use the download icon next to **Client secret** on its detail page.
6. Save the downloaded file as `credentials/gcp-oauth-client.json` in this project.

### 2. Install dependencies

```bash
npm install
```

### 3. Log in to Google (one-time)

```bash
npm run auth
```

This opens your browser to log in and grant access, then saves a token to `credentials/token.json`. You won't need to log in again unless access is revoked.

### 4. Connect it to Claude Desktop

Open **Claude Desktop → Settings → Developer → Edit Config**, and add this server under `mcpServers` (keep any existing entries in the file):

```json
{
  "mcpServers": {
    "sheets-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/sheets-mcp/server.js"]
    }
  }
}
```

Fully quit and reopen Claude Desktop. `sheets-mcp` should now appear under **Settings → Developer → Local MCP servers**.

## Project structure

```
sheets-mcp/
├── server.js         # The MCP server — exposes the 4 tools to Claude
├── auth.js           # Shared OAuth login + token refresh logic
├── auth-setup.js      # One-time login script (npm run auth)
├── credentials/       # gcp-oauth-client.json + token.json (gitignored)
└── package.json
```

## Troubleshooting

| Symptom | Cause | Fix |
|---|---|---|
| `access_denied` during login | App is in "Testing" mode | Add your Google account under Audience → Test users |
| `Drive API has not been used...` | Drive API not enabled on the project | Enable it in Google Cloud Console, wait a minute, retry |
| Server missing from Claude Desktop | Config not picked up | Fully quit and reopen Claude Desktop (not just close the window) |
| Login expired / revoked | Token no longer valid | Rerun `npm run auth` |

## Security notes

- `credentials/gcp-oauth-client.json` and `credentials/token.json` contain secrets and are gitignored — never commit or share them.
- The server only requests the minimum scopes needed: read/write Sheets, and read-only Drive metadata (to list files).

## License

[MIT](LICENSE)