sql_query
Execute SQL SELECT queries on spreadsheet data to analyze, filter, and join information across sheets using a database-like interface.
Instructions
Execute a read-only SQL SELECT query against the spreadsheet data.
Every sheet in the workbook is loaded as a database table, with the header row defining column names and data rows below it. Returns results as a list of {column: value} objects.
Only SELECT (and WITH ... SELECT) statements are accepted. Use sql_execute for INSERT, UPDATE, or DELETE.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes | Path to the spreadsheet file | |
| sql | Yes | SQL SELECT statement to execute. Each sheet is a table (quote names with double quotes if they contain spaces). Supports WHERE, ORDER BY, LIMIT, GROUP BY, HAVING, JOINs across sheets, DISTINCT, UNION, subqueries, and aggregates (COUNT, SUM, AVG, MIN, MAX). Example: SELECT name, revenue FROM Sales WHERE status = 'Active' ORDER BY revenue DESC LIMIT 20 | |
| header_row | No | 1-based row number containing column headers. Defaults to 1. |
Implementation Reference
- The `sql_query` tool is implemented here. It takes a spreadsheet file path and a SQL SELECT statement, loads the sheets into DuckDB, executes the query, and returns the results.
def sql_query( file: Annotated[str, Field(description="Path to the spreadsheet file")], sql: Annotated[str, Field(description=( "SQL SELECT statement to execute. Each sheet is a table (quote names " "with double quotes if they contain spaces). " "Supports WHERE, ORDER BY, LIMIT, GROUP BY, HAVING, JOINs across " "sheets, DISTINCT, UNION, subqueries, and aggregates (COUNT, SUM, " "AVG, MIN, MAX). " "Example: SELECT name, revenue FROM Sales WHERE status = 'Active' " "ORDER BY revenue DESC LIMIT 20" ))], header_row: Annotated[int, Field(description="1-based row number containing column headers. Defaults to 1.")] = 1, ) -> list[dict]: """Execute a read-only SQL SELECT query against the spreadsheet data. Every sheet in the workbook is loaded as a database table, with the header row defining column names and data rows below it. Returns results as a list of {column: value} objects. Only SELECT (and WITH ... SELECT) statements are accepted. Use sql_execute for INSERT, UPDATE, or DELETE. """ sql_stripped = sql.strip().rstrip(";") first_keyword = sql_stripped.split()[0].upper() if sql_stripped else "" if first_keyword not in ("SELECT", "WITH"): raise ValueError( "sql_query only accepts SELECT statements (or WITH ... SELECT). " "Use sql_execute for INSERT/UPDATE/DELETE." ) wb = load_workbook(file) conn = _load_sheets_to_duckdb(wb, header_row) result = conn.execute(sql_stripped) columns = [desc[0] for desc in result.description] return [dict(zip(columns, row)) for row in result.fetchall()] - src/mcp_server_spreadsheet/server.py:696-696 (registration)The `sql_query` function is registered as an MCP tool using the `@mcp.tool()` decorator.
@mcp.tool()