Read Tools
list_spreadsheets, list_sheets, inspect_spreadsheet, read_range, search_rows — inspect your Sheets without writing anything.
list_spreadsheets
Lists all Google Spreadsheets in the authenticated user's Drive.
No parameters required.
// Response — array of file objects
[
{
"id": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
"name": "Q2 2026 Revenue",
"createdTime": "2026-03-01T09:00:00.000Z",
"modifiedTime": "2026-05-12T14:23:00.000Z"
}
]Note
Uses
driveClient.files.listwithmimeType='application/vnd.google-apps.spreadsheet'andspaces: 'drive'. Returns files in default Drive sort order. Does not page — if you have hundreds of spreadsheets, usemanage_drivesearch with a name query to narrow results.
list_sheets
Lists all tabs (worksheets) inside a spreadsheet, with their numeric sheetId and tab index.
| Parameter | Type | Required | Description |
|---|---|---|---|
spreadsheetId | string | ✓ | The spreadsheet to inspect |
// Response — array of sheet tab objects
[
{ "sheetId": 0, "title": "Sheet1", "index": 0 },
{ "sheetId": 812345678, "title": "Revenue", "index": 1 },
{ "sheetId": 923456789, "title": "Archive", "index": 2 }
]Tip:
Always call
list_sheetsbefore usingformat_cells,copy_sheet,manage_sheets(rename/delete), orbatch_update_sheet— these tools require the numericsheetId, not the tab name string.
inspect_spreadsheet
Performs read-only reconnaissance on an unfamiliar spreadsheet before selecting ranges, transforming data, or making destructive edits. It returns a bounded architecture map across all tabs and samples only the top rows/columns needed for header and formula signals.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
spreadsheetId | string | ✓ | — | Target spreadsheet |
maxHeaderRows | number | ✗ | 3 | Top rows per sampled tab to inspect for header candidates; max 10 |
maxFormulaRows | number | ✗ | 25 | Top rows per sampled tab to inspect with FORMULA rendering; max 100 |
maxSampleColumns | number | ✗ | 50 | Maximum columns per sampled tab for header/formula probes; max 100 |
maxSampledSheets | number | ✗ | 25 | Maximum grid tabs to sample. Metadata is still returned for every tab; max 50 |
Response shape
{
"spreadsheetId": "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgVE2upms",
"title": "Operations Model",
"summary": {
"sheetCount": 4,
"sampledSheetCount": 4,
"namedRangeCount": 1,
"hiddenSheetCount": 1,
"protectedSheetCount": 2,
"formulaSheetCount": 2,
"warnings": []
},
"tabs": [
{
"sheetId": 0,
"title": "Orders",
"grid": { "rowCount": 52000, "columnCount": 34 },
"headers": {
"candidateRowNumber": 1,
"values": ["order_id", "created_at", "sku", "qty", "net_amount", "status"],
"blankCount": 0,
"duplicateHeaders": []
},
"formulaSummary": {
"formulaCellCount": 1,
"hasFormulas": true,
"hasArrayFormula": false,
"functions": []
},
"classification": {
"type": "transaction",
"confidence": 0.95,
"evidence": ["large row count", "6 transactional header clue(s)"]
},
"risks": ["Protected ranges present (1).", "Large grid; use analyze_range or bounded reads for data profiling."]
}
],
"recommendations": [
"Use this read-only recon before destructive deletes, transforms, or broad writes."
]
}AX: Recon first on unknown workbooks. Use inspect_spreadsheet before transform_range, delete_column, or raw batch_update_sheet when the workbook structure is not already known. Treat classification as evidence-based guidance, not guaranteed business truth.
read_range
Reads a 2D array of cell values from a range, along with the sheet's structural schema.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
spreadsheetId | string | ✓ | — | Target spreadsheet |
range | string | ✓ | — | A1 notation, e.g. Sheet1!A1:D10 |
renderOption | enum | ✗ | FORMATTED_VALUE | How values are rendered (see below) |
includeNotes | enum | ✗ | headers | If "headers", fetches cell notes from the first row and exposes them in _schema.columns; pass "none" only when you intentionally want value-only output |
renderOption values
| Value | Returns |
|---|---|
FORMATTED_VALUE | What the user sees — $1,200.00, Jan 2026, TRUE |
UNFORMATTED_VALUE | Raw underlying value — 1200, 46023 (serial date), true |
FORMULA | Cell formula strings — =SUM(A1:A5), or the value if not a formula |
Response shape
read_range always bundles the sheet schema with the values:
{
"values": [
["Name", "Revenue", "Status"],
["Acme Corp", "$12,000", "Active"],
["Globex", "$8,500", "Inactive"]
],
"_schema": {
"layout": { "frozenRows": 1, "frozenColumns": 0 },
"semantics": ["Has 3 conditional format rules"],
"protectedRanges": [],
"arrayFormulaColumns": ["C"],
"arrayFormulaAnchors": [
{
"columnIndex": 2,
"columnName": "C",
"formulaCell": {
"address": "Sheet1!C1",
"rowIndex": 0,
"columnIndex": 2,
"formula": "=ARRAYFORMULA(...)"
}
}
],
"warnings": ["⚠ Column C contains ARRAYFORMULA at Sheet1!C1 — do not write static values into C:C"],
"mergedTitleRows": [],
"constraints": [],
"columns": [
{
"columnIndex": 1,
"columnName": "B",
"header": "Revenue",
"note": "[FORMULA] Total recognized revenue for Q2",
"description": "Total recognized revenue for Q2",
"descriptionSource": "note",
"noteGuard": {
"tag": "FORMULA",
"severity": "formula",
"message": "Total recognized revenue for Q2",
"blocksWrite": true
}
}
]
}
}AX: Read _schema before writing. Header notes are included by default as column metadata. Structured note prefixes ([INFO], [WARN], [FORMULA], [LOCK]) appear as noteGuard metadata, and blocking guards are also checked automatically by write tools.
Truncation behaviour
If the response exceeds 1,000 rows or 2 MB, the result is truncated and a warning is appended:
⚠ read_range: Truncated to 1000 rows (original: 14823).
Use search_rows for exact row lookup, analyze_range with SQL for aggregates/filtering, or a narrower A1 range for bounded samples.When you see this warning, do not retry read_range on the same large range. Use search_rows for exact row lookup, analyze_range for aggregates/filtering, or a narrower A1 range for bounded samples.
Common A1 patterns
Sheet1!A1:D10 — rows 1–10, columns A–D
Sheet1!A:D — entire columns A–D (all rows)
Sheet1!1:1 — entire row 1 (header row only)
'My Sheet'!A1:Z100 — sheet name with spaces (single-quoted)Warning: Always qualify the range with the sheet name (Sheet1!A1). Without the sheet name prefix, the Sheets API defaults to the first tab, which may not be what you expect.
search_rows
Performs a fast server-side search for exact text matches within a specific column. Returns matching rows prefixed with their 1-indexed row number, along with the _schema and _meta wrappers.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
spreadsheetId | string | ✓ | — | Target spreadsheet |
range | string | ✓ | — | A1 notation, e.g. Sheet1!A:Z |
columnName | string | ✓ | — | Column header to search within |
value | string | ✓ | — | Exact text to search for |
matchMode | enum | ✗ | exact | Match mode |
matchCase | boolean | ✗ | false | Case-sensitive search |
limit | number | ✗ | 25 | Maximum number of rows to return |
Common dedup workflow
Use search_rows before appending data to prevent duplicates:
search_rows Customers!A:Z columnName=Email value=test@example.com
if values is empty, append_rowsLimitation Note
search_rowsonly supports exact-match lookup. It does not support fuzzy matching orcontainssearches. If you have dirty data, or need complex filtering, read the data usingread_rangeor run SQL queries viaanalyze_range.