Excel Automation with excelcli
Preconditions
Workflow Checklist
| Step |
Command |
When |
| 1. Session |
session create/open |
Always first |
| 2. Sheets |
worksheet create/rename |
If needed |
| 3. Write data |
See below |
If writing values |
| 4. Save & close |
session close --save |
Always last |
10+ commands? Use excelcli -q batch --input commands.json — sends all commands in one process with automatic session management. See Rule 8.
Writing Data (Step 3):
--values takes a JSON 2D array string: --values '[["Header1","Header2"],[1,2]]'
- Write one row at a time for reliability:
--range-address A1:B1 --values '[["Name","Age"]]'
- Strings MUST be double-quoted in JSON:
"text". Numbers are bare: 42
- Always wrap the entire JSON value in single quotes to protect special characters
CRITICAL RULES (MUST FOLLOW)
⚡ Building dashboards or bulk operations? Skip to Rule 8: Batch Mode — it eliminates per-command process overhead and auto-manages session IDs.
Rule 1: NEVER Ask Clarifying Questions
Execute commands to discover the answer instead:
| DON'T ASK |
DO THIS INSTEAD |
| "Which file should I use?" |
excelcli -q session list |
| "What table should I use?" |
excelcli -q table list --session <id> |
| "Which sheet has the data?" |
excelcli -q worksheet list --session <id> |
You have commands to answer your own questions. USE THEM.
Rule 2: Always End With a Text Summary
NEVER end your turn with only a command execution. After completing all operations, always provide a brief text message confirming what was done. Silent command-only responses are incomplete.
Rule 3: Session Lifecycle
Creating vs Opening Files:
# NEW file - use session create
excelcli -q session create C:\path\newfile.xlsx # Creates file + returns session ID
# EXISTING file - use session open
excelcli -q session open C:\path\existing.xlsx # Opens file + returns session ID
CRITICAL: Use session create for new files. session open on non-existent files will fail!
CRITICAL: ALWAYS use the session ID returned by session create or session open in subsequent commands. NEVER guess or hardcode session IDs. The session ID is in the JSON output (e.g., {"sessionId":"abc123"}). Parse it and use it.
# Example: capture session ID from output, then use it
excelcli -q session create C:\path\file.xlsx # Returns JSON with sessionId
excelcli -q range set-values --session <returned-session-id> ...
excelcli -q session close --session <returned-session-id> --save
Unclosed sessions leave Excel processes running, locking files.
Rule 4: Data Model Prerequisites
DAX operations require tables in the Data Model:
excelcli -q table add-to-data-model --session <id> --table-name Sales # Step 1
excelcli -q datamodel create-measure --session <id> ... # Step 2 - NOW works
Rule 5: Power Query Development Lifecycle
BEST PRACTICE: Test M code before creating permanent queries
# Step 1: Create/open a session and capture the session ID
$session = excelcli -q session create C:\path\file.xlsx | ConvertFrom-Json
$sessionId = $session.sessionId
# Step 2: Test M code without persisting (catches errors early)
excelcli -q powerquery evaluate --session $sessionId --m-code-file query.m
# Step 3: Create permanent query with validated code
excelcli -q powerquery create --session $sessionId --query-name Q1 --m-code-file query.m
# Step 4: Load data to destination
excelcli -q powerquery refresh --session $sessionId --query-name Q1
# Step 5: Close session
excelcli -q session close --session $sessionId --save
Rule 6: Report File Errors Immediately
If you see "File not found" or "Path not found" - STOP and report to user. Don't retry.
Rule 7: Use Calculation Mode for Bulk Writes
When writing many values/formulas (10+ cells), disable auto-recalc for performance:
# 1. Create/open a session and capture the session ID
$session = excelcli -q session create C:\path\file.xlsx | ConvertFrom-Json
$sessionId = $session.sessionId
# 2. Set manual mode
excelcli -q calculationmode set-mode --session $sessionId --mode manual
# 3. Write data row by row for reliability
excelcli -q range set-values --session $sessionId --sheet-name Sheet1 --range-address A1:B1 --values '[["Name","Amount"]]'
excelcli -q range set-values --session $sessionId --sheet-name Sheet1 --range-address A2:B2 --values '[["Salary",5000]]'
# 4. Recalculate once at end
excelcli -q calculationmode calculate --session $sessionId --scope workbook
# 5. Restore automatic mode
excelcli -q calculationmode set-mode --session $sessionId --mode automatic
# 6. Close session
excelcli -q session close --session $sessionId --save
Rule 8: Use Batch Mode for Bulk Operations (10+ commands)
When executing 10+ commands on the same file, use excelcli batch to send all commands in a single process launch. This avoids per-process startup overhead and terminal buffer saturation.
# Create a JSON file with all commands
@'
[
{"command": "session.open", "args": {"filePath": "C:\\path\\file.xlsx"}},
{"command": "range.set-values", "args": {"sheetName": "Sheet1", "rangeAddress": "A1", "values": [["Hello"]]}},
{"command": "range.set-values", "args": {"sheetName": "Sheet1", "rangeAddress": "A2", "values": [["World"]]}},
{"command": "session.close", "args": {"save": true}}
]
'@ | Set-Content commands.json
# Execute all commands at once
excelcli -q batch --input commands.json
Key features:
- Session auto-capture:
session.open/create result sessionId auto-injected into subsequent commands — no need to parse and pass session IDs
- NDJSON output: One JSON result per line:
{"index": 0, "command": "...", "success": true, "result": {...}}
--stop-on-error: Exit on first failure (default: continue all)
--session <id>: Pre-set session ID for all commands (skip session.open)
Input formats:
- JSON array from file:
excelcli -q batch --input commands.json
- NDJSON from stdin:
Get-Content commands.ndjson | excelcli -q batch
CLI Command Reference
Auto-generated from excelcli --help. Use these exact parameter names.
calculationmode
Control Excel recalculation (automatic vs manual). Set manual mode before bulk writes for faster performance, then recalculate once at the end.
Actions: get-mode, set-mode, calculate
| Parameter |
Description |
--mode |
Target calculation mode (required for: set-mode) |
--scope |
Scope: Workbook, Sheet, or Range (required for: calculate) |
--sheet-name |
Sheet name (required for Sheet/Range scope) |
--range-address |
Range address (required for Range scope) |
chart
Chart lifecycle - create, read, move, and delete embedded charts. POSITIONING (choose one): - targetRange (PREFERRED): Cell range like 'F2:K15' — positions chart within cells, no point math needed. - left/top: Manual positioning in points (72 points = 1 inch). - Neither: Auto-positions chart below all existing content (used range + other charts). COLLISION DETECTION: All create/move/fit-to-range operations automatically check for overlaps with data and other charts. Warnings are returned in the result message if collisions are detected. Always verify layout with screenshot(capture-sheet) after creating charts. CHART TYPES: 70+ types available including Column, Line, Pie, Bar, Area, XY Scatter. CREATE OPTIONS: - create-from-range: Create from cell range (e.g., 'A1:D10') - create-from-table: Create from Excel Table (uses table's data range) - create-from-pivottable: Create linked PivotChart Use chartconfig for series, titles, legends, styles, placement mode.
Actions: list, read, create-from-range, create-from-table, create-from-pivottable, delete, move, fit-to-range
| Parameter |
Description |
--chart-name |
Name of the chart (or shape name) (required for: read, delete, move, fit-to-range) |
--sheet-name |
Target worksheet name (required for: create-from-range, create-from-table, create-from-pivottable, fit-to-range) |
--source-range-address |
Data range for the chart (e.g., A1:D10) (required for: create-from-range) |
--chart-type |
Type of chart to create (required for: create-from-range, create-from-table, create-from-pivottable) |
--left |
Left position in points from worksheet edge |
--top |
Top position in points from worksheet edge |
--width |
Chart width in points |
--height |
Chart height in points |
--target-range |
Cell range to position chart within (e.g., 'F2:K15'). PREFERRED over left/top. When set, left/top are ignored. |
--table-name |
Name of the Excel Table (required for: create-from-table) |
--pivot-table-name |
Name of the source PivotTable (required for: create-from-pivottable) |
--range-address |
Range to fit the chart to (e.g., A1:D10) (required for: fit-to-range) |
chartconfig
Chart configuration - data source, series, type, title, axis labels, legend, and styling. SERIES MANAGEMENT: - add-series: Add data series with valuesRange (required) and optional categoryRange - remove-series: Remove series by 1-based index - set-source-range: Replace entire chart data source TITLES AND LABELS: - set-title: Set chart title (empty string hides title) - set-axis-title: Set axis labels (Category, Value, CategorySecondary, ValueSecondary) CHART STYLES: 1-48 (built-in Excel styles with different color schemes) DATA LABELS: Show values, percentages, series/category names. Positions: Center, InsideEnd, InsideBase, OutsideEnd, BestFit. TRENDLINES: Linear, Exponential, Logarithmic, Polynomial (order 2-6), Power, MovingAverage. PLACEMENT MODE: - 1: Move and size with cells - 2: Move but don't size with cells - 3: Don't move or size with cells (free floating) Use chart for lifecycle operations (create, delete, move, fit-to-range).
Actions: set-source-range, add-series, remove-series, set-chart-type, set-title, set-axis-title, get-axis-number-format, set-axis-number-format, show-legend, set-style, set-placement, set-data-labels, get-axis-scale, set-axis-scale, get-gridlines, set-gridlines, set-series-format, list-trendlines, add-trendline, delete-trendline, set-trendline
| Parameter |
Description |
--chart-name |
Name of the chart (required) |
--source-range |
New data source range (e.g., Sheet1!A1:D10) (required for: set-source-range) |
--series-name |
Display name for the series (required for: add-series) |
--values-range |
Range containing series values (e.g., B2:B10) (required for: add-series) |
--category-range |
Optional range for category labels (e.g., A2:A10) |
--series-index |
1-based index of the series to remove (required for: remove-series, set-series-format, list-trendlines, add-trendline, delete-trendline, set-trendline) |
--chart-type |
New chart type to apply (required for: set-chart-type) |
--title |
Title text to display (required for: set-title, set-axis-title) |
--axis |
Which axis to set title for (Category, Value, SeriesAxis) (required for: set-axis-title, get-axis-number-format, set-axis-number-format, get-axis-scale, set-axis-scale, set-gridlines) |
--number-format |
Excel number format code (e.g., "$#,##0", "0.00%") (required for: set-axis-number-format) |
--visible |
True to show legend, false to hide (required for: show-legend) |
--legend-position |
Optional position for the legend |
--style-id |
Excel chart style ID (1-48 for most chart types) (required for: set-style) |
--placement |
Placement mode: 1=MoveAndSize, 2=Move, 3=FreeFloating (required for: set-placement) |
--show-value |
Show data values on labels |
--show-percentage |
Show percentage values. Only meaningful for pie and doughnut chart types; setting to true on other chart types has no visual effect. |
--show-series-name |
Show series name on labels |
--show-category-name |
Show category name on labels |
--show-bubble-size |
Show bubble size (bubble charts) |
--separator |
Separator string between label components |
--label-position |
Position of data labels relative to data points |
--minimum-scale |
Minimum axis value (null for auto) |
--maximum-scale |
Maximum axis value (null for auto) |
--major-unit |
Major gridline interval (null for auto) |
--minor-unit |
Minor gridline interval (null for auto) |
--show-major |
Show major gridlines (null to keep current) |
--show-minor |
Show minor gridlines (null to keep current) |
--marker-style |
Marker shape style |
--marker-size |
Marker size in points (2-72) |
--marker-background-color |
Marker fill color (#RRGGBB) |
--marker-foreground-color |
Marker border color (#RRGGBB) |
--invert-if-negative |
Invert colors for negative values |
--trendline-type |
Type of trendline (Linear, Exponential, etc.) (required for: add-trendline) |
--order |
Polynomial order (2-6, for Polynomial type) |
--period |
Moving average period (for MovingAverage type) |
--forward |
Periods to extend forward |
--backward |
Periods to extend backward |
--intercept |
Force trendline through specific Y-intercept |
--display-equation |
Display trendline equation on chart |
--display-r-squared |
Display R-squared value on chart |
--name |
Custom name for the trendline |
--trendline-index |
1-based index of the trendline to delete (required for: delete-trendline, set-trendline) |
conditionalformat
Conditional formatting - visual rules based on cell values. TYPES: cellValue (requires operatorType+formula1), expression (formula only). Both camelCase and kebab-case accepted. FORMAT: interiorColor/fontColor as #RRGGBB, fontBold/Italic, borderStyle/Color. OPERATORS: equal, notEqual, greater, less, greaterEqual, lessEqual, between, notBetween. For 'between' and 'notBetween', both formula1 and formula2 are required.
Actions: add-rule, clear-rules
| Parameter |
Description |
--sheet-name |
Sheet name (empty for active sheet) |
--range-address |
Range address (A1 notation or named range) |
--rule-type |
Rule type: cellValue (or cell-value), expression, colorScale, dataBar, top10, iconSet, uniqueValues, blanksCondition, timePeriod, aboveAverage. Both camelCase and kebab-case accepted. |
--operator-type |
XlFormatConditionOperator: equal, notEqual, greater, less, greaterEqual, lessEqual, between, notBetween |
--formula1 |
First formula/value for condition |
--formula2 |
Second formula/value (for between/notBetween) |
--interior-color |
Fill color (#RRGGBB or color index) |
--interior-pattern |
Interior pattern (1=Solid, -4142=None, 9=Gray50, etc.) |
--font-color |
Font color (#RRGGBB or color index) |
--font-bold |
Bold font |
--font-italic |
Italic font |
--border-style |
Border style: none, continuous, dash, dot, etc. |
--border-color |
Border color (#RRGGBB or color index) |
connection
Data connections (OLEDB, ODBC, ODC import). TEXT/WEB/CSV: Use powerquery instead. Power Query connections auto-redirect to powerquery. TIMEOUT: 30 min auto-timeout for refresh/load-to.
Actions: list, view, create, refresh, delete, load-to, get-properties, set-properties, test
| Parameter |
Description |
--connection-name |
Name of the connection to view |
--connection-string |
OLEDB or ODBC connection string |
--command-text |
SQL query or table name |
--description |
Optional description for the connection |
--timeout |
Optional timeout for the refresh operation |
--sheet-name |
Target worksheet name |
--connection-string |
New connection string (null to keep current) |
--command-text |
New SQL query or table name (null to keep current) |
--background-query |
Run query in background (null to keep current) |
--refresh-on-file-open |
Refresh when file opens (null to keep current) |
--save-password |
Save password in connection (null to keep current) |
--refresh-period |
Auto-refresh interval in minutes (null to keep current) |
datamodel
Data Model (Power Pivot) - DAX measures and table management. CRITICAL: WORKSHEET TABLES AND DATA MODEL ARE SEPARATE! - After table append changes, Data Model still has OLD data - MUST call refresh to sync changes - Power Query refresh auto-syncs (no manual refresh needed) PREREQUISITE: Tables must be added to the Data Model first. Use table add-to-datamodel for worksheet tables, or powerquery to import and load data directly to the Data Model. DAX MEASURES: - Create with DAX formulas like 'SUM(Sales[Amount])' - DAX formulas are auto-formatted on CREATE/UPDATE via Dax.Formatter (SQLBI) - Read operations return raw DAX as stored DAX EVALUATE QUERIES: - Use evaluate to execute DAX EVALUATE queries against the Data Model - Returns tabular results from queries like 'EVALUATE TableName' - Supports complex DAX: SUMMARIZE, FILTER, CALCULATETABLE, TOPN, etc. DMV (DYNAMIC MANAGEMENT VIEW) QUERIES: - Use execute-dmv to query Data Model metadata via SQL-like syntax - Syntax: SELECT * FROM $SYSTEM.SchemaRowset (ONLY SELECT * supported) - Use DISCOVER_SCHEMA_ROWSETS to list all available DMVs Use datamodelrel for relationships between tables.
Actions: list-tables, list-columns, read-table, read-info, list-measures, read, delete-measure, delete-table, rename-table, refresh, create-measure, update-measure, evaluate, execute-dmv
| Parameter |
Description |
--table-name |
Name of the table to list columns from (required for: list-columns, read-table, delete-table, create-measure) |
--measure-name |
Name of the measure to get (required for: read, delete-measure, create-measure, update-measure) |
--old-name |
Current name of the table (required for: rename-table) |
--new-name |
New name for the table (required for: rename-table) |
--timeout |
Optional: Timeout for the refresh operation |
--dax-formula |
DAX formula for the measure (will be auto-formatted) (required for: create-measure) |
--format-type |
Optional: Format type (Currency, Decimal, Percentage, General) |
--description |
Optional: Description of the measure |
--dax-query |
DAX EVALUATE query (e.g., "EVALUATE 'TableName'" or "EVALUATE SUMMARIZE(...)") (required for: evaluate) |
--dmv-query |
DMV query in SQL-like syntax (e.g., "SELECT * FROM $SYSTEM.TMSCHEMA_TABLES") (required for: execute-dmv) |
datamodelrelationship
Data Model relationships - link tables for cross-table DAX calculations. CRITICAL: Deleting or recreating tables removes ALL their relationships. Use list-relationships before table operations to backup, then recreate relationships after schema changes. RELATIONSHIP REQUIREMENTS: - Both tables must exist in the Data Model first - Columns must have compatible data types - fromTable/fromColumn = many-side (detail table, foreign key) - toTable/toColumn = one-side (lookup table, primary key) ACTIVE VS INACTIVE: - Only ONE active relationship can exist between two tables - Use active=false when creating alternative paths - DAX USERELATIONSHIP() activates inactive relationships
Actions: list-relationships, read-relationship, create-relationship, update-relationship, delete-relationship
| Parameter |
Description |
--from-table |
Source table name (required for: read-relationship, create-relationship, update-relationship, delete-relationship) |
--from-column |
Source column name (required for: read-relationship, create-relationship, update-relationship, delete-relationship) |
--to-table |
Target table name (required for: read-relationship, create-relationship, update-relationship, delete-relationship) |
--to-column |
Target column name (required for: read-relationship, create-relationship, update-relationship, delete-relationship) |
--active |
Whether the relationship should be active (default: true) (required for: update-relationship) |
diag
Diagnostic commands for testing CLI/MCP infrastructure without Excel. These commands validate parameter parsing, routing, JSON serialization, and error handling — no Excel COM session needed.
Actions: ping, echo, validate-params
| Parameter |
Description |
--message |
The message to echo back (required) (required for: echo) |
--tag |
Optional tag to include in the response |
--name |
Required name parameter (required for: validate-params) |
--count |
Required integer parameter (required for: validate-params) |
--label |
Optional label parameter |
--verbose |
Optional boolean flag (default: false) |
namedrange
Named ranges for formulas/parameters. CREATE/UPDATE: value is cell reference (e.g., 'Sheet1!$A$1'). WRITE: value is data to store. TIP: range(rangeAddress=namedRangeName) for bulk data read/write.
Actions: list, write, read, update, create, delete
| Parameter |
Description |
--name |
Name of the named range (required for: write, read, update, create, delete) |
--value |
Value to set (required for: write) |
--reference |
New cell reference (e.g., Sheet1!$A$1:$B$10) (required for: update, create) |
pivottable
PivotTable lifecycle management: create from various sources, list, read details, refresh, and delete. Use pivottablefield for field operations, pivottablecalc for calculated fields and layout. BEST PRACTICE: Use 'list' before creating. Prefer 'refresh' or field modifications over delete+recreate. Delete+recreate loses field configurations, filters, sorting, and custom layouts. REFRESH: Call 'refresh' after configuring fields with pivottablefield to update the visual display. This is especially important for OLAP/Data Model PivotTables where field operations are structural only and don't automatically trigger a visual refresh. CREATE OPTIONS: - 'create-from-range': Use source sheet and range address for data range - 'create-from-table': Use an Excel Table (ListObject) as source - 'create-from-datamodel': Use a Power Pivot Data Model table as source
Actions: list, read, create-from-range, create-from-table, create-from-datamodel, delete, refresh
| Parameter |
Description |
--pivot-table-name |
Name of the PivotTable (required for: read, create-from-range, create-from-table, create-from-datamodel, delete, refresh) |
--source-sheet |
Source worksheet name (required for: create-from-range) |
--source-range |
Source range address (e.g., "A1:F100") (required for: create-from-range) |
--destination-sheet |
Destination worksheet name (required for: create-from-range, create-from-table, create-from-datamodel) |
--destination-cell |
Destination cell address (e.g., "A1") (required for: create-from-range, create-from-table, create-from-datamodel) |
--table-name |
Name of the Excel Table (required for: create-from-table, create-from-datamodel) |
--timeout |
Optional timeout for the refresh operation |
pivottablecalc
PivotTable calculated fields/members, layout configuration, and data extraction. Use pivottable for lifecycle, pivottablefield for field placement. CALCULATED FIELDS (for regular PivotTables): - Create custom fields using formulas like '=Revenue-Cost' or '=Quantity*UnitPrice' - Can reference existing fields by name - After creating, use pivottablefield add-value-field to add to Values area - For complex multi-table calculations, prefer DAX measures with datamodel CALCULATED MEMBERS (for OLAP/Data Model PivotTables only): - Create using MDX expressions - Member types: Member, Set, Measure LAYOUT OPTIONS: - 0 = Compact (default, fields in single column) - 1 = Tabular (each field in separate column - best for export/analysis) - 2 = Outline (hierarchical with expand/collapse)
Actions: get-data, create-calculated-field, list-calculated-fields, delete-calculated-field, list-calculated-members, create-calculated-member, delete-calculated-member, set-layout, set-subtotals, set-grand-totals
| Parameter |
Description |
--pivot-table-name |
Name of the PivotTable (required) |
--field-name |
Name for the calculated field (required for: create-calculated-field, delete-calculated-field, set-subtotals) |
--formula |
Formula using field references (e.g., "=Revenue-Cost") (required for: create-calculated-field, create-calculated-member) |
--member-name |
Name for the calculated member (MDX naming format) (required for: create-calculated-member, delete-calculated-member) |
--type |
Type of calculated member (Member, Set, or Measure) |
--solve-order |
Solve order for calculation precedence (default: 0) |
--display-folder |
Display folder path for organizing measures (optional) |
--number-format |
Number format code for the calculated member (optional) |
--row-layout |
Layout form: 0=Compact, 1=Tabular, 2=Outline (required for: set-layout) |
--show-subtotals |
True to show automatic subtotals, false to hide (required for: set-subtotals) |
--show-row-grand-totals |
Show row grand totals (bottom summary row) (required for: set-grand-totals) |
--show-column-grand-totals |
Show column grand totals (right summary column) (required for: set-grand-totals) |
pivottablefield
PivotTable field management: add/remove/configure fields, filtering, sorting, and grouping. Use pivottable for lifecycle, pivottablecalc for calculated fields and layout. IMPORTANT: Field operations modify structure only. Call pivottable refresh after configuring fields to update the visual display, especially for OLAP/Data Model PivotTables. FIELD AREAS: - Row fields: Group data by categories (add-row-field) - Column fields: Create column headers (add-column-field) - Value fields: Aggregate numeric data with Sum, Count, Average, etc. (add-value-field) - Filter fields: Add report-level filters (add-filter-field) AGGREGATION FUNCTIONS: Sum, Count, Average, Max, Min, Product, CountNumbers, StdDev, StdDevP, Var, VarP GROUPING: - Date fields: Group by Days, Months, Quarters, Years (group-by-date) - Numeric fields: Group by ranges with start/end/interval (group-by-numeric) NUMBER FORMAT: Use US format codes like '#,##0.00' for currency or '0.00%' for percentages.
Actions: list-fields, add-row-field, add-column-field, add-value-field, add-filter-field, remove-field, set-field-function, set-field-name, set-field-format, set-field-filter, sort-field, group-by-date, group-by-numeric
| Parameter |
Description |
--pivot-table-name |
Name of the PivotTable (required) |
--field-name |
Name of the field to add (required for: add-row-field, add-column-field, add-value-field, add-filter-field, remove-field, set-field-function, set-field-name, set-field-format, set-field-filter, sort-field, group-by-date, group-by-numeric) |
--position |
Optional position in row area (1-based) |
--aggregation-function |
Aggregation function (for Regular and OLAP auto-create mode) (required for: set-field-function) |
--custom-name |
Optional custom name for the field/measure (required for: set-field-name) |
--number-format |
Number format string (required for: set-field-format) |
--selected-values |
Values to show (others will be hidden) (required for: set-field-filter) |
--direction |
Sort direction |
--interval |
Grouping interval (Months, Quarters, Years) (required for: group-by-date) |
--start |
Starting value (null = use field minimum) |
--end-value |
Ending value (null = use field maximum) |
--interval-size |
Size of each group (e.g., 100 for groups of 100) (required for: group-by-numeric) |
powerquery
Power Query M code and data loading. TEST-FIRST DEVELOPMENT WORKFLOW (BEST PRACTICE): 1. evaluate - Test M code WITHOUT persisting (catches syntax errors, validates sources, shows data preview) 2. create/update - Store VALIDATED query in workbook 3. refresh/load-to - Load data to destination Skip evaluate only for trivial literal tables. IF CREATE/UPDATE FAILS: Use evaluate to get the actual M engine error message, fix code, retry. DATETIME COLUMNS: Always include Table.TransformColumnTypes() in M code to set column types explicitly. Without explicit types, dates may be stored as numbers and Data Model relationships may fail. DESTINATIONS: 'worksheet' (default), 'data-model' (for DAX), 'both', 'connection-only'. Use 'data-model' to load to Power Pivot, then use datamodel to create DAX measures. TARGET CELL: targetCellAddress places tables without clearing sheet. TIMEOUT: 30 min auto-timeout for refresh and load-to. For quick queries, use timeout=60 or similar. timeout=0 or omitted uses the 30 min default.
Actions: list, view, refresh, get-load-config, delete, create, update, load-to, refresh-all, rename, unload, evaluate
| Parameter |
Description |
--query-name |
Name of the query to view (required for: view, refresh, get-load-config, delete, create, update, load-to, unload) |
--timeout |
Maximum time to wait for refresh (required for: refresh) |
--m-code |
Raw M code (inline string) (required for: create, update, evaluate) |
--load-destination |
Load destination mode |
--target-sheet |
Target worksheet name (required for LoadToTable and LoadToBoth; defaults to query name when omitted) |
--target-cell-address |
Optional target cell address for worksheet loads (e.g., "B5"). Required when loading to an existing worksheet with other data. |
--refresh |
Whether to refresh data after update (default: true) |
--old-name |
Current name of the query (required for: rename) |
--new-name |
New name for the query (required for: rename) |
range
Core range operations: get/set values and formulas, copy ranges, clear content, and discover data regions. Use rangeedit for insert/delete/find/sort. Use rangeformat for styling/validation. Use rangelink for hyperlinks and cell protection. Calculation mode and explicit recalculation are handled by calculationmode. BEST PRACTICE: Use 'get-values' to check existing data before overwriting. Use 'clear-contents' (not 'clear-all') to preserve cell formatting when clearing data. set-values preserves existing formatting; use set-number-format after if format change needed. DATA FORMAT: values and formulas are 2D JSON arrays representing rows and columns. Example: [[row1col1, row1col2], [row2col1, row2col2]] Single cell returns [[value]] (always 2D). REQUIRED PARAMETERS: - sheetName + rangeAddress for cell operations (e.g., sheetName='Sheet1', rangeAddress='A1:D10') - For named ranges, use sheetName='' (empty string) and rangeAddress='MyNamedRange' COPY OPERATIONS: Specify source and target sheet/range for copy operations. NUMBER FORMATS: Use US locale format codes (e.g., '#,##0.00', 'mm/dd/yyyy', '0.00%').
Actions: get-values, set-values, get-formulas, set-formulas, validate-formulas, clear-all, clear-contents, clear-formats, copy, copy-values, copy-formulas, get-number-formats, set-number-format, set-number-formats, get-used-range, get-current-region, get-info
| Parameter |
Description |
--sheet-name |
Name of the worksheet containing the range - REQUIRED for cell addresses, use empty string for named ranges only (required for: get-values, set-values, get-formulas, set-formulas, validate-formulas, clear-all, clear-contents, clear-formats, get-number-formats, set-number-format, set-number-formats, get-used-range, get-current-region, get-info) |
--range-address |
Cell range address (e.g., 'A1', 'A1:D10', 'B:D') or named range name (e.g., 'SalesData') (required for: get-values, set-values, get-formulas, set-formulas, validate-formulas, clear-all, clear-contents, clear-formats, get-number-formats, set-number-format, set-number-formats, get-info) |
--values |
2D array of values to set - rows are outer array, columns are inner array (e.g., [[1,2,3],[4,5,6]] for 2 rows x 3 cols). Optional if valuesFile is provided. |
--values-file |
Path to a JSON or CSV file containing the values. JSON: 2D array. CSV: rows/columns. Alternative to inline values parameter. |
--formulas |
2D array of formulas to set - include '=' prefix (e.g., [['=A1+B1', '=SUM(A:A)'], ['=C1*2', '=AVERAGE(B:B)']]). Optional if formulasFile is provided. |
--formulas-file |
Path to a JSON file containing the formulas as a 2D array. Alternative to inline formulas parameter. |
--source-sheet |
Source worksheet name for copy operations (required for: copy, copy-values, copy-formulas) |
--source-range |
Source range address for copy operations (e.g., 'A1:D10') (required for: copy, copy-values, copy-formulas) |
--target-sheet |
Target worksheet name for copy operations (required for: copy, copy-values, copy-formulas) |
--target-range |
Target range address - can be single cell for paste destination (e.g., 'A1') (required for: copy, copy-values, copy-formulas) |
--format-code |
Number format code in US locale (e.g., '#,##0.00' for numbers, 'mm/dd/yyyy' for dates, '0.00%' for percentages, 'General' for default, '@' for text) (required for: set-number-format) |
--formats |
2D array of format codes - same dimensions as target range (e.g., [['#,##0.00', '0.00%'], ['mm/dd/yyyy', 'General']]). Optional if formatsFile is provided. |
--formats-file |
Path to a JSON file containing 2D array of format codes. Alternative to inline formats parameter. |
--cell-address |
Single cell address (e.g., 'B5') - expands to contiguous data region around this cell (required for: get-current-region) |
rangeedit
Range editing operations: insert/delete cells, rows, and columns; find/replace text; sort data. Use range for values/formulas/copy/clear operations. INSERT/DELETE CELLS: Specify shift direction to control how surrounding cells move. - Insert: 'Down' or 'Right' - Delete: 'Up' or 'Left' INSERT/DELETE ROWS: Use row range like '5:10' to insert/delete rows 5-10. INSERT/DELETE COLUMNS: Use column range like 'B:D' to insert/delete columns B-D. FIND/REPLACE: Search within the specified range with optional case/cell matching. - Find returns up to 10 matching cell addresses with total count. - Replace modifies all matches by default. SORT: Specify sortColumns as array of {columnIndex: 1, ascending: true} objects. Column indices are 1-based relative to the range.
Actions: insert-cells, delete-cells, insert-rows, delete-rows, insert-columns, delete-columns, find, replace, sort
| Parameter |
Description |
--sheet-name |
Name of the worksheet containing the range (required) |
--range-address |
Cell range address where cells will be inserted (e.g., 'A1:D10') (required) |
--insert-shift |
Direction to shift existing cells: 'Down' or 'Right' (required for: insert-cells) |
--delete-shift |
Direction to shift remaining cells: 'Up' or 'Left' (required for: delete-cells) |
--search-value |
Text or value to search for (required for: find) |
--find-options |
Search options: matchCase (default: false), matchEntireCell (default: false), searchFormulas (default: true) (required for: find) |
--find-value |
Text or value to search for (required for: replace) |
--replace-value |
Text or value to replace matches with (required for: replace) |
--replace-options |
Replace options: matchCase (default: false), matchEntireCell (default: false), replaceAll (default: true) (required for: replace) |
--sort-columns |
Array of sort specifications: [{columnIndex: 1, ascending: true}, ...] - columnIndex is 1-based relative to range (required for: sort) |
--has-headers |
Whether the range has a header row to exclude from sorting (default: true) |
rangeformat
Range formatting operations: apply styles, set fonts/colors/borders, add data validation, merge cells, auto-fit dimensions. Use range tool for values/formulas/copy/clear operations. set-style: Apply a named Excel style (Heading 1, Good, Bad, Neutral, Normal). Best for semantic status labels (Good/Bad/Neutral have fill colours and are theme-aware) and document hierarchy (Heading 1/2/3). NOTE: Heading styles do NOT apply a fill colour — use format-range when you need a coloured header row. format-range: Apply any combination of bold, fillColor, fontColor, alignment, borders. Required whenever you need a fill colour or custom branding. Pass ALL desired properties in a SINGLE call — do not call format-range multiple times for the same range. format-ranges: Apply one shared formatting payload to multiple ranges on the same worksheet. Prefer this over repeated format-range calls when the same styling applies to multiple non-contiguous targets. All target ranges are validated before formatting begins. If any target range is invalid, nothing is formatted. COLORS: Hex '#RRGGBB' (e.g., '#FF0000' for red, '#00FF00' for green) FONT: size in points (e.g., 12, 14, 16), alignment: 'left', 'center', 'right' / 'top', 'middle', 'bottom' DATA VALIDATION: Restrict cell input with validation rules: - Types: 'list', 'whole', 'decimal', 'date', 'time', 'textLength', 'custom' - For list validation, formula1 is the list source (e.g., '=$A$1:$A$10' or '"Option1,Option2,Option3"') - Operators: 'between', 'notBetween', 'equal', 'notEqual', 'greaterThan', 'lessThan', 'greaterThanOrEqual', 'lessThanOrEqual' MERGE: Combines cells into one. Only top-left cell value is preserved.
Actions: set-style, get-style, format-range, format-ranges, validate-range, get-validation, remove-validation, auto-fit-columns, auto-fit-rows, merge-cells, unmerge-cells, get-merge-info, set-column-width, set-row-height
| Parameter |
Description |
--sheet-name |
Name of the worksheet containing the range (required) |
--range-address |
Cell range address (e.g., 'A1:D10') (required for: set-style, get-style, format-range, validate-range, get-validation, remove-validation, auto-fit-columns, auto-fit-rows, merge-cells, unmerge-cells, get-merge-info, set-column-width, set-row-height) |
--style-name |
Built-in or custom style name (e.g., 'Heading 1', 'Good', 'Bad', 'Currency', 'Percent'). Use 'Normal' to reset. (required for: set-style) |
--font-name |
Font family name (e.g., 'Arial', 'Calibri', 'Times New Roman') |
--font-size |
Font size in points (e.g., 10, 11, 12, 14, 16) |
--bold |
Whether to apply bold formatting |
--italic |
Whether to apply italic formatting |
--underline |
Whether to apply underline formatting |
--font-color |
Font (foreground) color as hex '#RRGGBB' (e.g., '#FF0000' for red) |
--fill-color |
Cell fill (background) color as hex '#RRGGBB' (e.g., '#FFFF00' for yellow) |
--border-style |
Border line style: 'continuous', 'dash', 'dot', 'dashdot', 'dashdotdot', 'double', 'slantdashdot', 'none' |
--border-color |
Border color as hex '#RRGGBB' |
--border-weight |
Border weight: 'hairline', 'thin', 'medium', 'thick' |
--horizontal-alignment |
Horizontal text alignment: 'left', 'center', 'right', 'justify', 'fill' |
--vertical-alignment |
Vertical text alignment: 't |
…(truncated)
1---2name: sbroenne-mcp-server-excel-excel-cli3description: Excel Automation with excelcli4---56# Excel Automation with excelcli78## Preconditions910- Windows host with Microsoft Excel installed (2016+)11- Uses COM interop — does NOT work on macOS or Linux12- Install: Download `excelcli.exe` from https://github.com/sbroenne/mcp-server-excel/releases/latest and add to PATH1314## Workflow Checklist1516| Step | Command | When |17|------|---------|------|18| 1. Session | `session create/open` | Always first |19| 2. Sheets | `worksheet create/rename` | If needed |20| 3. Write data | See below | If writing values |21| 4. Save & close | `session close --save` | Always last |2223> **10+ commands?** Use `excelcli -q batch --input commands.json` — sends all commands in one process with automatic session management. See Rule 8.2425**Writing Data (Step 3):**26- `--values` takes a JSON 2D array string: `--values '[["Header1","Header2"],[1,2]]'`27- Write **one row at a time** for reliability: `--range-address A1:B1 --values '[["Name","Age"]]'`28- Strings MUST be double-quoted in JSON: `"text"`. Numbers are bare: `42`29- Always wrap the entire JSON value in single quotes to protect special characters3031## CRITICAL RULES (MUST FOLLOW)3233> **⚡ Building dashboards or bulk operations?** Skip to **Rule 8: Batch Mode** — it eliminates per-command process overhead and auto-manages session IDs.3435### Rule 1: NEVER Ask Clarifying Questions3637Execute commands to discover the answer instead:3839| DON'T ASK | DO THIS INSTEAD |40|-----------|-----------------|41| "Which file should I use?" | `excelcli -q session list` |42| "What table should I use?" | `excelcli -q table list --session <id>` |43| "Which sheet has the data?" | `excelcli -q worksheet list --session <id>` |4445**You have commands to answer your own questions. USE THEM.**4647### Rule 2: Always End With a Text Summary4849**NEVER end your turn with only a command execution.** After completing all operations, always provide a brief text message confirming what was done. Silent command-only responses are incomplete.5051### Rule 3: Session Lifecycle5253**Creating vs Opening Files:**54```powershell55# NEW file - use session create56excelcli -q session create C:\path\newfile.xlsx # Creates file + returns session ID5758# EXISTING file - use session open59excelcli -q session open C:\path\existing.xlsx # Opens file + returns session ID60```6162**CRITICAL: Use `session create` for new files. `session open` on non-existent files will fail!**6364**CRITICAL: ALWAYS use the session ID returned by `session create` or `session open` in subsequent commands. NEVER guess or hardcode session IDs. The session ID is in the JSON output (e.g., `{"sessionId":"abc123"}`). Parse it and use it.**6566```powershell67# Example: capture session ID from output, then use it68excelcli -q session create C:\path\file.xlsx # Returns JSON with sessionId69excelcli -q range set-values --session <returned-session-id> ...70excelcli -q session close --session <returned-session-id> --save71```7273**Unclosed sessions leave Excel processes running, locking files.**7475### Rule 4: Data Model Prerequisites7677DAX operations require tables in the Data Model:7879```powershell80excelcli -q table add-to-data-model --session <id> --table-name Sales # Step 181excelcli -q datamodel create-measure --session <id> ... # Step 2 - NOW works82```8384### Rule 5: Power Query Development Lifecycle8586**BEST PRACTICE: Test M code before creating permanent queries**8788```powershell89# Step 1: Create/open a session and capture the session ID90$session = excelcli -q session create C:\path\file.xlsx | ConvertFrom-Json91$sessionId = $session.sessionId9293# Step 2: Test M code without persisting (catches errors early)94excelcli -q powerquery evaluate --session $sessionId --m-code-file query.m9596# Step 3: Create permanent query with validated code97excelcli -q powerquery create --session $sessionId --query-name Q1 --m-code-file query.m9899# Step 4: Load data to destination100excelcli -q powerquery refresh --session $sessionId --query-name Q1101102# Step 5: Close session103excelcli -q session close --session $sessionId --save104```105106### Rule 6: Report File Errors Immediately107108If you see "File not found" or "Path not found" - STOP and report to user. Don't retry.109110### Rule 7: Use Calculation Mode for Bulk Writes111112When writing many values/formulas (10+ cells), disable auto-recalc for performance:113114```powershell115# 1. Create/open a session and capture the session ID116$session = excelcli -q session create C:\path\file.xlsx | ConvertFrom-Json117$sessionId = $session.sessionId118119# 2. Set manual mode120excelcli -q calculationmode set-mode --session $sessionId --mode manual121122# 3. Write data row by row for reliability123excelcli -q range set-values --session $sessionId --sheet-name Sheet1 --range-address A1:B1 --values '[["Name","Amount"]]'124excelcli -q range set-values --session $sessionId --sheet-name Sheet1 --range-address A2:B2 --values '[["Salary",5000]]'125126# 4. Recalculate once at end127excelcli -q calculationmode calculate --session $sessionId --scope workbook128129# 5. Restore automatic mode130excelcli -q calculationmode set-mode --session $sessionId --mode automatic131132# 6. Close session133excelcli -q session close --session $sessionId --save134```135136### Rule 8: Use Batch Mode for Bulk Operations (10+ commands)137138When executing 10+ commands on the same file, use `excelcli batch` to send all commands in a single process launch. This avoids per-process startup overhead and terminal buffer saturation.139140```powershell141# Create a JSON file with all commands142@'143[144 {"command": "session.open", "args": {"filePath": "C:\\path\\file.xlsx"}},145 {"command": "range.set-values", "args": {"sheetName": "Sheet1", "rangeAddress": "A1", "values": [["Hello"]]}},146 {"command": "range.set-values", "args": {"sheetName": "Sheet1", "rangeAddress": "A2", "values": [["World"]]}},147 {"command": "session.close", "args": {"save": true}}148]149'@ | Set-Content commands.json150151# Execute all commands at once152excelcli -q batch --input commands.json153```154155**Key features:**156- **Session auto-capture**: `session.open`/`create` result sessionId auto-injected into subsequent commands — no need to parse and pass session IDs157- **NDJSON output**: One JSON result per line: `{"index": 0, "command": "...", "success": true, "result": {...}}`158- **`--stop-on-error`**: Exit on first failure (default: continue all)159- **`--session <id>`**: Pre-set session ID for all commands (skip session.open)160161**Input formats:**162- JSON array from file: `excelcli -q batch --input commands.json`163- NDJSON from stdin: `Get-Content commands.ndjson | excelcli -q batch`164165## CLI Command Reference166167> Auto-generated from `excelcli --help`. Use these exact parameter names.168169170### calculationmode171172Control Excel recalculation (automatic vs manual). Set manual mode before bulk writes for faster performance, then recalculate once at the end.173174**Actions:** `get-mode`, `set-mode`, `calculate`175176| Parameter | Description |177|-----------|-------------|178| `--mode` | Target calculation mode (required for: set-mode) |179| `--scope` | Scope: Workbook, Sheet, or Range (required for: calculate) |180| `--sheet-name` | Sheet name (required for Sheet/Range scope) |181| `--range-address` | Range address (required for Range scope) |182183184185### chart186187Chart lifecycle - create, read, move, and delete embedded charts. POSITIONING (choose one): - targetRange (PREFERRED): Cell range like 'F2:K15' — positions chart within cells, no point math needed. - left/top: Manual positioning in points (72 points = 1 inch). - Neither: Auto-positions chart below all existing content (used range + other charts). COLLISION DETECTION: All create/move/fit-to-range operations automatically check for overlaps with data and other charts. Warnings are returned in the result message if collisions are detected. Always verify layout with screenshot(capture-sheet) after creating charts. CHART TYPES: 70+ types available including Column, Line, Pie, Bar, Area, XY Scatter. CREATE OPTIONS: - create-from-range: Create from cell range (e.g., 'A1:D10') - create-from-table: Create from Excel Table (uses table's data range) - create-from-pivottable: Create linked PivotChart Use chartconfig for series, titles, legends, styles, placement mode.188189**Actions:** `list`, `read`, `create-from-range`, `create-from-table`, `create-from-pivottable`, `delete`, `move`, `fit-to-range`190191| Parameter | Description |192|-----------|-------------|193| `--chart-name` | Name of the chart (or shape name) (required for: read, delete, move, fit-to-range) |194| `--sheet-name` | Target worksheet name (required for: create-from-range, create-from-table, create-from-pivottable, fit-to-range) |195| `--source-range-address` | Data range for the chart (e.g., A1:D10) (required for: create-from-range) |196| `--chart-type` | Type of chart to create (required for: create-from-range, create-from-table, create-from-pivottable) |197| `--left` | Left position in points from worksheet edge |198| `--top` | Top position in points from worksheet edge |199| `--width` | Chart width in points |200| `--height` | Chart height in points |201| `--target-range` | Cell range to position chart within (e.g., 'F2:K15'). PREFERRED over left/top. When set, left/top are ignored. |202| `--table-name` | Name of the Excel Table (required for: create-from-table) |203| `--pivot-table-name` | Name of the source PivotTable (required for: create-from-pivottable) |204| `--range-address` | Range to fit the chart to (e.g., A1:D10) (required for: fit-to-range) |205206207208### chartconfig209210Chart configuration - data source, series, type, title, axis labels, legend, and styling. SERIES MANAGEMENT: - add-series: Add data series with valuesRange (required) and optional categoryRange - remove-series: Remove series by 1-based index - set-source-range: Replace entire chart data source TITLES AND LABELS: - set-title: Set chart title (empty string hides title) - set-axis-title: Set axis labels (Category, Value, CategorySecondary, ValueSecondary) CHART STYLES: 1-48 (built-in Excel styles with different color schemes) DATA LABELS: Show values, percentages, series/category names. Positions: Center, InsideEnd, InsideBase, OutsideEnd, BestFit. TRENDLINES: Linear, Exponential, Logarithmic, Polynomial (order 2-6), Power, MovingAverage. PLACEMENT MODE: - 1: Move and size with cells - 2: Move but don't size with cells - 3: Don't move or size with cells (free floating) Use chart for lifecycle operations (create, delete, move, fit-to-range).211212**Actions:** `set-source-range`, `add-series`, `remove-series`, `set-chart-type`, `set-title`, `set-axis-title`, `get-axis-number-format`, `set-axis-number-format`, `show-legend`, `set-style`, `set-placement`, `set-data-labels`, `get-axis-scale`, `set-axis-scale`, `get-gridlines`, `set-gridlines`, `set-series-format`, `list-trendlines`, `add-trendline`, `delete-trendline`, `set-trendline`213214| Parameter | Description |215|-----------|-------------|216| `--chart-name` | Name of the chart (required) |217| `--source-range` | New data source range (e.g., Sheet1!A1:D10) (required for: set-source-range) |218| `--series-name` | Display name for the series (required for: add-series) |219| `--values-range` | Range containing series values (e.g., B2:B10) (required for: add-series) |220| `--category-range` | Optional range for category labels (e.g., A2:A10) |221| `--series-index` | 1-based index of the series to remove (required for: remove-series, set-series-format, list-trendlines, add-trendline, delete-trendline, set-trendline) |222| `--chart-type` | New chart type to apply (required for: set-chart-type) |223| `--title` | Title text to display (required for: set-title, set-axis-title) |224| `--axis` | Which axis to set title for (Category, Value, SeriesAxis) (required for: set-axis-title, get-axis-number-format, set-axis-number-format, get-axis-scale, set-axis-scale, set-gridlines) |225| `--number-format` | Excel number format code (e.g., "$#,##0", "0.00%") (required for: set-axis-number-format) |226| `--visible` | True to show legend, false to hide (required for: show-legend) |227| `--legend-position` | Optional position for the legend |228| `--style-id` | Excel chart style ID (1-48 for most chart types) (required for: set-style) |229| `--placement` | Placement mode: 1=MoveAndSize, 2=Move, 3=FreeFloating (required for: set-placement) |230| `--show-value` | Show data values on labels |231| `--show-percentage` | Show percentage values. Only meaningful for pie and doughnut chart types; setting to true on other chart types has no visual effect. |232| `--show-series-name` | Show series name on labels |233| `--show-category-name` | Show category name on labels |234| `--show-bubble-size` | Show bubble size (bubble charts) |235| `--separator` | Separator string between label components |236| `--label-position` | Position of data labels relative to data points |237| `--minimum-scale` | Minimum axis value (null for auto) |238| `--maximum-scale` | Maximum axis value (null for auto) |239| `--major-unit` | Major gridline interval (null for auto) |240| `--minor-unit` | Minor gridline interval (null for auto) |241| `--show-major` | Show major gridlines (null to keep current) |242| `--show-minor` | Show minor gridlines (null to keep current) |243| `--marker-style` | Marker shape style |244| `--marker-size` | Marker size in points (2-72) |245| `--marker-background-color` | Marker fill color (#RRGGBB) |246| `--marker-foreground-color` | Marker border color (#RRGGBB) |247| `--invert-if-negative` | Invert colors for negative values |248| `--trendline-type` | Type of trendline (Linear, Exponential, etc.) (required for: add-trendline) |249| `--order` | Polynomial order (2-6, for Polynomial type) |250| `--period` | Moving average period (for MovingAverage type) |251| `--forward` | Periods to extend forward |252| `--backward` | Periods to extend backward |253| `--intercept` | Force trendline through specific Y-intercept |254| `--display-equation` | Display trendline equation on chart |255| `--display-r-squared` | Display R-squared value on chart |256| `--name` | Custom name for the trendline |257| `--trendline-index` | 1-based index of the trendline to delete (required for: delete-trendline, set-trendline) |258259260261### conditionalformat262263Conditional formatting - visual rules based on cell values. TYPES: cellValue (requires operatorType+formula1), expression (formula only). Both camelCase and kebab-case accepted. FORMAT: interiorColor/fontColor as #RRGGBB, fontBold/Italic, borderStyle/Color. OPERATORS: equal, notEqual, greater, less, greaterEqual, lessEqual, between, notBetween. For 'between' and 'notBetween', both formula1 and formula2 are required.264265**Actions:** `add-rule`, `clear-rules`266267| Parameter | Description |268|-----------|-------------|269| `--sheet-name` | Sheet name (empty for active sheet) |270| `--range-address` | Range address (A1 notation or named range) |271| `--rule-type` | Rule type: cellValue (or cell-value), expression, colorScale, dataBar, top10, iconSet, uniqueValues, blanksCondition, timePeriod, aboveAverage. Both camelCase and kebab-case accepted. |272| `--operator-type` | XlFormatConditionOperator: equal, notEqual, greater, less, greaterEqual, lessEqual, between, notBetween |273| `--formula1` | First formula/value for condition |274| `--formula2` | Second formula/value (for between/notBetween) |275| `--interior-color` | Fill color (#RRGGBB or color index) |276| `--interior-pattern` | Interior pattern (1=Solid, -4142=None, 9=Gray50, etc.) |277| `--font-color` | Font color (#RRGGBB or color index) |278| `--font-bold` | Bold font |279| `--font-italic` | Italic font |280| `--border-style` | Border style: none, continuous, dash, dot, etc. |281| `--border-color` | Border color (#RRGGBB or color index) |282283284285### connection286287Data connections (OLEDB, ODBC, ODC import). TEXT/WEB/CSV: Use powerquery instead. Power Query connections auto-redirect to powerquery. TIMEOUT: 30 min auto-timeout for refresh/load-to.288289**Actions:** `list`, `view`, `create`, `refresh`, `delete`, `load-to`, `get-properties`, `set-properties`, `test`290291| Parameter | Description |292|-----------|-------------|293| `--connection-name` | Name of the connection to view |294| `--connection-string` | OLEDB or ODBC connection string |295| `--command-text` | SQL query or table name |296| `--description` | Optional description for the connection |297| `--timeout` | Optional timeout for the refresh operation |298| `--sheet-name` | Target worksheet name |299| `--connection-string` | New connection string (null to keep current) |300| `--command-text` | New SQL query or table name (null to keep current) |301| `--background-query` | Run query in background (null to keep current) |302| `--refresh-on-file-open` | Refresh when file opens (null to keep current) |303| `--save-password` | Save password in connection (null to keep current) |304| `--refresh-period` | Auto-refresh interval in minutes (null to keep current) |305306307308### datamodel309310Data Model (Power Pivot) - DAX measures and table management. CRITICAL: WORKSHEET TABLES AND DATA MODEL ARE SEPARATE! - After table append changes, Data Model still has OLD data - MUST call refresh to sync changes - Power Query refresh auto-syncs (no manual refresh needed) PREREQUISITE: Tables must be added to the Data Model first. Use table add-to-datamodel for worksheet tables, or powerquery to import and load data directly to the Data Model. DAX MEASURES: - Create with DAX formulas like 'SUM(Sales[Amount])' - DAX formulas are auto-formatted on CREATE/UPDATE via Dax.Formatter (SQLBI) - Read operations return raw DAX as stored DAX EVALUATE QUERIES: - Use evaluate to execute DAX EVALUATE queries against the Data Model - Returns tabular results from queries like 'EVALUATE TableName' - Supports complex DAX: SUMMARIZE, FILTER, CALCULATETABLE, TOPN, etc. DMV (DYNAMIC MANAGEMENT VIEW) QUERIES: - Use execute-dmv to query Data Model metadata via SQL-like syntax - Syntax: SELECT * FROM $SYSTEM.SchemaRowset (ONLY SELECT * supported) - Use DISCOVER_SCHEMA_ROWSETS to list all available DMVs Use datamodelrel for relationships between tables.311312**Actions:** `list-tables`, `list-columns`, `read-table`, `read-info`, `list-measures`, `read`, `delete-measure`, `delete-table`, `rename-table`, `refresh`, `create-measure`, `update-measure`, `evaluate`, `execute-dmv`313314| Parameter | Description |315|-----------|-------------|316| `--table-name` | Name of the table to list columns from (required for: list-columns, read-table, delete-table, create-measure) |317| `--measure-name` | Name of the measure to get (required for: read, delete-measure, create-measure, update-measure) |318| `--old-name` | Current name of the table (required for: rename-table) |319| `--new-name` | New name for the table (required for: rename-table) |320| `--timeout` | Optional: Timeout for the refresh operation |321| `--dax-formula` | DAX formula for the measure (will be auto-formatted) (required for: create-measure) |322| `--format-type` | Optional: Format type (Currency, Decimal, Percentage, General) |323| `--description` | Optional: Description of the measure |324| `--dax-query` | DAX EVALUATE query (e.g., "EVALUATE 'TableName'" or "EVALUATE SUMMARIZE(...)") (required for: evaluate) |325| `--dmv-query` | DMV query in SQL-like syntax (e.g., "SELECT * FROM $SYSTEM.TMSCHEMA_TABLES") (required for: execute-dmv) |326327328329### datamodelrelationship330331Data Model relationships - link tables for cross-table DAX calculations. CRITICAL: Deleting or recreating tables removes ALL their relationships. Use list-relationships before table operations to backup, then recreate relationships after schema changes. RELATIONSHIP REQUIREMENTS: - Both tables must exist in the Data Model first - Columns must have compatible data types - fromTable/fromColumn = many-side (detail table, foreign key) - toTable/toColumn = one-side (lookup table, primary key) ACTIVE VS INACTIVE: - Only ONE active relationship can exist between two tables - Use active=false when creating alternative paths - DAX USERELATIONSHIP() activates inactive relationships332333**Actions:** `list-relationships`, `read-relationship`, `create-relationship`, `update-relationship`, `delete-relationship`334335| Parameter | Description |336|-----------|-------------|337| `--from-table` | Source table name (required for: read-relationship, create-relationship, update-relationship, delete-relationship) |338| `--from-column` | Source column name (required for: read-relationship, create-relationship, update-relationship, delete-relationship) |339| `--to-table` | Target table name (required for: read-relationship, create-relationship, update-relationship, delete-relationship) |340| `--to-column` | Target column name (required for: read-relationship, create-relationship, update-relationship, delete-relationship) |341| `--active` | Whether the relationship should be active (default: true) (required for: update-relationship) |342343344345### diag346347Diagnostic commands for testing CLI/MCP infrastructure without Excel. These commands validate parameter parsing, routing, JSON serialization, and error handling — no Excel COM session needed.348349**Actions:** `ping`, `echo`, `validate-params`350351| Parameter | Description |352|-----------|-------------|353| `--message` | The message to echo back (required) (required for: echo) |354| `--tag` | Optional tag to include in the response |355| `--name` | Required name parameter (required for: validate-params) |356| `--count` | Required integer parameter (required for: validate-params) |357| `--label` | Optional label parameter |358| `--verbose` | Optional boolean flag (default: false) |359360361362### namedrange363364Named ranges for formulas/parameters. CREATE/UPDATE: value is cell reference (e.g., 'Sheet1!$A$1'). WRITE: value is data to store. TIP: range(rangeAddress=namedRangeName) for bulk data read/write.365366**Actions:** `list`, `write`, `read`, `update`, `create`, `delete`367368| Parameter | Description |369|-----------|-------------|370| `--name` | Name of the named range (required for: write, read, update, create, delete) |371| `--value` | Value to set (required for: write) |372| `--reference` | New cell reference (e.g., Sheet1!$A$1:$B$10) (required for: update, create) |373374375376### pivottable377378PivotTable lifecycle management: create from various sources, list, read details, refresh, and delete. Use pivottablefield for field operations, pivottablecalc for calculated fields and layout. BEST PRACTICE: Use 'list' before creating. Prefer 'refresh' or field modifications over delete+recreate. Delete+recreate loses field configurations, filters, sorting, and custom layouts. REFRESH: Call 'refresh' after configuring fields with pivottablefield to update the visual display. This is especially important for OLAP/Data Model PivotTables where field operations are structural only and don't automatically trigger a visual refresh. CREATE OPTIONS: - 'create-from-range': Use source sheet and range address for data range - 'create-from-table': Use an Excel Table (ListObject) as source - 'create-from-datamodel': Use a Power Pivot Data Model table as source379380**Actions:** `list`, `read`, `create-from-range`, `create-from-table`, `create-from-datamodel`, `delete`, `refresh`381382| Parameter | Description |383|-----------|-------------|384| `--pivot-table-name` | Name of the PivotTable (required for: read, create-from-range, create-from-table, create-from-datamodel, delete, refresh) |385| `--source-sheet` | Source worksheet name (required for: create-from-range) |386| `--source-range` | Source range address (e.g., "A1:F100") (required for: create-from-range) |387| `--destination-sheet` | Destination worksheet name (required for: create-from-range, create-from-table, create-from-datamodel) |388| `--destination-cell` | Destination cell address (e.g., "A1") (required for: create-from-range, create-from-table, create-from-datamodel) |389| `--table-name` | Name of the Excel Table (required for: create-from-table, create-from-datamodel) |390| `--timeout` | Optional timeout for the refresh operation |391392393394### pivottablecalc395396PivotTable calculated fields/members, layout configuration, and data extraction. Use pivottable for lifecycle, pivottablefield for field placement. CALCULATED FIELDS (for regular PivotTables): - Create custom fields using formulas like '=Revenue-Cost' or '=Quantity*UnitPrice' - Can reference existing fields by name - After creating, use pivottablefield add-value-field to add to Values area - For complex multi-table calculations, prefer DAX measures with datamodel CALCULATED MEMBERS (for OLAP/Data Model PivotTables only): - Create using MDX expressions - Member types: Member, Set, Measure LAYOUT OPTIONS: - 0 = Compact (default, fields in single column) - 1 = Tabular (each field in separate column - best for export/analysis) - 2 = Outline (hierarchical with expand/collapse)397398**Actions:** `get-data`, `create-calculated-field`, `list-calculated-fields`, `delete-calculated-field`, `list-calculated-members`, `create-calculated-member`, `delete-calculated-member`, `set-layout`, `set-subtotals`, `set-grand-totals`399400| Parameter | Description |401|-----------|-------------|402| `--pivot-table-name` | Name of the PivotTable (required) |403| `--field-name` | Name for the calculated field (required for: create-calculated-field, delete-calculated-field, set-subtotals) |404| `--formula` | Formula using field references (e.g., "=Revenue-Cost") (required for: create-calculated-field, create-calculated-member) |405| `--member-name` | Name for the calculated member (MDX naming format) (required for: create-calculated-member, delete-calculated-member) |406| `--type` | Type of calculated member (Member, Set, or Measure) |407| `--solve-order` | Solve order for calculation precedence (default: 0) |408| `--display-folder` | Display folder path for organizing measures (optional) |409| `--number-format` | Number format code for the calculated member (optional) |410| `--row-layout` | Layout form: 0=Compact, 1=Tabular, 2=Outline (required for: set-layout) |411| `--show-subtotals` | True to show automatic subtotals, false to hide (required for: set-subtotals) |412| `--show-row-grand-totals` | Show row grand totals (bottom summary row) (required for: set-grand-totals) |413| `--show-column-grand-totals` | Show column grand totals (right summary column) (required for: set-grand-totals) |414415416417### pivottablefield418419PivotTable field management: add/remove/configure fields, filtering, sorting, and grouping. Use pivottable for lifecycle, pivottablecalc for calculated fields and layout. IMPORTANT: Field operations modify structure only. Call pivottable refresh after configuring fields to update the visual display, especially for OLAP/Data Model PivotTables. FIELD AREAS: - Row fields: Group data by categories (add-row-field) - Column fields: Create column headers (add-column-field) - Value fields: Aggregate numeric data with Sum, Count, Average, etc. (add-value-field) - Filter fields: Add report-level filters (add-filter-field) AGGREGATION FUNCTIONS: Sum, Count, Average, Max, Min, Product, CountNumbers, StdDev, StdDevP, Var, VarP GROUPING: - Date fields: Group by Days, Months, Quarters, Years (group-by-date) - Numeric fields: Group by ranges with start/end/interval (group-by-numeric) NUMBER FORMAT: Use US format codes like '#,##0.00' for currency or '0.00%' for percentages.420421**Actions:** `list-fields`, `add-row-field`, `add-column-field`, `add-value-field`, `add-filter-field`, `remove-field`, `set-field-function`, `set-field-name`, `set-field-format`, `set-field-filter`, `sort-field`, `group-by-date`, `group-by-numeric`422423| Parameter | Description |424|-----------|-------------|425| `--pivot-table-name` | Name of the PivotTable (required) |426| `--field-name` | Name of the field to add (required for: add-row-field, add-column-field, add-value-field, add-filter-field, remove-field, set-field-function, set-field-name, set-field-format, set-field-filter, sort-field, group-by-date, group-by-numeric) |427| `--position` | Optional position in row area (1-based) |428| `--aggregation-function` | Aggregation function (for Regular and OLAP auto-create mode) (required for: set-field-function) |429| `--custom-name` | Optional custom name for the field/measure (required for: set-field-name) |430| `--number-format` | Number format string (required for: set-field-format) |431| `--selected-values` | Values to show (others will be hidden) (required for: set-field-filter) |432| `--direction` | Sort direction |433| `--interval` | Grouping interval (Months, Quarters, Years) (required for: group-by-date) |434| `--start` | Starting value (null = use field minimum) |435| `--end-value` | Ending value (null = use field maximum) |436| `--interval-size` | Size of each group (e.g., 100 for groups of 100) (required for: group-by-numeric) |437438439440### powerquery441442Power Query M code and data loading. TEST-FIRST DEVELOPMENT WORKFLOW (BEST PRACTICE): 1. evaluate - Test M code WITHOUT persisting (catches syntax errors, validates sources, shows data preview) 2. create/update - Store VALIDATED query in workbook 3. refresh/load-to - Load data to destination Skip evaluate only for trivial literal tables. IF CREATE/UPDATE FAILS: Use evaluate to get the actual M engine error message, fix code, retry. DATETIME COLUMNS: Always include Table.TransformColumnTypes() in M code to set column types explicitly. Without explicit types, dates may be stored as numbers and Data Model relationships may fail. DESTINATIONS: 'worksheet' (default), 'data-model' (for DAX), 'both', 'connection-only'. Use 'data-model' to load to Power Pivot, then use datamodel to create DAX measures. TARGET CELL: targetCellAddress places tables without clearing sheet. TIMEOUT: 30 min auto-timeout for refresh and load-to. For quick queries, use timeout=60 or similar. timeout=0 or omitted uses the 30 min default.443444**Actions:** `list`, `view`, `refresh`, `get-load-config`, `delete`, `create`, `update`, `load-to`, `refresh-all`, `rename`, `unload`, `evaluate`445446| Parameter | Description |447|-----------|-------------|448| `--query-name` | Name of the query to view (required for: view, refresh, get-load-config, delete, create, update, load-to, unload) |449| `--timeout` | Maximum time to wait for refresh (required for: refresh) |450| `--m-code` | Raw M code (inline string) (required for: create, update, evaluate) |451| `--load-destination` | Load destination mode |452| `--target-sheet` | Target worksheet name (required for LoadToTable and LoadToBoth; defaults to query name when omitted) |453| `--target-cell-address` | Optional target cell address for worksheet loads (e.g., "B5"). Required when loading to an existing worksheet with other data. |454| `--refresh` | Whether to refresh data after update (default: true) |455| `--old-name` | Current name of the query (required for: rename) |456| `--new-name` | New name for the query (required for: rename) |457458459460### range461462Core range operations: get/set values and formulas, copy ranges, clear content, and discover data regions. Use rangeedit for insert/delete/find/sort. Use rangeformat for styling/validation. Use rangelink for hyperlinks and cell protection. Calculation mode and explicit recalculation are handled by calculationmode. BEST PRACTICE: Use 'get-values' to check existing data before overwriting. Use 'clear-contents' (not 'clear-all') to preserve cell formatting when clearing data. set-values preserves existing formatting; use set-number-format after if format change needed. DATA FORMAT: values and formulas are 2D JSON arrays representing rows and columns. Example: [[row1col1, row1col2], [row2col1, row2col2]] Single cell returns [[value]] (always 2D). REQUIRED PARAMETERS: - sheetName + rangeAddress for cell operations (e.g., sheetName='Sheet1', rangeAddress='A1:D10') - For named ranges, use sheetName='' (empty string) and rangeAddress='MyNamedRange' COPY OPERATIONS: Specify source and target sheet/range for copy operations. NUMBER FORMATS: Use US locale format codes (e.g., '#,##0.00', 'mm/dd/yyyy', '0.00%').463464**Actions:** `get-values`, `set-values`, `get-formulas`, `set-formulas`, `validate-formulas`, `clear-all`, `clear-contents`, `clear-formats`, `copy`, `copy-values`, `copy-formulas`, `get-number-formats`, `set-number-format`, `set-number-formats`, `get-used-range`, `get-current-region`, `get-info`465466| Parameter | Description |467|-----------|-------------|468| `--sheet-name` | Name of the worksheet containing the range - REQUIRED for cell addresses, use empty string for named ranges only (required for: get-values, set-values, get-formulas, set-formulas, validate-formulas, clear-all, clear-contents, clear-formats, get-number-formats, set-number-format, set-number-formats, get-used-range, get-current-region, get-info) |469| `--range-address` | Cell range address (e.g., 'A1', 'A1:D10', 'B:D') or named range name (e.g., 'SalesData') (required for: get-values, set-values, get-formulas, set-formulas, validate-formulas, clear-all, clear-contents, clear-formats, get-number-formats, set-number-format, set-number-formats, get-info) |470| `--values` | 2D array of values to set - rows are outer array, columns are inner array (e.g., [[1,2,3],[4,5,6]] for 2 rows x 3 cols). Optional if valuesFile is provided. |471| `--values-file` | Path to a JSON or CSV file containing the values. JSON: 2D array. CSV: rows/columns. Alternative to inline values parameter. |472| `--formulas` | 2D array of formulas to set - include '=' prefix (e.g., [['=A1+B1', '=SUM(A:A)'], ['=C1*2', '=AVERAGE(B:B)']]). Optional if formulasFile is provided. |473| `--formulas-file` | Path to a JSON file containing the formulas as a 2D array. Alternative to inline formulas parameter. |474| `--source-sheet` | Source worksheet name for copy operations (required for: copy, copy-values, copy-formulas) |475| `--source-range` | Source range address for copy operations (e.g., 'A1:D10') (required for: copy, copy-values, copy-formulas) |476| `--target-sheet` | Target worksheet name for copy operations (required for: copy, copy-values, copy-formulas) |477| `--target-range` | Target range address - can be single cell for paste destination (e.g., 'A1') (required for: copy, copy-values, copy-formulas) |478| `--format-code` | Number format code in US locale (e.g., '#,##0.00' for numbers, 'mm/dd/yyyy' for dates, '0.00%' for percentages, 'General' for default, '@' for text) (required for: set-number-format) |479| `--formats` | 2D array of format codes - same dimensions as target range (e.g., [['#,##0.00', '0.00%'], ['mm/dd/yyyy', 'General']]). Optional if formatsFile is provided. |480| `--formats-file` | Path to a JSON file containing 2D array of format codes. Alternative to inline formats parameter. |481| `--cell-address` | Single cell address (e.g., 'B5') - expands to contiguous data region around this cell (required for: get-current-region) |482483484485### rangeedit486487Range editing operations: insert/delete cells, rows, and columns; find/replace text; sort data. Use range for values/formulas/copy/clear operations. INSERT/DELETE CELLS: Specify shift direction to control how surrounding cells move. - Insert: 'Down' or 'Right' - Delete: 'Up' or 'Left' INSERT/DELETE ROWS: Use row range like '5:10' to insert/delete rows 5-10. INSERT/DELETE COLUMNS: Use column range like 'B:D' to insert/delete columns B-D. FIND/REPLACE: Search within the specified range with optional case/cell matching. - Find returns up to 10 matching cell addresses with total count. - Replace modifies all matches by default. SORT: Specify sortColumns as array of {columnIndex: 1, ascending: true} objects. Column indices are 1-based relative to the range.488489**Actions:** `insert-cells`, `delete-cells`, `insert-rows`, `delete-rows`, `insert-columns`, `delete-columns`, `find`, `replace`, `sort`490491| Parameter | Description |492|-----------|-------------|493| `--sheet-name` | Name of the worksheet containing the range (required) |494| `--range-address` | Cell range address where cells will be inserted (e.g., 'A1:D10') (required) |495| `--insert-shift` | Direction to shift existing cells: 'Down' or 'Right' (required for: insert-cells) |496| `--delete-shift` | Direction to shift remaining cells: 'Up' or 'Left' (required for: delete-cells) |497| `--search-value` | Text or value to search for (required for: find) |498| `--find-options` | Search options: matchCase (default: false), matchEntireCell (default: false), searchFormulas (default: true) (required for: find) |499| `--find-value` | Text or value to search for (required for: replace) |500| `--replace-value` | Text or value to replace matches with (required for: replace) |501| `--replace-options` | Replace options: matchCase (default: false), matchEntireCell (default: false), replaceAll (default: true) (required for: replace) |502| `--sort-columns` | Array of sort specifications: [{columnIndex: 1, ascending: true}, ...] - columnIndex is 1-based relative to range (required for: sort) |503| `--has-headers` | Whether the range has a header row to exclude from sorting (default: true) |504505506507### rangeformat508509Range formatting operations: apply styles, set fonts/colors/borders, add data validation, merge cells, auto-fit dimensions. Use range tool for values/formulas/copy/clear operations. set-style: Apply a named Excel style (Heading 1, Good, Bad, Neutral, Normal). Best for semantic status labels (Good/Bad/Neutral have fill colours and are theme-aware) and document hierarchy (Heading 1/2/3). NOTE: Heading styles do NOT apply a fill colour — use format-range when you need a coloured header row. format-range: Apply any combination of bold, fillColor, fontColor, alignment, borders. Required whenever you need a fill colour or custom branding. Pass ALL desired properties in a SINGLE call — do not call format-range multiple times for the same range. format-ranges: Apply one shared formatting payload to multiple ranges on the same worksheet. Prefer this over repeated format-range calls when the same styling applies to multiple non-contiguous targets. All target ranges are validated before formatting begins. If any target range is invalid, nothing is formatted. COLORS: Hex '#RRGGBB' (e.g., '#FF0000' for red, '#00FF00' for green) FONT: size in points (e.g., 12, 14, 16), alignment: 'left', 'center', 'right' / 'top', 'middle', 'bottom' DATA VALIDATION: Restrict cell input with validation rules: - Types: 'list', 'whole', 'decimal', 'date', 'time', 'textLength', 'custom' - For list validation, formula1 is the list source (e.g., '=$A$1:$A$10' or '"Option1,Option2,Option3"') - Operators: 'between', 'notBetween', 'equal', 'notEqual', 'greaterThan', 'lessThan', 'greaterThanOrEqual', 'lessThanOrEqual' MERGE: Combines cells into one. Only top-left cell value is preserved.510511**Actions:** `set-style`, `get-style`, `format-range`, `format-ranges`, `validate-range`, `get-validation`, `remove-validation`, `auto-fit-columns`, `auto-fit-rows`, `merge-cells`, `unmerge-cells`, `get-merge-info`, `set-column-width`, `set-row-height`512513| Parameter | Description |514|-----------|-------------|515| `--sheet-name` | Name of the worksheet containing the range (required) |516| `--range-address` | Cell range address (e.g., 'A1:D10') (required for: set-style, get-style, format-range, validate-range, get-validation, remove-validation, auto-fit-columns, auto-fit-rows, merge-cells, unmerge-cells, get-merge-info, set-column-width, set-row-height) |517| `--style-name` | Built-in or custom style name (e.g., 'Heading 1', 'Good', 'Bad', 'Currency', 'Percent'). Use 'Normal' to reset. (required for: set-style) |518| `--font-name` | Font family name (e.g., 'Arial', 'Calibri', 'Times New Roman') |519| `--font-size` | Font size in points (e.g., 10, 11, 12, 14, 16) |520| `--bold` | Whether to apply bold formatting |521| `--italic` | Whether to apply italic formatting |522| `--underline` | Whether to apply underline formatting |523| `--font-color` | Font (foreground) color as hex '#RRGGBB' (e.g., '#FF0000' for red) |524| `--fill-color` | Cell fill (background) color as hex '#RRGGBB' (e.g., '#FFFF00' for yellow) |525| `--border-style` | Border line style: 'continuous', 'dash', 'dot', 'dashdot', 'dashdotdot', 'double', 'slantdashdot', 'none' |526| `--border-color` | Border color as hex '#RRGGBB' |527| `--border-weight` | Border weight: 'hairline', 'thin', 'medium', 'thick' |528| `--horizontal-alignment` | Horizontal text alignment: 'left', 'center', 'right', 'justify', 'fill' |529| `--vertical-alignment` | Vertical text alignment: 't530531…(truncated)