AI access to Quadratic spreadsheets: open files, run Python/SQL, query connected databases.
Access Quadratic spreadsheets and run Python/SQL queries on connected databases.
Captured live from the server via tools/list.
auth
Authenticate the MCP session with Quadratic.
Actions:
• login() — Start an OAuth device authorization flow. Returns a URL the user must open in a browser to authorize. The flow is completed by confirm_login.
• confirm_login(device_code) — Complete an in-progress login by polling for user authorization. If the response indicates the user has not yet authorized, this action can be called again with the same device_code to continue polling.
• set_token(token, email?) — Set a JWT directly (used when the OAuth device flow is not available).
• logout() — Clear saved authentication for the current session.
Parameters (2)
actionstringrequired
Action to perform: login, confirm_login, set_token, or logout
paramsany
Parameters for the action (see tool description)
files_read
Read-only file metadata operations on Quadratic files the user has access to. No data is modified. Requires authentication.
Actions:
• list_files() — List all accessible files.
• get_file_info(file_id) — Get metadata for a single file.
Parameters (2)
actionstringrequired
Action to perform: list_files or get_file_info
paramsany
Parameters for the action (see tool description)
files_write
File management operations that create or modify state: create a new file, open an existing file to start an editing session, or close a session. Requires authentication.
Actions:
• open_file(file_id?, file_name?) — Open a file by UUID or name and start an editing session. Returns the file's web URL.
• create_file(file_name, team_uuid?) — Create a new blank spreadsheet. If team_uuid is omitted, the user's first team is used. Returns the new file's UUID and web URL; the file must be opened with open_file before it can be edited.
• close_file(file_id) — Close an active editing session.
Parameters (2)
actionstringrequired
Action to perform: open_file, create_file, or close_file
paramsany
Parameters for the action (see tool description)
read_data
Read-only queries on the open spreadsheet. No data is modified. Safe to auto-approve. Call as {"action": "<name>", "params": {...}} — per-action params are listed in the Action Reference below.
Special actions (not shown in the action enum):
• batch — {"action": "batch", "params": {"actions": [{"action": "<name>", "params": {...}}, ...]}}. Runs reads in parallel; individual failures are reported per-entry without short-circuiting.
• context — {"action": "context", "params": {"topic": "<name>"}} or {"action": "context", "params": {"action": "<name>"}}. Returns deeper docs for a topic or a single action's signature. Plural "topics" / "actions" arrays are also accepted and may be combined. Topics: python, javascript, formula, connection, validation, a1, quadratic.
Action Reference
• get_cell_data(selection, page?, sheet_name?) — Returns cell values for a selection in A1 notation. Supports comma-separated ranges to fetch multiple areas in ONE call, including across different sheets. Examples: "A1:B10, D1:E10", "TableName, OtherTable", "'Sheet1'!A1:B10, 'Sheet2'!C1:D10". Table names are globally unique so they work without sheet prefixes. For cell ranges on other sheets use 'SheetName'!Range. Only use when you need the full dataset (aggregations, lookups, analysis). The file summary already includes sample rows. Results may be paginated — use page (0-based) for additional pages.
• has_cell_data(selection, sheet_name?) — Check if any cells in a selection have data. Returns true if ANY cell contains data. Use before creating/moving tables or code to avoid spill errors. All ranges MUST be on the same sheet.
• get_code_cell_value(code_cell_position?, code_cell_name?, sheet_name?) — Get full code from an existing Python, JavaScript, or connection code cell. Do NOT use for formula cells — formulas are already in get_cell_data results and the file summary.
• get_text_formats(selection, page?, sheet_name?) — Get text formatting info. Use table column references for tables ("Table_Name[Column Name]"). Results may be paginated.
• get_validations(sheet_name?) — Get all validations in a sheet.
• get_conditional_formats(sheet_name) — Get all conditional formatting rules. Use to check existing rules before creating/updating/deleting.
• text_search(query, case_sensitive?, whole_cell?, search_code?, regex?, sheet_name?) — Search for text in cell outputs. Supports regex when enabled (e.g., "\d+", "^hello", "foo|bar"). Searches cell outputs only, not code. Booleans default false.
• get_sheet_info() — List all sheets and names.
• get_spreadsheet_context(sheet_name?, include_errors?) — Full context snapshot of the file.
• read_data(selection, sheet_name?, max_rows?) — Read cell data as compact CSV. Auto-tiers: returns all rows for small/medium data (<5000 rows), head+tail preview for large data. Preferred over get_cell_data for most reads.
• outline(sheet_name?) — Structural map of the file: sheets, bounds, tables, code cells, charts, connections, errors. Use to understand file layout before reading data.
• dependencies(position, sheet_name?, direction?) — Trace cell dependencies. direction: "forward" (what this cell reads), "reverse" (what depends on this cell), or "both" (default).
• list_connections(team_uuid?) — List all database connections in a team (PostgreSQL, MySQL, MS SQL, Snowflake, BigQuery, Mixpanel, Google Analytics, Plaid, etc.). Returns each connection's uuid, name, and type. team_uuid is optional — if omitted, the user's only team is used; multi-team users must pass it. Call this BEFORE get_database_schemas or set_sql_code_cell_value to discover the connection_ids and connection types you need.
• get_database_schemas(connection_ids, connection_type, team_uuid) — Get table/column schemas for database connections. Always call before writing SQL. Get connection_ids from list_connections. connection_type: POSTGRES, MYSQL, MSSQL, SNOWFLAKE, BIGQUERY, COCKROACHDB, etc.
• list_agent_connections(team_uuid?) — List the team's ready Agent Connections (third-party REST API bindings). Returns each connection's uuid, name, service, base U
Parameters for the action (see tool description). For batch: {actions: [{action, params}, ...]}
write_data
Write operations on the open spreadsheet. Call as {"action": "<name>", "params": {...}} — per-action params are listed in the Action Reference below. Numbers, booleans, and nulls in cell values are coerced to strings.
Special actions (not shown in the action enum):
• batch — {"action": "batch", "params": {"actions": [{"action": "<name>", "params": {...}}, ...]}}. Runs writes sequentially; errors short-circuit the batch.
• context — {"action": "context", "params": {"topic": "<name>"}} or {"action": "context", "params": {"action": "<name>"}}. Returns deeper docs for a topic or a single action's signature. Plural "topics" / "actions" arrays are also accepted and may be combined. Topics: python, javascript, formula, connection, validation, a1, quadratic.
Action Reference
Cell Data:
• set_cell_values(top_left_position, cell_values, sheet_name?) — Sets cell values as a 2D string array (first row = headers). top_left_position: single cell in A1 notation. Don't place over existing data unless requested. Values replace existing content; use empty string to clear. For merged cells, place at the anchor (top-left) cell. Prefer this over add_data_table unless data is clearly tabular. Don't use for formulas or code.
• delete_cells(selection, sheet_name?) — Delete cell values in a selection (A1 notation). Don't delete cells referenced by code cells unless explicitly asked. To delete table columns: "TableName[Column Name]". To delete tables: "TableName".
• move_cells(source_selection_rect, target_top_left_position, sheet_name?) — Move a rectangular block of cells. Target is the top-left corner (single cell). For spilled code cells, move just the anchor cell.
• add_data_table(sheet_name, top_left_position, table_name, table_data) — Adds a data table. First row of table_data is headers. Leave 2 rows below and 2 columns right as spacing. All rows must have equal length (use empty strings for missing values). To convert existing data, use convert_to_table instead. To delete a table, use set_cell_values with empty string at the anchor. Don't add formulas or code to data tables.
Code:
• set_code_cell_value(code_cell_position, code_cell_language, code_cell_name, code_string, sheet_name?) — Sets and runs a Python or JavaScript code cell. Use for complex tasks (data transforms, ML, correlations, charts). For simple tasks use set_formula_cell_value. For static data use set_cell_values. For SQL use set_sql_code_cell_value. IMPORTANT: Always reference sheet data with q.cells() — never hardcode data values. For charts, use Plotly ONLY (import plotly.express or plotly.graph_objects). Do NOT use Matplotlib/Seaborn. Name the output (no spaces/special chars, _ allowed). Placement: Estimate output size before placing. Charts default to 7 wide x 23 tall cells. Cell must be empty (avoids spill error). Leave one extra column/row gap between the code cell and nearest content. Empty sheet → A1.
• set_formula_cell_value(formulas) — formulas: [{code_cell_position, formula_string, sheet_name?}]. Don't prefix formulas with =. code_cell_position can be a single cell ("A1"), range ("A1:A10"), or collection ("A1,A2:B2"). Cell references adjust relatively (like copy-paste). Use $ for absolute references ($A$1). Place near referenced data, no extra spacing needed. Aggregations go directly below or beside data.
• rerun_code(sheet_name?, selection?) — Re-run code cells. Do NOT call after set_code_cell_value, set_formula_cell_value, or set_sql_code_cell_value — those already run automatically. Only use to refresh unchanged code (e.g., external data).
• set_sql_code_cell_value(code_cell_position, code_cell_name, connection_kind, sql_code_string, connection_id, sheet_name?) — Sets and runs a SQL connection code cell. connection_kind: POSTGRES, MYSQL, MSSQL, SNOWFLAKE, BIGQUERY, COCKROACHDB, MARIADB, SUPABASE, NEON, MIXPANEL, GOOGLE_ANALYTICS, PLAID, QUICKBOOKS. Always call get_database_schemas before writing SQL. Cell must be empty. Empty sheet → A1.
Import:
• import_file(file_name, file_data, sheet_name?, insert_at?) — Import CSV/Excel/Parquet. file_data: base64-enco
This repository packages the hosted Quadratic MCP server as a Cursor plugin.
Installing it connects Cursor to Quadratic spreadsheets through the production
streamable HTTP MCP endpoint:
plugins/quadratic-mcp/mcp.json adds the hosted Quadratic MCP server.
plugins/quadratic-mcp/rules/ provides light guidance for using Quadratic MCP safely.
plugins/quadratic-mcp/skills/ adds an on-demand spreadsheet workflow skill.
plugins/quadratic-mcp/assets/logo.svg is the marketplace logo.
Usage
After installing the plugin in Cursor, open a chat and ask to work with a
Quadratic spreadsheet. If you are not authenticated yet, ask Cursor to run the
Quadratic MCP auth tool with the login action and complete the device auth
flow.
Example prompts:
"Open my Budget 2026 Quadratic file and summarize it."
"Create a Quadratic spreadsheet from this CSV."
"Add a Python code cell that analyzes sales by month."
"Show me the schema for my connected Postgres database."
Development
Validate the plugin manifest and referenced files:
bash
node scripts/validate-template.mjs
The marketplace manifest lives at .cursor-plugin/marketplace.json. The plugin
manifest lives at plugins/quadratic-mcp/.cursor-plugin/plugin.json.