Google Sheets Write MCP Server
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| SHEETS_WRITE_MCP_TOKEN | No | Path to OAuth token JSON file | ~/.config/sheets-write-mcp/token.json |
| SHEETS_WRITE_MCP_DATA_DIR | No | Directory for data (audit logs, snapshots) | ~/.local/share/sheets-write-mcp/ |
| SHEETS_WRITE_MCP_WHITELIST | No | Path to whitelist YAML file | ~/.config/sheets-write-mcp/allowed_spreadsheets.yaml |
| SHEETS_WRITE_MCP_CREDENTIALS | No | Path to OAuth credentials JSON file | ~/.config/sheets-write-mcp/credentials.json |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| update_rangeA | Write values (or formulas) to an existing range. Overwrites current content. Formulas like '=SUM(A:A)' are interpreted as formulas by default (USER_ENTERED). The previous values of the target range are snapshotted for rollback before writing. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. range: Bare A1 range without sheet prefix, e.g. 'B2:D10'. values: 2D list of cell values, rows x columns. raw: If true, store inputs literally (formulas become plain text). dry_run: If true, return the execution plan without writing. force: Allow writes touching more than the cell limit. |
| batch_update_valuesA | Write multiple ranges in one call (one API request, atomic-ish). Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. updates: List of {"sheet": str, "range": str, "values": list[list]}. 'sheet' is a name or gid; 'range' is bare A1 without prefix. raw: If true, store inputs literally (formulas become plain text). dry_run: If true, return the execution plan without writing. force: Allow writes touching more than the cell limit. |
| append_rowsA | Append rows after the last data row of a sheet. Never overwrites. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. rows: 2D list of row values to append. raw: If true, store inputs literally (formulas become plain text). dry_run: If true, return the execution plan without writing. force: Allow writes touching more than the cell limit. |
| clear_rangeA | Clear all values in a range (destructive — dry_run defaults to TRUE). Values are snapshotted before clearing so they can be restored. Formatting is not affected by this operation. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. range: Bare A1 range without sheet prefix, e.g. 'B2:D10'. dry_run: Defaults to TRUE. Pass false to actually clear. force: Allow clears touching more than the cell limit. |
| insert_rowsA | Insert blank rows before the given row number. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. start_row: 1-indexed row number the new rows are inserted BEFORE (start_row=3 inserts new rows as row 3..). count: Number of rows to insert. inherit_before: Inherit formatting from the row above. dry_run: If true, return the execution plan without changing anything. |
| insert_columnsA | Insert blank columns before the given column. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. start_column: Column letter ('B') or 1-indexed number the new columns are inserted BEFORE. count: Number of columns to insert. inherit_before: Inherit formatting from the column to the left. dry_run: If true, return the execution plan without changing anything. |
| delete_rowsA | Delete rows (destructive — dry_run defaults to TRUE). The full contents of the rows are snapshotted (formulas preserved) before deletion. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. start_row: 1-indexed first row to delete. count: Number of rows to delete. dry_run: Defaults to TRUE. Pass false to actually delete. force: Allow deletions touching more than the cell limit. |
| delete_columnsA | Delete columns (destructive — dry_run defaults to TRUE). The full contents of the columns are snapshotted before deletion. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. start_column: Column letter ('B') or 1-indexed number of the first column to delete. count: Number of columns to delete. dry_run: Defaults to TRUE. Pass false to actually delete. force: Allow deletions touching more than the cell limit. |
| add_sheetA | Add a new empty sheet (tab). Whitelist note: allowed only when writable_sheets is "*" or the new title is explicitly listed. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. title: Name of the new sheet. rows: Grid row count. columns: Grid column count. index: Optional 0-based tab position. dry_run: If true, return the execution plan without changing anything. |
| delete_sheetA | Delete an entire sheet (destructive — dry_run defaults to TRUE). The whole sheet's values (formulas preserved) and its properties are snapshotted so the sheet can be recreated. Formatting is not restored. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. dry_run: Defaults to TRUE. Pass false to actually delete. force: Allow deletion of sheets larger than the cell limit. |
| duplicate_sheetA | Duplicate a sheet within the same spreadsheet. Whitelist note: allowed only when writable_sheets is "*" or the new title is explicitly listed. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Source sheet name OR gid string. new_title: Name for the copy. insert_index: Optional 0-based tab position for the copy. dry_run: If true, return the execution plan without changing anything. |
| rename_sheetA | Rename a sheet (tab). Note: if the whitelist lists sheets by name, update the whitelist entry after renaming — the old name will no longer match. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. new_title: New sheet name. dry_run: If true, return the execution plan without changing anything. |
| set_number_formatA | Set the number format of a range (e.g. '#,##0', '0.0%', 'yyyy-mm-dd'). Only numberFormat is touched — other formatting is preserved. Formatting changes are NOT rollback-capable (use Sheets version history). Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. range: Bare A1 range without sheet prefix. pattern: Number format pattern string. type: One of TEXT/NUMBER/PERCENT/CURRENCY/DATE/TIME/DATE_TIME/SCIENTIFIC. dry_run: If true, return the execution plan without changing anything. |
| set_cell_styleA | Style cells. Only the parameters you pass are changed; the rest is preserved. Formatting changes are NOT rollback-capable (use Sheets version history). Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. range: Bare A1 range without sheet prefix. bold: Bold on/off. italic: Italic on/off. font_size: Font size in points. fg_color: Text color '#RRGGBB'. bg_color: Background color '#RRGGBB'. h_align: 'left' | 'center' | 'right'. borders: Optional {"sides": ["top","bottom","left","right","innerHorizontal","innerVertical"], "style": "SOLID|SOLID_MEDIUM|SOLID_THICK|DOTTED|DASHED|DOUBLE|NONE", "color": "#RRGGBB"}. dry_run: If true, return the execution plan without changing anything. |
| set_conditional_formatA | Add a conditional-format rule to a range. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. range: Bare A1 range without sheet prefix. condition_type: e.g. NUMBER_GREATER, TEXT_CONTAINS, CUSTOM_FORMULA, BLANK. condition_values: Values/formula for the condition (e.g. ['100'] or ['=B2>C2']). bg_color: Highlight background '#RRGGBB'. fg_color: Highlight text color '#RRGGBB'. bold: Bold the matching cells. index: Rule priority position (0 = highest). dry_run: If true, return the execution plan without changing anything. |
| set_data_validationA | Set (or clear) data validation on a range. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. range: Bare A1 range without sheet prefix. rule_type: e.g. ONE_OF_LIST, NUMBER_BETWEEN, CHECKBOX, CUSTOM_FORMULA. Pass null/None to CLEAR validation from the range. values: Rule values (e.g. ['A','B','C'] for ONE_OF_LIST). strict: Reject invalid input (false = warning only). show_dropdown: Show dropdown for list rules. dry_run: If true, return the execution plan without changing anything. |
| set_basic_filterA | Set (or clear) the basic filter of a sheet. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. range: Bare A1 range for the filter. None = whole sheet. clear: If true, remove the existing basic filter instead. dry_run: If true, return the execution plan without changing anything. |
| protect_rangeA | Protect a range (or the whole sheet) from editing. Args: spreadsheet_id_or_url: Full Sheets URL or bare spreadsheet ID. sheet: Sheet name OR gid string. range: Bare A1 range to protect. None = whole sheet. description: Label shown in the Sheets UI. warning_only: Show a warning instead of blocking edits. editors: Email addresses still allowed to edit (ignored when warning_only). dry_run: If true, return the execution plan without changing anything. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/tg-tool/google-sheets-write-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server