Connect Google Sheets to Claude (private sheets, exact totals)
Claude can read a spreadsheet you paste or attach, but it reads it as text. With a few thousand rows that means long context, slow answers and totals that are estimated rather than computed. This guide connects a Google Sheet to Claude as a custom connector, so Claude sends a query and gets back an exact result.
It works in Claude.ai, Claude Desktop and Claude Code, with private sheets as well as public ones.
What you need
- A Google Sheet (any size up to 100,000 rows per tab on the free plan).
- A datatomcp account. Signing in with Google is simplest, because the same account later picks the sheet.
- A Claude plan that allows custom connectors.
1. Import the sheet
- Sign in at app.datatomcp.com and open Add data → Google Sheet.
- Click Choose a Google Sheet. Google’s own file picker opens. Choose the spreadsheet; datatomcp gets access to that file only, not the rest of your Drive (Google’s
drive.filepermission). - datatomcp reads the first tab with unformatted values, so
€1,200.50arrives as the number1200.5, and builds the dataset.
You land on the import report: every column with its detected type, example values and warnings such as “number stored as text” or “mixed date formats”. Nothing is converted silently; fixes are one click and create a new version.
A public sheet works too: paste its share link under Paste a link instead.
2. Add the connector to Claude
- In Claude, open Settings → Connectors → Add custom connector.
- Name it
datatomcpand paste the URLhttps://app.datatomcp.com/mcp. - Click Connect. A datatomcp sign-in opens, then a consent screen listing what Claude may do (read and query your datasets). Allow it.
There is no API key to copy. Claude holds a token that you can revoke from datatomcp at any time.
Claude Code takes one command:
claude mcp add --transport http datatomcp https://app.datatomcp.com/mcp
Then run /mcp inside Claude Code, pick datatomcp and authenticate.
3. Ask a question
Start a chat and ask something your sheet can answer. With our 50,000-row test orders sheet:
How many orders came from France in September 2026, and what was the revenue?
Claude calls describe_dataset to learn the columns, then one aggregate call:
{
"where": [
{ "column": "country", "op": "eq", "value": "France" },
{ "column": "order_date", "op": "between", "value": ["2026-09-01", "2026-09-30"] }
],
"metrics": [
{ "fn": "count", "as": "orders" },
{ "fn": "sum", "column": "total", "as": "revenue" }
]
}
and answers 277 orders, €50,279.50. The tool result is 32 bytes. Pasting the same sheet would have sent about 4 MB of text.
Why this beats pasting the sheet
- Exact numbers. Counts and sums are computed by a database (DuckDB), not estimated by the model.
- Big tabs work. Claude only receives the rows or totals it asks for, so 100,000 rows cost the same as 100.
- Real filter values. Claude can call
distinct_valuesfirst, so it filters on"United States"rather than guessing"USA". - Every answer is traceable. Each result says which version of the dataset it came from and when it was refreshed.
Keeping it in sync
When the sheet changes, click Refresh now on the dataset page. On Pro, datatomcp re-reads the sheet every hour and only publishes a new version when something changed. If a refresh fails (the sheet was deleted, access was removed), agents keep getting the last good version and you get one email.
Troubleshooting
- “datatomcp can’t open this sheet” right after picking it: Google can take a few seconds to grant access. Try once more.
- Claude doesn’t use the tools: mention the data explicitly (“use datatomcp to…”) the first time, or check the connector is enabled for the chat.
- Wrong column type (a code like
00123read as a number): change the type on the dataset page; the dataset is rebuilt as a new version.