-
Notifications
You must be signed in to change notification settings - Fork 157
feat: add format_cells tool for cell formatting #45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -84,7 +84,8 @@ You're ready! Start issuing commands via your MCP client. | |
| ## ✨ Key Features | ||
|
|
||
| * **Seamless Integration:** Connects directly to Google Drive & Google Sheets APIs. | ||
| * **Comprehensive Tools:** Offers a wide range of operations (CRUD, listing, batching, sharing, formatting, etc.). | ||
| * **Comprehensive Tools:** Offers a wide range of operations (CRUD, listing, batching, sharing, cell formatting, etc.). | ||
| * **Cell Formatting:** Apply number formats, colors, text styles, and alignment to spreadsheet cells. | ||
| * **Flexible Authentication:** Supports **Service Accounts (recommended)**, OAuth 2.0, and direct credential injection via environment variables. | ||
| * **Easy Deployment:** Run instantly with `uvx` (zero-install feel) or clone for development using `uv`. | ||
| * **AI-Ready:** Designed for use with MCP-compatible clients, enabling natural language spreadsheet interaction. | ||
|
|
@@ -148,6 +149,15 @@ This server exposes the following tools for interacting with Google Sheets: | |
| * `recipients` (array of objects): `[{email_address: '[email protected]', role: 'writer'}, ...]`. Roles: `reader`, `commenter`, `writer`. | ||
| * `send_notification` (optional boolean, default True): Send email notifications. | ||
| * _Returns:_ Dictionary with `successes` and `failures` lists. | ||
| * **`format_cells`**: Apply formatting to cells in a Google Spreadsheet. | ||
| * `spreadsheet_id` (string) | ||
| * `sheet` (string): Name of the sheet. | ||
| * `range` (string): Cell range in A1 notation (e.g., `'A1:C10'` or `'E17'`). | ||
| * `number_format` (optional object): Number format with `type` and `pattern` keys. Example: `{'type': 'CURRENCY', 'pattern': '$#,##0.00'}`. Common types: `NUMBER`, `CURRENCY`, `PERCENT`, `DATE`, `TIME`, `TEXT`. | ||
| * `background_color` (optional object): Background color with `red`, `green`, `blue` keys (0-1 range). Example: `{'red': 1, 'green': 0.647, 'blue': 0}` for orange. | ||
| * `text_format` (optional object): Text format with keys like `bold`, `italic`, `fontSize`, `foregroundColor`, etc. Example: `{'bold': True, 'fontSize': 11}`. | ||
| * `horizontal_alignment` (optional string): One of: `LEFT`, `CENTER`, `RIGHT`. | ||
| * _Returns:_ Format operation result object. | ||
| * **`add_columns`**: Adds columns to a sheet. *(Verify parameters if implemented)* | ||
| * **`copy_sheet`**: Duplicates a sheet within a spreadsheet. *(Verify parameters if implemented)* | ||
| * **`rename_sheet`**: Renames an existing sheet. *(Verify parameters if implemented)* | ||
|
|
@@ -458,6 +468,9 @@ Once connected, try prompts like: | |
| * "Append these rows to the 'Log' sheet in spreadsheet `XYZ`: `[['2024-07-31', 'Task A Completed'], ['2024-08-01', 'Task B Started']]`" | ||
| * "Get a summary of the spreadsheets 'Sales Data' and 'Inventory Count'." | ||
| * "Share the 'Team Vacation Schedule' spreadsheet with `[email protected]` as a reader and `[email protected]` as a writer. Don't send notifications." | ||
| * "Format cells A1:E1 in Sheet1 with orange background, bold black text." | ||
| * "Apply currency formatting to cells E2:E10 in the 'Sales' sheet." | ||
| * "Center align the text in cells B1:D1 and make them bold." | ||
|
|
||
| --- | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -928,6 +928,128 @@ def share_spreadsheet(spreadsheet_id: str, | |||||||
|
|
||||||||
| return {"successes": successes, "failures": failures} | ||||||||
|
|
||||||||
|
|
||||||||
| @mcp.tool() | ||||||||
| def format_cells(spreadsheet_id: str, | ||||||||
| sheet: str, | ||||||||
| range: str, | ||||||||
| number_format: Optional[Dict[str, str]] = None, | ||||||||
| background_color: Optional[Dict[str, float]] = None, | ||||||||
| text_format: Optional[Dict[str, Any]] = None, | ||||||||
| horizontal_alignment: Optional[str] = None, | ||||||||
| ctx: Context = None) -> Dict[str, Any]: | ||||||||
| """ | ||||||||
| Apply formatting to cells in a Google Spreadsheet. | ||||||||
|
|
||||||||
| Args: | ||||||||
| spreadsheet_id: The ID of the spreadsheet (found in the URL) | ||||||||
| sheet: The name of the sheet | ||||||||
| range: Cell range in A1 notation (e.g., 'A1:C10' or 'E17') | ||||||||
| number_format: Optional number format with 'type' and 'pattern' keys. | ||||||||
| Example: {'type': 'NUMBER', 'pattern': '$#,##0.00'} for currency | ||||||||
| Common types: 'NUMBER', 'CURRENCY', 'PERCENT', 'DATE', 'TIME', 'TEXT' | ||||||||
| background_color: Optional background color with 'red', 'green', 'blue' keys (0-1 range). | ||||||||
| Example: {'red': 1, 'green': 1, 'blue': 1} for white | ||||||||
| text_format: Optional text format with keys like 'bold', 'italic', 'fontSize', etc. | ||||||||
| Example: {'bold': True, 'fontSize': 11} | ||||||||
|
||||||||
| Example: {'bold': True, 'fontSize': 11} | |
| You can specify text color using the 'foregroundColor' key, which should be an object with 'red', 'green', 'blue' keys (0-1 range), similar to background_color. | |
| Example: {'bold': True, 'fontSize': 11, 'foregroundColor': {'red': 0, 'green': 0, 'blue': 0}} for black text. |
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import re statement should be moved to the top of the file with other imports (around line 1-25). Local imports within functions are generally discouraged unless there's a specific reason (e.g., optional dependencies, circular imports).
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The regex pattern doesn't account for lowercase column letters. Google Sheets A1 notation can be case-insensitive in practice. Consider using r'([A-Za-z]+)(\d+)(?::([A-Za-z]+)(\d+))?' and converting to uppercase, or add the re.IGNORECASE flag.
Copilot
AI
Dec 6, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Consider extracting the A1 notation parsing logic (lines 974-996) into a separate module-level helper function. This would make it reusable for other tools that might need to parse A1 ranges in the future and easier to test independently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change from
strict = truetostrict = falseappears unrelated to the cell formatting feature. Consider removing this change or documenting the reason for it in the PR description. Disabling strict mode for dynamic versioning can allow version tag mismatches to pass silently.