Server definition
- Hash
- sha256:85a4e8b540e36533f6e7d60ef38c37387b0a441269c30f308ef01b78a20690cf
- What it is
- What a remote MCP server returned when asked what it offers: 5 tools
The blob, as servednamed by its sha256
{
"instructions": "# Using the Quadratic tools\n\nThe file summary returned when a file is opened already includes sample rows for every table. Consult that summary before calling read tools; fetch full data only when the sample is insufficient for the task.\n\n## Efficiency\n- Consolidate reads: pass comma-separated ranges to get_cell_data rather than making multiple calls.\n- Issue independent tool calls in parallel; only sequence them when one result feeds the next.\n- read_data supports action \"batch\" to run multiple reads in parallel; write_data supports action \"batch\" to run multiple writes sequentially. Batches inherit the parent tool's permission hint.\n\n## Code cells\nCode cells are not global — variables and imports declared in one cell are not visible in another. Use print() (Python) or console.log() (JavaScript) to inspect intermediate values. Formatting is applied with the formatting tools, not from code.\n\n## Formulas vs. code\nFormulas are included in the file-summary sample data. To read formulas beyond the sample, use get_cell_data. To write a formula, use set_formula_cell_value. get_code_cell_value is only for Python, JavaScript, and connection code — it does not return formula cell contents.\n\n## Placement\nWriting cells, tables, or code over an existing range produces a spill error. When a write reports a spill, use move_cells to relocate the new content with at least one empty cell between it and the existing range.\n\n# Quadratic Docs\n\nQuadratic is a modern AI-enabled spreadsheet combining formulas with Python, SQL, and JavaScript.\n\n## File and Data Support\n\nImport: Drag and drop csv, excel, or parquet files into the sheet or import via file menu. SQL connects to databases.\n\nExport: Highlight data > right-click > \"Download as CSV\" or File > Download > choose format (.grid, .xlsx, .csv)\n\nPDFs and images: Attach via AI chat paperclip button, paste, or drag into chat.\n\n## Code in Quadratic\n\nInsert code via AI or press `/` in a cell. Double-click or press `/` to edit existing code cells.\n\nCode cells are not global - variables and imports must be defined in each cell. Output data can be referenced by other cells.\n\nFormatting is done via AI or toolbar, not code.\n\nIMPORTANT: Prefer Formulas over Python and JavaScript. Only use Python or JavaScript when the functionality is not available in Formulas (e.g. charts, machine learning, complex data transforms, or web/API requests).\n\n## Tables in Quadratic\n\nPrefer plain cell values over data tables. Only create a data table when the user explicitly asks for one, or when working within a file that already uses data tables.\n\nWhen you lay out tabular data as plain cells, you MUST style the header row so it reads as a header — plain cells don't auto-style headers the way data tables do. Writing the values and styling the header are a single paired operation: in the SAME response/tool batch as the set_cell_values call, also call set_text_formats on the header row — always make it bold, and also apply a fill color and a bottom border so the header is clearly distinct from the data below. NEVER defer header formatting to a later step or wait to be prompted to continue; treat it as part of creating the table, not an optional finishing touch. Do this every time you write a plain-cell table.\n\nEditable tables (imported tables and value-based tables you can type into) DO support single-cell Formulas and Code (Python/JavaScript) directly inside their data cells. Such a cell is stored as a single-cell code cell that computes a 1x1 result shown in place — it does not create a separate table and has no table name or column header of its own. It recomputes when its dependencies change, can be referenced by other cells, and travels with its row when the table is sorted.\n\nCode-output tables (the table produced by a Python/JavaScript/Formula that returns an array or table) and charts are read-only: you cannot place Formulas or Code in their cells, nor in any table's name or column-header rows. To compute over a code-output table, reference its data from cells outside the table.\n\n## Placing Content\n\nNEVER place cells, tables, code, or connections over existing content. Before placing new data:\n1. Check existing data ranges from context provided\n2. Place new content outside those ranges (to the right or below, whichever makes sense given the context)\n3. Leave one cell of space between old and new data\n\n## Formatting Values\n\nUse spreadsheet values: enter 0.01 if trying to do 1% so you can format it and view it as 1% (formatting as % shows 1%). Emojis are supported.\n\n## Numeric Precision\n\nRound generated and computed numbers to at most 2 decimal places before writing them to the sheet or a chart. This keeps tables clean and removes floating-point noise like 0.5999999999999999. Round the stored value, not just its display: `round(x, 2)` in Python, `Math.round(x * 100) / 100` in JavaScript, `ROUND(x, 2)` in formulas. For fractions shown as percentages, round the fraction to 4 places so the percentage still shows 2 decimals (e.g. 0.0570 → 5.70%). Keep more precision only when accuracy requires it — stock or financial prices, scientific or statistical data, sub-cent currency, IDs, or values the user asks to keep exact.\n\n## Spills\n\nWhen code, tables, or charts expand and overlap existing content creating a spill error, use the move_cells tool to relocate with sufficient space to avoid creating another spill.\n\n\n# A1 Docs\n\nCell references in Quadratic are in A1 notation.\n\n## Rectangular Ranges\n\nRectangular ranges are references to a range of cells in a sheet. They are referenced by the top left cell and the bottom right cell. For example, A1:C3 is a rectangular range that references the cells A1, B1, C1, A2, B2, C2, A3, B3, and C3.\n\n### Rectangular Range Examples\n\n- D5 - references the cell D5\n- A1:C3 - references the cells A1, B1, C1, A2, B2, C2, A3, B3, and C3\n- A1:A3 - references the cells A1, A2, and A3\n- A1:C1 - references the cells A1, B1, and C1\n\n## Column and Row References\n\nIn A1 notation, when referencing an entire column or row, use the column or row name(s).\n\n**IMPORTANT**: Column and row references like `A` or `A3:A` should only be used for non-table data. When referencing columns within tables, ALWAYS use table column references like `Table_Name[Column Name]` instead of column references like `A` or infinite ranges like `A3:A`.\n\n### Column and Row Examples\n\n- B - references the entire column B (use only for non-table data)\n- B3:B - references all rows in column B starting from row 3 (use only for non-table data)\n- 10 - references the entire row 10\n- C4:C - references all columns in row C starting from row 4\n- D2:2 - references all columns in row 2 starting from column D\n\n## Table References\n\n**PREFERRED**: Always use table names (e.g., Table_Name) when working with entire tables or entire columns within tables. Use A1 notation only for non-table data or partial table selections.\n\n**IMPORTANT for Formatting and Conditional Formatting**: When applying formatting or conditional formatting to table columns, ALWAYS use table column references like `Table_Name[Column Name]` instead of A1 range notation like `A2:A2000`, column references like `A`, or infinite ranges like `A3:A`. This ensures the formatting applies correctly to the entire column as the table grows or shrinks.\n\nColumns within tables may be referenced by their name in A1 notation, eg, Table1[Column Name]. To reference multiple columns within a table, you use Table1[[Name]:[Address]]. In tables, you can also reference parts of the table. If you only want the table names, you can reference it with Table1[#HEADERS]. If you want the data and the headers, you would use Table1[[#DATA],[#HEADERS]]. By default, tables are referenced as Table1[#DATA].\n\nIf you need individual cells within a table, you need to use normal A1 reference. For example, if you want the first row of a table, you would reference it using its corresponding A1 reference. Remember that tables usually include a name row as the first row, and a column header row as the second row. (Although these may sometimes be hidden.)\n\n### Table Examples\n\n- Table1 - references the entire table's data\n- Table1[#HEADERS] - references the table headers\n- Table1[[#DATA],[#HEADERS]] - references the entire table including the headers\n- Table1[Column 2] - references a single column within Table1\n- Table1[[Name]:[Address]] - references a range of columns\n\n## Multiple Ranges\n\n You can reference multiple ranges by combining ranges with commas.\n\n### Multiple Range Examples\n\n- A1:C3,D5:F7\n- A1:C3,D5:F7,G9:I11\n- Table1[Column 2], A1:C3\n\n## Other Sheets\n\nYou can reference cells in other sheets by using the sheet name as part of the reference. Note, table names do not need sheet names as table names are unique within the file.\n\n### Other Sheet Examples\n\n- Sheet1!A1:C3\n- Sheet1!A1:C3,Sheet2!D5:F7\n- Sheet1!A1:C3,Sheet2!D5:F7,Sheet3!G9:I11\n- Table1[Column 2],Sheet2!A1:C3\n\n\n# Available Languages\nDefault to Formulas. Use Formulas whenever they can accomplish the task, and only reach for Python or JavaScript when the functionality is not available in Formulas (e.g. charts, machine learning, complex data transforms, or web/API requests).\n- **Formulas**: The default choice. Calculations, lookups, aggregations, cell references, conditional logic, text manipulation, and anything expressible with spreadsheet functions.\n- **Python**: Use only when Formulas can't do it — analysis, transforms, ML, visualizations. pandas, numpy, Plotly charts. Reference data with q.cells().\n- **JavaScript**: Use only when Formulas can't do it and the user prefers JavaScript. Chart.js charts. Reference data with q.cells().\n- **SQL Connections**: Query external databases (Postgres, MySQL, etc.).\n- **Agent Connections**: Call third-party REST APIs (Stripe, HubSpot, etc.) from Python/JavaScript fetch code, referencing team secrets as {{SECRET_NAME}} placeholders.\n- **Financial data**: For basic historical stock prices, use the STOCKHISTORY formula (unadjusted OHLCV). Use Python with q.financial only for data not available as a formula — adjusted prices, financial statements, dividends, splits, real-time/intraday prices, technical indicators, or economic data.\n\nFor detailed documentation on any action or topic, use the context action on the read_data or write_data tool. Multiple items may be requested in one call: action \"context\", params {\"actions\": [\"a\",\"b\"], \"topics\": [\"python\"]}. Singular forms are also accepted: {\"action\": \"<name>\"}, {\"topic\": \"<name>\"}. Topics: python, javascript, formula, connection, validation.\n\nQuadratic files have a public URL of the form https://app.quadratichq.com/file/<uuid>.",
"tools": [
{
"description": "Authenticate the MCP session with Quadratic.\n\nActions:\n• 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.\n• 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. confirm_login is idempotent: if a later tool call reports \"Not authenticated on this connection\", call confirm_login again with the same device_code to re-establish auth (some clients use a new session per request, so the session that ran the tool may differ from the one that logged in).\n• set_token(token, email?) — Set a JWT directly (used when the OAuth device flow is not available).\n• logout() — Clear saved authentication for the current session.\n",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"action": {
"description": "Action to perform: login, confirm_login, set_token, or logout",
"type": "string"
},
"params": {
"description": "Parameters for the action (see tool description)"
}
},
"required": [
"action"
],
"title": "AuthAction",
"type": "object"
},
"name": "auth",
"outputSchema": null
},
{
"description": "Read-only file metadata operations on Quadratic files the user has access to. No data is modified. Requires authentication.\n\nActions:\n• list_files() — List all accessible files.\n• get_file_info(file_id) — Get metadata for a single file.\n",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"action": {
"description": "Action to perform: list_files or get_file_info",
"type": "string"
},
"params": {
"description": "Parameters for the action (see tool description)"
}
},
"required": [
"action"
],
"title": "FilesReadAction",
"type": "object"
},
"name": "files_read",
"outputSchema": null
},
{
"description": "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.\n\nActions:\n• open_file(file_id?, file_name?) — Open a file by UUID or name and start an editing session. Returns the file's web URL.\n• 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.\n• close_file(file_id) — Close an active editing session.\n",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"action": {
"description": "Action to perform: open_file, create_file, or close_file",
"type": "string"
},
"params": {
"description": "Parameters for the action (see tool description)"
}
},
"required": [
"action"
],
"title": "FilesWriteAction",
"type": "object"
},
"name": "files_write",
"outputSchema": null
},
{
"description": "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.\n\nSpecial actions (not shown in the action enum):\n• batch — {\"action\": \"batch\", \"params\": {\"actions\": [{\"action\": \"<name>\", \"params\": {...}}, ...]}}. Runs reads in parallel; individual failures are reported per-entry without short-circuiting.\n• 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, chart, pivot_table.\n\nAction Reference\n\n• 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.\n• 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.\n• 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.\n• 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.\n• get_validations(sheet_name?) — Get all validations in a sheet.\n• get_conditional_formats(sheet_name) — Get all conditional formatting rules. Use to check existing rules before creating/updating/deleting.\n• 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.\n• get_sheet_info() — List all sheets and names.\n• get_spreadsheet_context(sheet_name?, include_errors?) — Full context snapshot of the file.\n• 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.\n• outline(sheet_name?) — Structural map of the file: sheets, bounds, tables, code cells, charts, connections, errors. Use to understand file layout before reading data.\n• dependencies(position, sheet_name?, direction?) — Trace cell dependencies. direction: \"forward\" (what this cell reads), \"reverse\" (what depends on this cell), or \"both\" (default).\n• export_pdf(options?) — Export the file as a PDF with Excel-parity print semantics. Returns {mime_type, size_bytes, data_base64}. options is a camelCase object: {sheetIds?: [id], fileName?, pageSetup?: {paperSize (\"letter\"|\"legal\"|\"tabloid\"|\"a3\"|\"a4\"|\"a5\"|...), orientation (\"portrait\"|\"landscape\"), margins {left,right,top,bottom,header,footer} (inches), scaling ({type:\"zoom\",percent} or {type:\"fitTo\",width?,height?}), pageOrder (\"downThenOver\"|\"overThenDown\"), centerHorizontally?, centerVertically?, printGridlines?, printHeadings?, header/footer {odd:{left,center,right}, even?, first?} with Excel codes (&P page, &N total, &D date, &T time, &F file, &A sheet, &B bold)}, sheetOptions?: {\"<sheetId>\": {pageSetup?, printArea? (\"A1:F20\"), repeatRows? ([1,2]), repeatCols?, rowBreaks?, colBreaks?}}}. Omit options for sensible defaults (letter portrait, 100% zoom, all sheets).\n• 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.\n• 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.\n• 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 URL, auth pattern, and `{{SECRET_NAME}}` references to use in fetch code. team_uuid is optional — if omitted, the user's only team is used; multi-team users must pass it. Reference secrets via `{{SECRET_NAME}}` in Python/JavaScript fetch code; the connection proxy substitutes team secret values at request time.\n• inspect_agent_connection(connection_id, team_uuid?) — Get the full schema (resources, endpoints, fields, docs URLs) and plan for one ready Agent Connection by uuid (from list_agent_connections). Call BEFORE writing fetch code against a connection so you don't guess at endpoints. team_uuid is optional with the same single-team fallback as list_agent_connections.\n\nBatch:\n• batch(actions) — actions: [{action, params}]. Runs reads in parallel through this same tool; per-entry failures are reported in the result without short-circuiting the batch. `action` may be any name from this reference. Nested `context` items are allowed and returned alongside the reads.\n",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"action": {
"description": "Action to perform: get_cell_data, has_cell_data, get_code_cell_value, get_text_formats, get_validations, get_conditional_formats, text_search, get_sheet_info, get_spreadsheet_context, read_data, outline, dependencies, export_pdf, get_database_schemas, list_connections, list_agent_connections, inspect_agent_connection, or batch",
"type": "string"
},
"params": {
"description": "Parameters for the action (see tool description). For batch: {actions: [{action, params}, ...]}"
}
},
"required": [
"action"
],
"title": "ReadDataAction",
"type": "object"
},
"name": "read_data",
"outputSchema": null
},
{
"description": "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.\n\nSpecial actions (not shown in the action enum):\n• batch — {\"action\": \"batch\", \"params\": {\"actions\": [{\"action\": \"<name>\", \"params\": {...}}, ...]}}. Runs writes sequentially; errors short-circuit the batch.\n• 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, chart, pivot_table.\n\nAction Reference\n\nCell Data:\n• 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 for tabular data; only use add_data_table when the user explicitly asks for a data table or the file already uses data tables. When writing tabular data as plain cells, format the header row afterward with set_text_formats (at least bold) so it's visually distinct — plain cells don't auto-style headers like data tables do. Don't use for formulas or code.\n• 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\".\n• 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.\n• add_data_table(top_left_position, table_name, table_data, sheet_name?) — Adds a data table. Data tables are discouraged by default — only use when the user specifically requests a data table or the file already uses data tables; otherwise use set_cell_values. 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. A single-value formula or code cell MAY be written into a data cell of an editable (imported/value) table — it's stored as in-place single-cell code computing a 1x1 result; avoid the table's name/column-header rows and read-only code-output tables/charts, and don't put multi-cell output (dataframes/charts) inside a table.\n\nCode:\n• 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. Prefer set_formula_cell_value whenever a formula can do the task; only use code when the functionality is not available in formulas (e.g. charts, ML, correlations, complex data transforms, or web/API requests). 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.\n• set_formula_cell_value(formulas) — formulas: [{code_cell_position, formula_string, sheet_name?}]. Prefer this whenever a formula can do the task; only use set_code_cell_value when formulas can't. For basic historical stock prices use the STOCKHISTORY formula; for financial data with no formula equivalent (adjusted prices, statements, dividends, real-time/intraday, technicals, economic data) use set_code_cell_value with Python + q.financial. 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.\n• 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).\n• 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.\n\nImport:\n• import_file(file_name, file_data, sheet_name?, insert_at?) — Import CSV/Excel/Parquet. file_data: base64-encoded. Extension determines format (.csv, .xlsx/.xls, .parquet/.parq/.pqt). To create a new file from an import, call files create_file first, then import_file.\n\nFormatting:\n• set_text_formats(formats) — formats array: [{selection, bold?, italic?, underline?, strike_through?, text_color?, fill_color?, align?, vertical_align?, wrap?, font_size?, number_type?, currency_symbol?, numeric_decimals?, numeric_commas?, date_time?, sheet_name?}]. For table columns use table references (\"Table_Name[Column Name]\") instead of A1 ranges. Colors: hex (\"#FF0000\"), empty string to remove. align: \"left\"/\"center\"/\"right\". vertical_align: \"top\"/\"middle\"/\"bottom\". wrap: \"wrap\"/\"clip\"/\"overflow\". number_type: \"number\"/\"currency\"/\"percentage\"/\"exponential\" (currency requires currency_symbol, e.g. \"$\"). numeric_decimals: integer >= 0, number of decimal places to display (e.g. \"format percents as 2 decimals\" → 2). Percentages: .01 → 1%, 1 → 100%. date_time: chrono format e.g. \"%Y-%m-%d\". font_size: points (default 10). Set to null to clear any format.\n• set_borders(borders) — borders: [{selection, border_selection, color, line, sheet_name?}]. border_selection: all/inner/outer/horizontal/vertical/left/top/right/bottom/clear. line: line1 (thin)/line2 (medium)/line3 (thick)/dotted/dashed/double/clear. color: CSS color string.\n• merge_cells(selection, sheet_name?) — Merge a range of cells (e.g. A1:D1). All values except top-left are cleared.\n• unmerge_cells(selection, sheet_name?) — Unmerge merged cells overlapping the selection.\n\nSheets:\n• add_sheet(sheet_name, insert_before_sheet_name?) — Sheet names: unique, max 31 chars, no / \\ ? * : [ ]\n• duplicate_sheet(sheet_name_to_duplicate, name_of_new_sheet)\n• rename_sheet(sheet_name, new_name)\n• delete_sheet(sheet_name)\n• move_sheet(sheet_name, insert_before_sheet_name?)\n• color_sheets(sheet_names_to_color) — [{sheet_name, color}]. color: CSS color string.\n• set_frozen_panes(sheet_name?, frozen_row_count, frozen_column_count) — freeze/pin rows from row 1 and columns from column 1. Use 0 to unfreeze an axis.\n\nTables:\n• convert_to_table(selection, table_name, first_row_is_column_names, sheet_name?) — Convert existing cell data to a data table. Only use when the user explicitly asks for a data table or the file already uses data tables; otherwise keep data as plain cells. Selection must NOT contain code cells or existing tables. Table name row is added above, pushing data down by one row.\n• table_meta(table_location, new_table_name?, show_name?, show_columns?, alternating_row_colors?, first_row_is_column_names?, sheet_name?) — Set table metadata. table_location: anchor cell (top-left, e.g. A5).\n• table_column_settings(table_location, column_names, sheet_name?) — column_names: [{old_name, new_name, show}]. Only include columns to change. To delete columns use delete_cells with \"TableName[Column Name]\".\n\nLayout:\n• resize_columns(selection, size, sheet_name?) — size: \"auto\" (fit content), \"default\", or pixels (20-2000).\n• resize_rows(selection, size, sheet_name?) — size: \"auto\", \"default\", or pixels (10-2000).\n• set_default_column_width(size, sheet_name?) — size in pixels (20-2000, default 100).\n• set_default_row_height(size, sheet_name?) — size in pixels (10-2000, default 21).\n• insert_columns(column, right, count, sheet_name?) — column: letter (e.g. \"C\"). right: true=insert right, false=insert left.\n• insert_rows(row, below, count, sheet_name?) — row: number. below: true=insert below, false=insert above.\n• delete_columns(columns, sheet_name?) — columns: array of letters (e.g. [\"A\", \"C\"]).\n• delete_rows(rows, sheet_name?) — rows: array of numbers (e.g. [1, 5, 10]).\n\nCharts (Excel-native; prefer over Plotly/Chart.js code cells for standard charts of sheet data — see the \"chart\" topic for details):\n• add_chart(chart_type, position, series, sheet_name?, title?, name?, categories?, legend?, x_axis_title?, x_axis_min?, x_axis_max?, x_axis_number_format?, y_axis_title?, y_axis_min?, y_axis_max?, y_axis_number_format?, width_cells?, height_cells?, chart_3d_rot_x?, chart_3d_rot_y?, chart_3d_perspective?, chart_3d_depth_gap?) — Adds an Excel-native chart anchored at position (single cell). chart_type: column, column_stacked, column_percent_stacked, bar, bar_stacked, bar_percent_stacked, line, line_stacked, area, area_stacked, pie, doughnut, scatter, scatter_line, bubble, radar, radar_filled, stock, column_3d, bar_3d, line_3d, area_3d, pie_3d, waterfall, funnel, histogram, pareto, box_whisker, treemap, sunburst, region_map. series: [{values, name?, bubble_sizes?, color?}] where values is one row or column of numbers in A1 (\"B2:B13\", table references allowed). categories: labels range (x values for scatter/bubble). Charts float over the grid (no spill errors); the anchor is nudged to free space if the cell would cover content. Returns the chart_id for update_chart/delete_chart.\n• update_chart(chart_id, sheet_name?, chart_type?, position?, series?, title?, name?, categories?, legend?, axis and 3d options as in add_chart) — Changes an existing chart; omitted arguments leave that part unchanged. Chart ids are returned by add_chart and listed in the file context under \"Native Chart\".\n• delete_chart(chart_id, sheet_name?) — Removes a chart.\n\nPivot Tables:\n• set_pivot_table(action, pivot_table_name?, sheet_name?, source?, destination?, rows?, columns?, values?, filters?, layout?, values_layout?, row_grand_total?, column_grand_total?, subtotal_position?) — Creates (\"create\"), reconfigures (\"update\"), or removes (\"delete\") a PivotTable: a live cross-tabulation that groups source rows and aggregates values, recomputing when the source changes. Prefer it over SUMIFS or a Python groupby for \"totals by category\" requests. Reference source columns by header name, not letter. source (create): A1 range with a header row or a table name. destination (create): \"new_sheet\" (default) or a top-left cell. rows/columns: [{field, label?, sort?, show_totals?, group_by?, numeric_interval?}]. values (at least one): [{field, aggregation?, name?, show_as?, number_format?, decimals?, visual?}]. filters: [{field, include?, exclude?}]. For update: null leaves an area as it is, an empty array clears it — send only the areas you're changing. pivot_table_name is required for update/delete; names are listed in the file context. The report's cells are read-only; change it with this action. See the \"pivot_table\" topic for details.\n\nValidation:\n• add_logical_validation(selection, show_checkbox?, ignore_blank?, sheet_name?) — True/false validation with optional checkbox.\n• add_list_validation(selection, list_source_list?, list_source_selection?, drop_down?, ignore_blank?, sheet_name?) — list_source_list: comma-separated values (\"Item 1, Item 2\"). list_source_selection: A1 cell reference. Use one, not both.\n• remove_validation(selection, sheet_name?) — Remove all validations from the selection.\n\nConditional Formatting:\n• update_conditional_formats(sheet_name, rules) — rules: [{action, id?, selection?, type?, rule?, bold?, italic?, underline?, strike_through?, text_color?, fill_color?, apply_to_empty?, color_scale_thresholds?, auto_contrast_text?}]. action: \"create\"/\"update\"/\"delete\". type: \"formula\" (apply styles when formula is true) or \"color_scale\" (gradient colors). For formula type: rule examples: \"A1>100\", \"ISBLANK(A1)\", \"AND(A1>=5,A1<=10)\". For color_scale: thresholds: [{value_type: \"min\"/\"max\"/\"number\"/\"percent\"/\"percentile\", value, color}]. For table columns use table references instead of A1 ranges. For delete: only id required.\n\nHistory:\n• undo(count?) — Default 1.\n• redo(count?) — Default 1.\n\nBatch:\n• batch(actions) — actions: [{action, params}]. Runs writes sequentially through this same tool; errors short-circuit the batch. `action` may be any name from this reference. Nested `context` items are allowed and returned alongside the writes.\n",
"inputSchema": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"action": {
"description": "Action to perform: set_cell_values, delete_cells, move_cells, add_data_table, set_code_cell_value, set_formula_cell_value, rerun_code, set_text_formats, set_borders, merge_cells, unmerge_cells, add_sheet, duplicate_sheet, rename_sheet, delete_sheet, move_sheet, color_sheets, set_frozen_panes, convert_to_table, table_meta, table_column_settings, resize_columns, resize_rows, set_default_column_width, set_default_row_height, insert_columns, insert_rows, delete_columns, delete_rows, add_logical_validation, add_list_validation, remove_validation, update_conditional_formats, add_chart, update_chart, delete_chart, set_pivot_table, set_sql_code_cell_value, import_file, undo, redo, or batch",
"type": "string"
},
"params": {
"description": "Parameters for the action (see tool description). For batch: {actions: [{action, params}, ...]}"
}
},
"required": [
"action"
],
"title": "WriteDataAction",
"type": "object"
},
"name": "write_data",
"outputSchema": null
}
]
}Verify it yourself
curl -s https://api.teppi.xyz/v1/evidence/sha256:85a4e8b540e36533f6e7d60ef38c37387b0a441269c30f308ef01b78a20690cf | sha256sum