SheetForge MCP
SheetForge MCP lets AI agents safely read, inspect, query, edit, validate, and verify Excel .xlsx workbooks through MCP tools.
Create, copy, rename, delete, hide, protect, and inspect worksheets; create workbooks and snapshots.
Read cell ranges and native Excel tables with compact outputs, pagination, schema inference, search, and read-strategy guidance.
Query, aggregate, filter, union, and cross-lookup data across one or many workbooks.
Write cells/rows/ranges, apply formulas, validate formula syntax, and trace formula dependencies or circular references.
Format ranges, merge cells, freeze panes, set autofilters, print areas/titles, column widths, row heights, and worksheet protection.
Create and manage native Excel tables, charts, pivot summaries, named ranges, data validation, and conditional formatting rules.
Append, upsert, or update table/worksheet rows with dry runs and structure-change safeguards.
Audit and repair workbooks, diff versions, analyze range impact, and explain recipe changes.
Run preview/commit workflows for changesets, recipes, scenarios, workbook contracts, and table patches with verification, rollback, and fidelity safeguards.
Works local-first over
stdio, streamable HTTP, or SSE usingopenpyxl, without Excel or LibreOffice.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@SheetForge MCP read the sales table from report.xlsx"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
SheetForge MCP
Local-first Excel MCP server for AI agents that need structured reads, workbook introspection, and safer
.xlsxmutation.
SheetForge MCP is an Excel MCP server for .xlsx automation over the Model Context Protocol. It is built for AI agents, MCP clients, and automation workflows that need more than raw cell access: compact structured reads, workbook-aware guidance, layout-aware inspection, and safer write paths with Python and openpyxl, without launching Microsoft Excel or LibreOffice.
If you are looking for an Excel MCP server for spreadsheet automation, workbook inspection, Excel report generation, dashboard authoring, or .xlsx editing from AI tools, SheetForge MCP is built for that workflow.
Instead of treating every sheet as a blind cell grid, SheetForge helps agents distinguish native Excel tables, worksheet-shaped datasets, layout-heavy dashboards, and chart sheets, then choose the right read or mutation path for each workbook task.
Package name: sheetforge-mcp
CLI command: sheetforge-mcp
Published package release: 0.15.0
Repository docs track the current main-branch tool surface, which currently exposes 83 MCP tools.
Version 0.15.0 adds opt-in preserving XLSX saves for literal cell edits in a restricted workbook profile. Targeted XLSX fidelity checks still guard direct and ChangeSet-backed writes.
Workbook Contracts v1 is included in 0.14.0: explicit bindings and full bounded data checks can guard Recipe preview/commit, with logical-field, file-path and worksheet-versus-table recovery guidance.
Verified Recipes v1 is included in 0.11.0: reusable native-table reports with explicit checks and verified preview/commit.
Verified Explanations v1 is included in 0.12.0: read-only, independently reconciled changes between recomputed recipe results.
Verified Rebase and Verified Scenarios v1 are included in 0.13.0: intent-preserving keyed edits and outcome-checked alternatives with verified commits.
Why SheetForge
reusable workbook contracts via
inspect_workbook_contractand optional Recipe enforcement: separate declared meanings from checked key/type/value rules, resolve only approved exact headers, block ambiguous bindings, and guide agents through logical-field errors without weakening the contractoutcome-checked alternatives via
evaluate_workbook_scenarios: compare explicit keyed changes against exact overall/group metric bounds, then commit one selected outcome with post-save recomputation and rollbackintent-preserving table edits via
apply_table_patch: rebind keyed updates against a pinned base, reject changed premises and conflicting writes, and commit a fresh verified preview while keeping unrelated current valuesagent-friendly reads via
suggest_read_strategy,describe_dataset,query_table, andaggregate_tablesafer cell and multi-step edits:
write_data_to_excelchecks a staged save for targeted XLSX losses;apply_workbook_changesetadds value/table/layout assertions, a structural diff, and commit against the exact previewed source bytesreusable report recipes via
run_workbook_recipe: filter and aggregate a native table, check the result, and write it through a verified ChangeSet without passing intermediate rows through the modelexplainable report changes via
explain_recipe_delta: recompute the same recipe on two source versions, compare by unique keys, and reconcile added/removed/updated contributions without modifying either workbooksafer workbook creation and baselines:
create_workbookrefuses to overwrite an existing.xlsx, whilecreate_workbook_snapshotcreates a verified non-overwriting copy for before/after validationserialized workbook mutation: same-host writers lock each workbook before loading it, then keep the lock through atomic replace and reopen verification so concurrent agents do not silently overwrite one another
smarter worksheet boundaries with bounded
strict,default, andextendedread presets plus compact metadata for any trailing blocks that were intentionally left outworkbook and layout awareness via
profile_workbook,describe_sheet_layout,list_tables,list_charts, andanalyze_range_impactsafer local mutation through
dry_run, compact write responses, guarded native-table append/upsert flows, and workbook diff/audit/repair loopslocal-first performance and privacy with
openpyxl, no desktop Excel dependency, and no cloud-auth requirement
Related MCP server: fcp-sheets
Excel MCP Server Features
workbook creation and metadata
worksheet creation, renaming, copying, deletion, and visibility
structured reads, compact table reads, declarative table queries, grouped aggregates, and cell search
row, column, and range mutations
formulas and validation checks
formatting, freezes, autofilters, merges, and conditional formatting
native Excel tables, charts, and pivot summaries
stdio,streamable-http, and deprecatedssetransports
Common Use Cases
AI agents that need safe, structured Excel workbook access through MCP
spreadsheet automation workflows that read and update
.xlsxreportsExcel dashboard generation with formatting, tables, charts, freeze panes, and print setup
workbook QA and inspection flows that need metadata, named ranges, tables, charts, and protection state
data extraction from native Excel tables or worksheet-shaped datasets without hand-written
openpyxlscripts
Requirements
Python
3.10+.xlsxworkbookseither
uvxor a local package install
Quick Start
Install and run directly from PyPI with uvx, or install the package locally in your Python environment.
Stdio
Use stdio when the MCP client starts the server locally.
uvx sheetforge-mcp stdio{
"mcpServers": {
"excel": {
"command": "uvx",
"args": ["sheetforge-mcp", "stdio"]
}
}
}Streamable HTTP
Use streamable-http when you want a long-running local server process.
EXCEL_FILES_PATH=/path/to/excel-files uvx sheetforge-mcp streamable-httpDefault endpoint:
http://127.0.0.1:8017/mcpExample client config:
{
"mcpServers": {
"excel": {
"url": "http://127.0.0.1:8017/mcp"
}
}
}Remote binding is an explicit opt-in because the HTTP transports do not provide built-in authentication:
FASTMCP_HOST=0.0.0.0 \
SHEETFORGE_ALLOW_REMOTE=true \
EXCEL_FILES_PATH=/path/to/excel-files \
uvx sheetforge-mcp streamable-httpOnly expose a remote listener behind an authenticated and access-controlled network boundary.
SSE
SSE is kept for compatibility, but new integrations should prefer streamable-http.
EXCEL_FILES_PATH=/path/to/excel-files uvx sheetforge-mcp sseDefault endpoint:
http://127.0.0.1:8017/sseFile Path Rules
Paths refer to the server filesystem, not the client's cwd. Reuse supplied paths; never invent an absolute prefix for a relative name.
In
stdiomode,filepathvalues must be absolute paths.In
streamable-httpandssemode, relative paths are resolved underEXCEL_FILES_PATH.In
streamable-httpandssemode, absolute paths are accepted only when they remain insideEXCEL_FILES_PATH; parent traversal and symlink escapes are rejected.In
streamable-httpandssemode, the server createsEXCEL_FILES_PATHautomatically if it does not exist.
Path-policy errors include a stable code and safe next step. Retry the original user-supplied root-relative path on a rooted server, or ask for the intended absolute path in normal stdio. No automatic basename fallback or relocation occurs. See path guidance and error recovery.
Environment Variables
Variable | Default | Used by | Purpose |
|
| HTTP and SSE | Bind address for the server process |
|
| HTTP and SSE | Port for the server process |
|
| HTTP and SSE | Base directory for relative workbook paths |
| unset | HTTP and SSE | Required opt-in for any non-loopback bind; does not add authentication |
Tooling Overview
Worksheet tabs and native Excel tables have separate names. For a named source,
use list_tables to verify its containing tab, then read_excel_table; a missing
name in the worksheet list does not prove the table is absent. See
source selection and error recovery.
The server currently registers 83 MCP tools across these groups:
workbook overview:
create_workbook,create_worksheet,create_workbook_snapshot,get_workbook_metadata,profile_workbook,describe_sheet_layout,audit_workbook,plan_workbook_repairs,apply_workbook_repairs,apply_workbook_changeset,run_workbook_recipe,explain_recipe_delta,diff_workbooks,analyze_range_impact,explain_formula_cell,detect_circular_dependencies,create_named_range,inspect_named_range,list_named_ranges,delete_named_range,list_all_sheets,list_tablesdata access:
suggest_read_strategy,describe_dataset,query_table,aggregate_table,bulk_aggregate_workbooks,bulk_filter_workbooks,union_tables,cross_workbook_lookup,quick_read,read_excel_table,read_data_from_excel,read_excel_as_table,search_in_sheet,write_data_to_excel,append_table_rows,append_excel_table_rows,upsert_excel_table_rows,update_rows_by_keyworksheet and range changes:
copy_worksheet,delete_worksheet,rename_worksheet,set_worksheet_visibility,get_worksheet_protection,set_worksheet_protection,copy_range,delete_range,insert_rows,insert_columns,delete_sheet_rows,delete_sheet_columnsformatting and layout:
format_range,format_ranges,read_range_formatting,freeze_panes,set_autofilter,set_print_area,set_print_titles,set_column_widths,autofit_columns,set_row_heights,merge_cells,unmerge_cells,get_merged_cellsformulas and validation:
apply_formula,validate_formula_syntax,inspect_formula,validate_excel_range,get_data_validation_info,inspect_data_validation_rules,remove_data_validation_rules,inspect_conditional_format_rules,remove_conditional_format_rulesanalysis and structure:
create_table,list_charts,find_free_canvas,create_chart,create_chart_from_series,create_pivot_tableguarded table patches:
apply_table_patchguarded alternatives:
evaluate_workbook_scenariosworkbook contracts:
inspect_workbook_contractandrun_workbook_recipe(..., workbook_contract=...)
For explicit reusable field definitions and mandatory source checks before report generation, see the Workbook Contracts guide and net-sales contract. Declared business meanings are not machine-verified facts. V1 integrates Recipes only; it does not silently enforce contracts on other tools.
For comparing proposed edits before choosing one, see the Verified Scenarios guide and budget example. Scenarios verify explicit sum/count bounds, not forecasts or the business correctness of a decision.
For native-table edits prepared against an earlier snapshot, see apply_table_patch
and the Verified Rebase guide. This is separate from
unconditional key-based upserts: declared read dependencies and old target values
are checked before compiling a fresh ChangeSet.
For chart authoring, prefer create_chart as the primary entry point:
use
data_rangefor the simple contiguous-data pathuse explicit
seriesplus optionalcategories_rangefor non-contiguous or hand-authored chartsuse top-level
widthandheightto control chart size in centimeters; defaults are15 x 7.5use
placementwhen you want SheetForge to position the chart relative to worksheet content, a source range, or a named table instead of guessingtarget_cellmanuallyuse
placement={"relative_to": "free_canvas"}when a busy dashboard needs the first non-overlapping chart slot instead of a simple right/below placement rulekeep
create_chart_from_seriesfor backward compatibility or existing prompts that already rely on it
The most agent-friendly read tools are:
suggest_read_strategy: recommends the best next read tool for a workbook target, including whether SheetForge should treat it as a native Excel table, a clean worksheet dataset, a layout-heavy dashboard sheet, or a chart sheetdescribe_dataset: samples a worksheet or native Excel table and returns headers, schema hints, key-candidate guesses, structural signals, guarded worksheet-boundary metadata, and a recommended follow-up read pathquery_table: filters, projects, sorts, and limits worksheet-shaped data or native Excel tables with a declarative JSON query instead of ad hoc cell loopsaggregate_table: computes grouped metrics such ascount,sum,avg,min, andmaxover worksheet-shaped data or native Excel tablesbulk_aggregate_workbooks: computes the same grouped metrics across many workbook files in one call, with explicit schema handling viastrict,intersect, orunionbulk_filter_workbooks: returns matching rows across many workbook files with optional source provenance columns, so recurring cross-file QA and reporting checks no longer need one-tool-call-per-file loopsunion_tables: combines comparable worksheet or native-table rows across many workbook files, with optional deduplication keys and explicit schema handling for workbook collections that drift over timecross_workbook_lookup: enriches one workbook dataset from one or more lookup workbooks with left-join style matching, optional duplicate-match handling, and compact per-row provenance for matched lookup rowsprofile_workbook: one-call inventory for sheets, tables, charts, named ranges, and key layout/protection state, including chartoccupied_rangefor grid-anchored worksheet chartsdescribe_sheet_layout: worksheet-level structural summary for safe dashboard edits, including freeze panes, print settings, merges, chart anchors, table metadata, conditional-format and validation counts, custom row/column sizing, and a small free-canvas previewaudit_workbook: workbook-level audit for high-signal problems such as broken#REF!formulas, error cells, hidden sheets, header-quality issues, layout-heavy sheets, and named ranges that reference missing sheetsplan_workbook_repairs: converts workbook audit findings into prioritized next steps, including suggested SheetForge tool calls for inspection, safe dry runs, and repair workflowsapply_workbook_repairs: dry-runs or applies the safe repair subset from those plans, including broken named ranges, broken validation rules, broken conditional formats, and optional hidden-sheet revealsapply_workbook_changeset: previews a bounded multi-tool report mutation on an isolated candidate, evaluates explicit postconditions, and commits it with exact-file stale-write protection plus optional verified snapshot and rollbackrun_workbook_recipe: executes a versioned JSON recipe over one native table, checks unique keys, row counts or sum reconciliation, probes column/row-order invariance, and writes a reserved rectangle in the same workbook through ChangeSet preview/commit. See the Verified Recipes guide and example recipe.explain_recipe_delta: independently reconciles changes in recomputedsum/countrecipe results across two source versions by unique keys. Includes group drilldown, exact decimal evidence and explicit sample remainders. It does not validate saved report cells or infer business causes. See Verified Explanations.diff_workbooks: compares two workbook files and reports structural changes plus sampled cell-value diffs, which is useful for before/after verification in agent workflowscreate_workbook_snapshot: creates the verified, non-overwriting baseline that makesdiff_workbooksusable without an external copy scriptanalyze_range_impact: preflight blast-radius check for a worksheet range, including overlaps with tables, chart footprints, merged cells, named ranges, data validations, conditional formats, autofilters, print areas, formula cells inside the range, and formulas or rule expressions elsewhere that depend on it directly or transitively, through named ranges, or through structured table references such asTable1[Sales]explain_formula_cell: resolves a formula cell's direct references, shows upstream formula-chain cells, returns a compactformula_chainsummary with depth layers and sampled paths, and reports downstream dependents so agents can debug workbook logic without manual tracingdetect_circular_dependencies: scans workbook formula graphs, including named-range-driven edges, and reports self-references plus multi-cell circular dependency groups before they surprise downstream automationcreate_named_range: creates workbook-level or sheet-scoped named ranges withdry_runandreplacesupport, so agents can promote important workbook regions into stable references without dropping to ad hoc Pythoninspect_formula: inspects a formula string without workbook context, listing functions, reference token types, volatile functions, and risky functions such asINDIRECTinspect_named_range: inspects one defined name, including its scope, destinations, and whether it points at missing sheets or broken referencesquick_read: single-call compact table read that auto-selects the first sheet when needed, with guardedstrict/default/extendedboundaries,start_rowpagination, andstart_col/end_colcolumn windowing for large sheetsread_excel_table: read a native Excel table bytable_namewithout guessing worksheet bounds, now withstart_rowpagination and optionalstart_col/end_coltable column windowinglist_all_sheets: quick workbook inventory with sheet sizes, emptiness flags, andsheet_typefor worksheets versus chart sheetsread_excel_as_table: compactheaders + rowsoutput for structured datasets, with guarded boundary presets,compact=Truefor the smallest payload,start_rowfor page-like reads, andstart_col/end_colfor narrower column slicesread_data_from_excel: cell-address-aware range reader that supportsmax_rowsandmax_colswindowing for large non-tabular ranges,values_only=Truefor smaller 2D payloads, and cursor-based continuations for multi-step 2D traversalread_range_formatting: compact formatting readback for a worksheet range, grouped by distinct style signatures instead of noisy per-cell dumps, with merged-range and conditional-format overlap summariessearch_in_sheet: exact or partial value search across instantiated worksheet cells, so distant style-only cells do not force a scan of the entire rectangular used range
Workbook inventory tools such as list_all_sheets, profile_workbook, and list_charts surface both worksheets and chart sheets. Grid-oriented tools such as quick_read, read_excel_table, create_table, formatting, formulas, and validation require a real worksheet and return a clear chartsheet error if you target the wrong sheet type.
The most agent-friendly write helpers for structured data are:
upsert_excel_table_rows: update matching rows in a native Excel table and append missing keys in one call Note: totals-row tables are update-only for now; append attempts are rejected rather than shifting unrelated rows.append_excel_table_rows: append rows to a native Excel table when you want the tablerefto grow with the new recordsappend_table_rows: append header-aware rows to worksheet-shaped data when you do not have a native Excel tableupdate_rows_by_key: update worksheet-shaped data by a named key column without appending missing keys
For the compact table readers (quick_read, read_excel_as_table, read_excel_table):
row_mode="arrays"keeps the smallestheaders + rowsshaperow_mode="objects"returnsrecordskeyed by normalized field names such asfirst_namenormalized field names are ASCII-safe transliterations, so headers like
Näyttökerratbecomenayttokerratinfer_schema=Trueadds lightweightschemahints inferred from the returned rowsstart_col/end_collet you slice wide worksheets or native Excel tables down to just the columns you need before pagination or schema inferencetruncated pages now include
next_start_row, which you can pass back to the same tool for the next pagenon-tabular range reads can also return
continuations.downandcontinuations.rightcursor tokens so agents can continue large 2D windows without recomputing coordinatessuggest_read_strategyhelps agents choose between table-aware, worksheet-aware, range-aware, and workbook-orientation reads before they spend context on the wrong pathdescribe_datasetprovides a lighter-weight dataset summary than a full read, including sample rows, header quality, key candidates, and recommended next tooldescribe_dataset,quick_read,read_excel_as_table, andread_excel_tablenow also returnstructure_token,content_token, andsnapshot_metadata, so agents can carry read-time identity forward into safer optimistic-concurrency writesworksheet-shaped compact readers and row-mutation helpers favor the first contiguous data block after the header, so sparse footer notes or distant outlier rows do not silently stretch
total_rows, append targets, or key-based update scansworksheet reads can opt into
read_boundary_mode="strict"(0 blank rows),"default"(5), or"extended"(100); the bounded presets deliberately avoid an unlimited raw gap parameterdescribe_dataset,quick_read, andread_excel_as_tablesurface aread_boundaryobject with the effective tolerance, data end, ignored row count, and compact trailing-block locationsnon-default boundary views are read-only diagnostics and return
write_precondition_compatible=false; reread with the default mode before carrying a structure token into a writequery_tableis the lightest way to pull just the matching rows and columns you need from a worksheet dataset or native Excel tablequery_tableandbulk_filter_workbooksacceptneas a shorthand forneq, and membership filters can use eithervaluesor the shortervaluelist formaggregate_tablelets agents compute grouped summaries directly in SheetForge instead of over-reading the full dataset into context firstbulk_aggregate_workbooksextends that pattern across many workbook files when a recurring reporting workflow would otherwise need ad hoc Python or repeated per-file tool callsaggregate metrics accept both the canonical
{"op": "sum", "field": "Sales", "as": "total_sales"}shape and the more guessable alias form{"agg": "sum", "column": "Sales", "as": "total_sales"}bulk_filter_workbooksdoes the same for row-level inspection, while keeping workbook provenance visible by defaultunion_tablesis the fastest way to normalize many comparable workbook datasets into one combined tabular payload before downstream QA, export, or further aggregationcross_workbook_lookupis the fastest way to enrich one workbook from another without writing an ad hoc merge script, especially for master-data lookups, status enrichment, and cross-file QA workflowsappend_excel_table_rowsis the right append path for native Excel tables when you do not need key-based upsert behaviorappend_table_rowsnow refuses to write directly under an adjacent native Excel table and points you atappend_excel_table_rowsinstead of silently leaving the table range staletoken-aware structured writes can pass
expected_structure_tokento abort on structural drift; append-style writes additionally requireallow_structure_change=True, and successful writes report both previous and new structure/content tokensrename_worksheetnow updates formula cells as well as chart references and named ranges, and it also renames the default sibling pivot sheet (Data_pivot->Revenue_pivot) when that move is conflict-freecopy_worksheetpreserves native tables with workbook-unique copied names, data validations, conditional formatting, freeze panes, autofilters, print settings, protection, charts with their exact anchor geometry, and sheet-scoped names; copied self-references and structured table references are rewritten to the new sheetformatting color inputs accept
RRGGBB,#RRGGBB,AARRGGBB, or#AARRGGBB, so prompts do not need to strip CSS-style#prefixes firstaudit_workbookis the fastest workbook-wide preflight when you need to know whether a spreadsheet is safe and predictable enough for autonomous editingaudit_workbooknow treats dominant native-table sheets more honestly when nearby dashboard/layout artifacts extend the used range, so unrelated merged/chart areas do not create false blank-header risk on an otherwise clean tableplan_workbook_repairsis the fastest way to turn those audit findings into an actual action queue instead of manually deciding the next tool call for every problemapply_workbook_repairslets agents preview or apply the safe subset of those repairs without having to orchestrate each broken workbook artifact manuallydiff_workbooksis the quickest before/after QA pass when an agent has touched workbook structure and wants proof of what actually changed
Recommended Agent Workflows
Unfamiliar workbook -> verified multi-step mutation Start with
profile_workbook(orlist_all_sheetsfor the lightest inventory), inspect layout-heavy tabs withdescribe_sheet_layout, and runanalyze_range_impact. Put supported report-building edits and explicit postconditions intoapply_workbook_changeset(mode="preview"). Reviewpackage_fidelity; only ifready_to_commit=trueshould you repeat the same plan withmode="commit",expected_workbook_sha256, andchangeset_tokenfrom the preview. See XLSX fidelity checks and the preserving save mode for restricted literal cell edits.Workbook repair loop Use
audit_workbookto find high-signal issues,plan_workbook_repairsto turn them into an action queue,apply_workbook_repairs(..., dry_run=True)to preview the safe subset, then rerunaudit_workbookafter applying repairs to confirm the workbook is back to a low-risk state.Multi-workbook reporting Use
bulk_aggregate_workbooks,bulk_filter_workbooks,union_tables, orcross_workbook_lookupto build the reporting dataset first, then write the summarized rows into a fresh workbook tab and finish the presentation layer withformat_ranges,find_free_canvas,create_chart, andautofit_columns.
See TOOLS.md for the full reference. Release notes live in CHANGELOG.md.
Response Format
Every tool now returns a JSON envelope with a consistent top-level shape:
{
"ok": true,
"operation": "read_excel_as_table",
"message": "read_excel_as_table completed",
"data": {}
}Error responses follow the same contract:
{
"ok": false,
"operation": "write_data_to_excel",
"error": {
"type": "DataError",
"message": "No data provided to write"
}
}For destructive tools that support preview mode, the envelope may also include dry_run and changes.
Committed write operations now default to compact summaries; pass include_changes=True when you want per-cell, per-range, or per-operation detail.
Development
Install dependencies:
uv sync --extra devRun tests:
uv run --extra dev pytest -qRun lint checks:
uv run --extra dev ruff check src testsRun the package locally:
uv run sheetforge-mcp stdioBuild distributions locally:
uv buildRelease Flow
Update
pyproject.toml,manifest.json, and the tracked.mcpbbundle together for each release.Keep the tracked bundle filename in sync with the package version, for example
sheetforge-mcp-<version>.mcpb.Every distribution-building workflow verifies the wheel, source distribution, and tracked MCPB bundle against shared public-artifact allowlists before release or publication.
GitHub releases run a build verification workflow only.
PyPI publishing is a separate manual workflow, so releases do not create a failing deployment before Trusted Publisher is configured for the package.
Repository Layout
src/excel_mcp/server.py: MCP server, transport setup, and tool registrationsrc/excel_mcp/workbook.py: workbook lifecycle helpers and workbook metadatasrc/excel_mcp/changeset.py: verified multi-operation preview/commit transactions and assertionssrc/excel_mcp/recipes.py: bounded native-table report recipes, checks, lineage samples, and ChangeSet compilationsrc/excel_mcp/explanations.py: read-only keyed recipe deltas with independent arithmetic/filter checks and bounded evidencesrc/excel_mcp/data.py: read, write, table, and search helperssrc/excel_mcp/sheet.py: worksheet and range mutationstests/: regression tests covering data, layout, charts, pivots, formatting, tables, and resource safetyscripts/verify_release_artifacts.py: shared wheel/sdist/MCPB content verifier used by CI and release workflowsmanifest.json: packaged MCP bundle metadatadocs/index.html: static project landing page
Why SheetForge MCP
Excel-first MCP surface: the toolset is focused on real
.xlsxworkbook operations, not generic file I/Oagent-friendly responses: consistent JSON envelopes, compact writes, and
dry_runpreviews reduce context wasteworkbook introspection:
profile_workbook,list_all_sheets,list_tables, andlist_chartsmake unfamiliar spreadsheets easier to navigatesafer edits:
analyze_range_impactgives agents a read-only preflight before overwriting, deleting, or restructuring an important range, including downstream formula chains plus validation-rule and conditional-format references elsewhere in the workbook even when formulas point at the range through named ranges or structured table referencesverified transactions:
apply_workbook_changesetbinds a bounded operation/assertion plan to the canonical target path and exact source SHA-256, tests it on an isolated candidate, verifies cells, tables, freeze panes, autofilters, and chart placement, and replaces the source once only after all checks passlayout planning:
find_free_canvassuggests safe empty slots for charts or dashboard blocks before you place them, defaulting to the standard chart footprint when you omit explicit sizingpractical Excel output: formatting, print setup, worksheet protection, table upserts, chart authoring, and autofit helpers cover real reporting workflows
Python ecosystem fit: built on
openpyxl, packaged foruvx, and easy to run locally overstdioor through a deliberately gated HTTP deployment
Notes For Integrators
stdiomode is careful not to write non-protocol text tostdout.All tools return structured JSON envelopes, which makes client-side parsing predictable.
Tool responses now use compact JSON serialization to reduce MCP payload size while keeping the same envelope shape.
read_data_from_excel(..., preview_only=True)limits the response to the first 10 rows in the selected range and marks the payload as truncated when applicable.read_data_from_excel(..., compact=True)omits default validation stubs for cells that do not have validation rules.read_data_from_excel(..., values_only=True)returns a plain 2Dvaluesarray for range reads that do not need per-cell addresses or validation metadata.read_data_from_excel(..., max_rows=...)paginates tall rectangular ranges and returnsnext_start_rowplusnext_start_cellwhen more rows remain.read_data_from_excel(..., max_cols=...)paginates wide rectangular ranges and returnsnext_start_colplusnext_column_start_cellwhen more columns remain.read_data_from_excel(..., cursor=...)resumes from a continuation token so agents can keep paging without recomputing the next window manually; 2D windows expose directional continuations undercontinuations.downandcontinuations.rightread_excel_as_table(..., compact=True)minimizes the tabular payload toheadersandrowsunless truncation metadata is needed, while still returning dataset identity metadatacompact tabular readers still include
structure_token,content_token, andsnapshot_metadata, even when the tabular payload itself is minimizedquick_read(..., start_row=...)andread_excel_as_table(..., start_row=...)let agents paginate deep worksheets without first reading from the top.quick_read(..., start_col=..., end_col=...)andread_excel_as_table(..., start_col=..., end_col=...)let agents request only the relevant columns from wide worksheets instead of pulling every column into context.read_excel_table(..., start_col=..., end_col=...)now supports the same narrower column slices for native Excel tables, as long as the requested columns fall inside the table range.quick_read(..., include_headers=False),read_excel_as_table(..., include_headers=False), andread_excel_table(..., include_headers=False)let follow-up pages omit repeated header payload once the first page already established the schema.read_excel_table(..., start_row=...)now supports deeper pagination into native Excel tables instead of always reading from the top.Truncated tabular reads now return
next_start_rowso agents can continue paging without recalculating offsets.Oversized read responses now fail early with
ResponseTooLargeErrorplus structuredhints, so agents can retry with smaller ranges or pagination before the client truncates the payload.quick_read,read_excel_as_table, andread_excel_tablecan now returnrecordsplus inferredschemahints when you opt intorow_mode="objects"andinfer_schema=True.Read tools do not recalculate Excel formulas; formula cells surface as formula text such as
=B2*C2, and inferred schema labels formula-backed columns asformulaso agents do not mistake them for fresh numeric values.profile_workbookprovides a single-call workbook inventory with sheet-level table, chart, protection, print, and filter metadata for faster agent orientation, and now includes chartoccupied_rangealongside anchors and dimensions for grid-anchored worksheet charts.Core mutation tools now default to compact responses on committed writes, including data writes, formatting, worksheet layout helpers, and merge/unmerge helpers. Use
include_changes=Truefor detailed diffs.Token-aware structured writes now return
previous_structure_token,new_structure_token,previous_content_token,new_content_token, andsnapshot_metadata, which makes multi-agent or read-then-write flows safer without adding hidden workbook metadata.dry_runversions of those structured writes now label snapshot metadata astoken_basis="dry_run_preview"and keep the on-disk file facts undersource_file_*, so preview tokens are no longer mixed with live-file metadata.Workbook saves that go through
safe_workbook(..., save=True)use a timeout-aware same-host workbook lock plus temp-file save,fsync, atomic replace, rollback-on-verification-failure, and reopen verification. Symlink paths update their real target without replacing the symlink itself. If automatic rollback fails, the recovery backup is retained and identified in the error. This protects cooperating SheetForge processes on one machine; it is not a distributed lock for cloud-sync providers.format_rangesbatches multiple formatting operations into one workbook pass and reports per-rangeerrorswithout discarding successful ranges. A failed range is rolled back to its pre-operation styles, values, comments, hyperlinks, merge state, and conditional-format rules before the batch continues.validate_formula_syntaxperforms structural token validation, checks Excel coordinate limits, and rejects risky functions such asINDIRECT,HYPERLINK,WEBSERVICE,DGET, andRTDcase-insensitively. It does not calculate formulas or replace Excel's own calculation engine.write_data_to_excelremains a raw cell-write primitive and can store formula strings directly; use it only with trusted data, or useapply_formulawhen you want SheetForge's formula safety checks.Server logs rotate at 5 MiB with two backups instead of growing without a bound.
autofit_columnsestimates practical column widths from the current cell contents, with optional column filters and min/max bounds.list_chartsnow reports chartwidthandheightin centimeters in addition to anchor, type, and series metadata.get_worksheet_protectionandset_worksheet_protectionadd a safe worksheet-level wrapper around Excel protection flags.set_print_areaandset_print_titlesmake report/export setup scriptable without dropping into raw openpyxl workbook internals.list_tablesnow returns lightweight schema metadata such as headers, row counts, and stripe settings in addition to table names and ranges.upsert_excel_table_rowsexpands native Excel table ranges automatically when it appends missing keys, refuses to grow a table into already occupied cells, and rejects append attempts when the target table has an enabled totals row.Core mutation tools support
dry_run=Trueso clients can preview changes before saving a workbook.
License
MIT. See LICENSE.
Available Tools
83 toolsaggregate_tableCRead-only
Compute grouped metrics over worksheet-shaped data or a native Excel table.
Inputs: filepath (required), limit, filters, metrics, +8 more.
analyze_range_impactBRead-only
Inspect workbook structures that overlap a worksheet range before mutation.
Inputs: filepath (required), range_ref (required), sheet_name (required).
append_excel_table_rowsCDestructive
Append rows to a native Excel table and expand its range safely.
Inputs: rows (required), filepath (required), table_name (required), dry_run, +4 more.
append_table_rowsCDestructive
Append dictionary-shaped rows by matching worksheet headers on a worksheet dataset.
Inputs: rows (required), filepath (required), sheet_name (required), dry_run, +4 more.
apply_formulaCDestructive
Apply Excel formula to cell. Excel formula will write to cell with verification.
Inputs: cell (required), formula (required), filepath (required), sheet_name (required).
apply_table_patchADestructive
Preview/commit a three-way keyed patch against a pinned retained base.
patch requires version=1, source={table_name, optional sheet_name}, nonempty
key_fields, explicit read_fields (use [] only for no extra dependencies), and
updates=[{key: {all key fields}, values: {literal field updates}}]. Write fields
must not be keys/read_fields. Checks complete unique keys and row-local read
dependencies; does not infer undeclared or cross-row dependencies. Existing
rows only, same exact headers with reordering allowed, no formula evaluation.
Conflicts/missing rows/changed premises block the entire batch. Commit requires
the identical patch/base and rebase_token/expected_workbook_sha256 from a fresh
preview. Reuses ChangeSet snapshots, exact-file checks and rollback. Limits:
1000 target cells, 50 contiguous column spans, 50000 table cells/64 columns per
source; sample_limit 1-10 bounds examples only. Tokens are not authentication.
Inputs: patch (required), filepath (required), base_filepath (required), expected_base_sha256 (required), +4 more.
apply_workbook_changesetADestructive
Preview or commit an assertion-backed group of workbook mutations as one transaction.
Each operation is {"tool": "name", "args": {...}}. Supported tool names are
create_worksheet, write_data_to_excel, format_range, format_ranges, freeze_panes,
set_autofilter, set_column_widths, set_row_heights, autofit_columns, create_table,
and create_chart. Assertions support sheet_exists, cell_equals, range_equals,
range_values_unchanged, table_exists, freeze_panes_equals, autofilter_equals,
chart_exists, and no_cell_ref_errors.
Call preview first. Commit the identical plan with expected_workbook_sha256 and
changeset_token from that preview. Snapshot creation defaults to enabled.
Inspect package_fidelity: custom XML or untouched formula-cache loss blocks
commit. The check is targeted, not a guarantee of full Excel round-trip fidelity.
save_mode="preserve" patches only literal cell writes in a restricted XLSX.
Unsupported workbook features or formulas block the save; no standard fallback.
Use the same save_mode in preview and commit.
Inputs: filepath (required), operations (required), mode, save_mode, +6 more.
apply_workbook_repairsBDestructive
Apply safe workbook repair actions with dry-run planning and before/after diff output.
Inputs: filepath (required), dry_run, header_row, sheet_names, +2 more.
audit_workbookCRead-only
Audit workbook structure for high-signal issues that affect agent workflows.
Inputs: filepath (required), header_row, sample_limit.
autofit_columnsCDestructive
Auto-fit worksheet columns based on content width.
Inputs: filepath (required), sheet_name (required), columns, dry_run, +3 more.
bulk_aggregate_workbooksCRead-only
Aggregate comparable worksheet or table data across multiple workbooks.
Inputs: filepaths (required), limit, filters, metrics, +10 more.
bulk_filter_workbooksCRead-only
Filter comparable worksheet or table data across multiple workbooks. Uses the same filter operators and aliases as query_table.
Inputs: filepaths (required), limit, select, filters, +10 more.
copy_rangeCDestructive
Copy a range of cells to another location.
Inputs: filepath (required), sheet_name (required), source_end (required), source_start (required), +3 more.
copy_worksheetCDestructive
Copy a worksheet with tables, rules, charts, names, and layout settings.
Inputs: filepath (required), source_sheet (required), target_sheet (required).
create_chartADestructive
Create chart in worksheet from a contiguous range or explicit series.
This is the preferred chart authoring entry point; explicit-series calls are
also still available via create_chart_from_series for backward compatibility.
Inputs: filepath (required), chart_type (required), sheet_name (required), style, +10 more.
create_chart_from_seriesCDestructive
Create a chart from explicit series definitions for non-contiguous ranges.
Inputs: filepath (required), chart_type (required), sheet_name (required), style, +9 more.
create_named_rangeCDestructive
Create a workbook-level or sheet-scoped named range.
Inputs: name (required), filepath (required), range_ref (required), hidden, +4 more.
create_pivot_tableCDestructive
Create pivot table in worksheet.
Inputs: rows (required), values (required), filepath (required), data_range (required), +4 more.
create_tableCDestructive
Creates a native Excel table from a specified range of data.
Inputs: filepath (required), data_range (required), sheet_name (required), table_name, +1 more.
create_workbookCDestructive
Create a new Excel workbook with an optional initial worksheet name.
Inputs: filepath (required), sheet_name.
create_workbook_snapshotBDestructive
Create a verified workbook snapshot without overwriting an existing file.
Inputs: filepath (required), snapshot_filepath (required).
create_worksheetCDestructive
Create new worksheet in workbook.
Inputs: filepath (required), sheet_name (required).
cross_workbook_lookupCRead-only
Enrich one workbook dataset from matching rows in one or more lookup workbooks.
Inputs: source_key (required), source_filepath (required), lookup_filepaths (required), limit, +20 more.
delete_named_rangeCDestructive
Delete a workbook-level or sheet-scoped named range.
Inputs: name (required), filepath (required), dry_run, scope_sheet.
delete_rangeCDestructive
Delete a range of cells and shift remaining cells.
Inputs: end_cell (required), filepath (required), sheet_name (required), start_cell (required), +2 more.
delete_sheet_columnsCDestructive
Delete one or more columns starting at the specified column.
Inputs: filepath (required), start_col (required), sheet_name (required), count, +1 more.
delete_sheet_rowsCDestructive
Delete one or more rows starting at the specified row.
Inputs: filepath (required), start_row (required), sheet_name (required), count, +1 more.
delete_worksheetCDestructive
Delete worksheet from workbook.
Inputs: filepath (required), sheet_name (required).
describe_datasetCRead-only
Summarize a worksheet or native Excel table for agent-friendly orientation.
Inputs: filepath (required), header_row, sheet_name, table_name, +2 more.
describe_sheet_layoutCRead-only
Return a structural worksheet layout summary for safe dashboard-style edits.
Inputs: filepath (required), sheet_name (required), sample_limit, free_canvas_cols, +2 more.
detect_circular_dependenciesCRead-only
Detect circular workbook formula dependencies, including self-references.
Inputs: filepath (required), sample_limit.
diff_workbooksBRead-only
Diff two workbook files and report structural changes plus sampled cell-value changes.
Inputs: after_filepath (required), before_filepath (required), sample_limit, include_cell_changes.
evaluate_workbook_scenariosADestructive
Compare explicit alternatives read-only, or commit one exact verified outcome.
scenario_set requires version=1, a Recipe v1 (only sum/count; output is never
written), key_fields, guards=[{metric, scope: overall|each_group, min?, max?}],
and scenarios=[{id, updates: [{key: {...}, values: {...}}]}]. Bounds are inclusive
exact comparisons. Each-group checks include all baseline/candidate groups;
missing baseline groups and empty coverage fail. No optimization or forecasting.
One native table, existing keys/literal updates only, no formulas/key changes.
Commit requires the identical set, selected_scenario id, scenario_token and
expected_workbook_sha256 from comparison; source drift requires a new comparison.
Full metric checks run again on the saved workbook under ChangeSet rollback.
Limits: 5 alternatives, 8 sum/count metrics, 20 guards, 50000 source cells,
1000 targets/49 column spans per alternative, 256KB JSON, sample_limit 1-5.
Inputs: filepath (required), scenario_set (required), mode, sample_limit, +3 more.
explain_formula_cellBRead-only
Explain a formula cell's direct references, upstream formula chain, and downstream dependents.
Inputs: cell (required), filepath (required), sheet_name (required), max_depth.
explain_recipe_deltaARead-only
Explain sum/count changes by source identity, without modifying either file.
Recompute one shared Recipe v1 on two distinct .xlsx source versions. Requires
nonblank unique key_fields (exact headers) on every source data row, even if
excluded by recipe filters. Supports at most 8 metrics, all sum/count.
Returns added/removed/updated contributions, group changes and bounded physical
source-row examples. Numeric evidence uses exact decimal strings. Recipe float
differences are explicit numeric_adjustment values, not business explanations.
Optional metric selects one exact output alias; group must give all group_by
fields with exact literal values. All calculations/checks remain complete;
sample_limit (1-10) only bounds examples and omitted contributions are reported.
Pin both source sha256 values and recipe_sha256 from a previous response for
repeatable drilldown. The explanation_token is an integrity fingerprint, not
authorization or a commit token. Does not validate saved report cells, infer
historical recipe definitions, evaluate formulas or establish business causes.
Limits per source: 50,000 table cells, 64 columns, 10,000 recomputed result cells.
Inputs: recipe (required), key_fields (required), after_filepath (required), before_filepath (required), +6 more.
find_free_canvasCRead-only
Suggest free worksheet slots for charts or dashboard blocks.
Inputs: filepath (required), sheet_name (required), limit, width, +8 more.
format_rangeCDestructive
Apply formatting to a range of cells. Colors accept RRGGBB, #RRGGBB, AARRGGBB, or #AARRGGBB.
Inputs: filepath (required), sheet_name (required), start_cell (required), bold, +16 more.
format_rangesBDestructive
Apply formatting to multiple ranges in a single workbook pass. Colors accept RRGGBB, #RRGGBB, AARRGGBB, or #AARRGGBB.
Inputs: ranges (required), filepath (required), sheet_name (required), dry_run, +1 more.
freeze_panesCDestructive
Set or clear worksheet freeze panes.
Inputs: filepath (required), sheet_name (required), cell, dry_run, +1 more.
get_data_validation_infoBRead-only
Get all data validation rules in a worksheet.
This tool helps identify which cell ranges have validation rules
and what types of validation are applied.
Args:
filepath: Path to Excel file
sheet_name: Name of worksheet
Returns:
JSON string containing all validation rules in the worksheet
Inputs: filepath (required), sheet_name (required).
get_merged_cellsCRead-only
Get merged cells in a worksheet.
Inputs: filepath (required), sheet_name (required).
get_workbook_metadataARead-only
Get workbook metadata; sheets lists TABS, not native table names.
Table inventory is not included. A missing table name in sheets does NOT mean
the table is absent. Use list_tables without sheet_name to verify named sources.
Inputs: filepath (required), include_ranges.
get_worksheet_protectionCRead-only
Get worksheet protection status and option flags.
Inputs: filepath (required), sheet_name (required).
insert_columnsCDestructive
Insert one or more columns starting at the specified column.
Inputs: filepath (required), start_col (required), sheet_name (required), count, +1 more.
insert_rowsCDestructive
Insert one or more rows starting at the specified row.
Inputs: filepath (required), start_row (required), sheet_name (required), count, +1 more.
inspect_conditional_format_rulesBRead-only
Inspect worksheet conditional formatting rules with stable rule indexes.
Inputs: filepath (required), sheet_name (required), broken_only.
inspect_data_validation_rulesCRead-only
Inspect worksheet data validation rules with stable rule indexes.
Inputs: filepath (required), sheet_name (required), broken_only.
inspect_formulaARead-only
Inspect a formula string for functions, references, and risky signals.
Inputs: formula (required).
inspect_named_rangeBRead-only
Inspect a named range, including scope, destinations, and broken-reference signals.
Inputs: name (required), filepath (required), scope_sheet.
inspect_workbook_contractARead-only
Read-only full bounded native-table contract check; never infer business meaning.
Contract v1 requires version=1, name, source={table_name, optional sheet_name},
row_grain (a declaration), key_fields (logical names), and fields=[{name,
headers: [approved exact alternatives], type: string|number|integer|boolean,
nullable?: false, meaning?, allowed_values?, min?, max?}]. Optional min_rows
defaults to 1; filters use logical field names and Recipe predicates. Missing
or multiple matching headers are unresolved, never automatically selected.
Checks all source rows BEFORE filtering, excluding native totals. Declared
meanings are not verified facts. No coercion, formulas, dates, joins or code.
Limits: 32KB JSON, 32 fields, 8 aliases/field, 8 key fields, 20 filters,
50000 table cells/64 columns; sample_limit 1-5 affects row examples only.
Pass the same contract as workbook_contract to run_workbook_recipe to enforce
it in preview/commit; this inspection alone does not guard other tools.
Recovery: omit sample_limit for default 3 (never use Recipe's 10 here).
recipe_input_fields lists the exact logical names to use in Recipe inputs;
bindings values are physical headers for inspection, not Recipe field names.
For {name: "net", headers: ["NetSales"]}, use metrics.field="net", not
"NetSales". For {name: "currency", headers: ["Currency"]}, use
group_by=["currency"]. Metric as="Revenue" is an output label, not remapped.
Follow next_action: unresolved/violated requires an owner decision, not a
changed contract or filtered-out violation. Reuse the supplied filepath;
do not construct an absolute path by prefixing the client working directory.
Inputs: contract (required), filepath (required), sample_limit.
list_all_sheetsARead-only
List all sheets in a workbook with row/column counts. Quick overview before reading data.
Inputs: filepath (required).
list_chartsCRead-only
List embedded charts in a workbook or worksheet.
Inputs: filepath (required), sheet_name.
list_named_rangesBRead-only
List workbook defined names and their destinations.
Inputs: filepath (required).
list_tablesARead-only
Map native table names to worksheet tabs and ranges; these names are distinct.
Omit sheet_name to search the whole workbook, especially after a missing-tab
error. Table and worksheet names may differ; neither name implies the other.
Inputs: filepath (required), sheet_name.
merge_cellsCDestructive
Merge a range of cells.
Inputs: end_cell (required), filepath (required), sheet_name (required), start_cell (required), +2 more.
plan_workbook_repairsCRead-only
Turn workbook audit findings into prioritized next steps for SheetForge workflows.
Inputs: filepath (required), header_row, sample_limit.
profile_workbookBRead-only
Return a compact workbook inventory with sheets, tables, charts, and layout state.
Inputs: filepath (required).
query_tableCRead-only
Filter, project, sort, and limit worksheet or table data. Filters support eq/neq/ne, comparisons, string matching, blank checks, and in/not_in with value or values.
Inputs: filepath (required), limit, select, filters, +7 more.
quick_readARead-only
Read a compact table from an explicit sheet or the first workbook sheet.
Can return either array rows or object-shaped records, plus optional schema
hints inferred from the returned rows.
sheet_name is a worksheet tab, NOT a native table name. For named tables use
read_excel_table(table_name=...); list_tables verifies the containing worksheet.
Inputs: filepath (required), end_col, max_rows, row_mode, +7 more.
read_data_from_excelARead-only
Read data from Excel worksheet with cell metadata including validation rules.
Args:
filepath: Path to Excel file
sheet_name: Worksheet tab name, NOT a native table name; list_tables maps tables to tabs
start_cell: Starting cell (default A1)
end_cell: Ending cell (optional, auto-expands if not provided)
max_rows: Optional maximum number of rows to return from the starting row
max_cols: Optional maximum number of columns to return from the starting column
cursor: Optional continuation token returned by an earlier range read
preview_only: Whether to return preview only
compact: Whether to omit default validation metadata for smaller responses
values_only: Whether to return a 2D value grid without per-cell metadata
Returns:
JSON string containing either structured cell data with validation metadata
or a plain 2D value grid when values_only=True.
Inputs: filepath (required), sheet_name (required), cursor, compact, +6 more.
read_excel_as_tableARead-only
Read Excel data as a compact table with headers and rows or record objects.
sheet_name is a worksheet TAB, not a native table. For an approved named
table use read_excel_table(table_name=...); list_tables maps tables to tabs.
Much more context-efficient than read_data_from_excel for structured data,
with optional inferred schema hints for downstream steps.
Inputs: filepath (required), sheet_name (required), compact, end_col, +8 more.
read_excel_tableARead-only
Read a native Excel table by its table name, not by a worksheet tab name.
Use the exact table_name from list_tables. Omit sheet_name when unknown;
if supplied, it must be the table's containing worksheet tab, not the table name.
Supports compact table payloads, object-shaped record output, and optional
inferred schema hints.
Inputs: filepath (required), table_name (required), compact, end_col, +7 more.
read_range_formattingCRead-only
Read a compact formatting summary for a worksheet range.
Inputs: filepath (required), range_ref (required), sheet_name (required), sample_limit.
remove_conditional_format_rulesBDestructive
Remove worksheet conditional formatting rules by index or remove all broken ones.
Inputs: filepath (required), sheet_name (required), dry_run, broken_only, +1 more.
remove_data_validation_rulesBDestructive
Remove worksheet data validation rules by index or remove all broken ones.
Inputs: filepath (required), sheet_name (required), dry_run, broken_only, +1 more.
rename_worksheetCDestructive
Rename worksheet in workbook.
Inputs: filepath (required), new_name (required), old_name (required).
run_workbook_recipeADestructive
Preview or commit a reusable JSON recipe without echoing intermediate rows.
Recipe v1 requires version=1, source={table_name, optional sheet_name},
group_by=[exact header names], metrics=[{op, field, as}], and
output={sheet_name, range_ref, optional allow_overwrite=false}.
Optional filters use query_table operators; optional checks support unique_key
(fields), row_count (min/max), and sum_matches (source_field/output_field).
count metrics omit field. Other metrics: sum, avg, min, max, count_non_null,
count_distinct. Only literal finite JSON cells in referenced fields are supported.
Optional workbook_contract enforces Contract v1: source selectors must match,
ALL Recipe input references must use contract fields[].name, NEVER physical
fields[].headers. Copy names from inspection.recipe_input_fields (binding keys).
Example: net bound to NetSales -> metrics=[{op:"sum",field:"net",as:"Revenue"}];
currency bound to Currency -> group_by=["currency"]. The as label stays Revenue.
This also applies to filters.field, unique_key.fields and sum_matches.source_field.
Contract field errors return bounded details.examples with Recipe JSON-pointer
paths and exact replace_with names where known: fix the Recipe references only,
keep workbook_contract unchanged, then make a NEW preview before commit.
Contract filters are mandatory
AND predicates. All contract rows are checked before filtering and again on
the saved workbook. Repeat the identical contract on commit; changed contracts
invalidate recipe tokens. Declared meanings are not verified business truth.
Output is one reserved rectangle in the same workbook, fully replaced including
blank padding. Occupied output requires allow_overwrite=true; table/merge overlap
is rejected. Preview first, then commit the unchanged recipe with recipe_token
and expected_workbook_sha256 from preview. A verified snapshot is always enabled.
Limits: 50,000 source cells, 64 source columns, 10,000 output cells; sample_limit 1-10.
Inputs: recipe (required), filepath (required), mode, recipe_token, +3 more.
search_in_sheetCRead-only
Search for cells matching a value in a worksheet.
Inputs: query (required), filepath (required), sheet_name (required), exact, +1 more.
set_autofilterCDestructive
Set worksheet autofilter for an explicit or inferred range.
Inputs: filepath (required), sheet_name (required), dry_run, range_ref, +1 more.
set_column_widthsCDestructive
Set explicit widths for one or more worksheet columns.
Inputs: widths (required), filepath (required), sheet_name (required), dry_run, +1 more.
set_print_areaCDestructive
Set or clear worksheet print area.
Inputs: filepath (required), sheet_name (required), dry_run, range_ref, +1 more.
set_print_titlesBDestructive
Set, preserve, or clear repeating print title rows and columns.
Inputs: filepath (required), sheet_name (required), rows, columns, +2 more.
set_row_heightsCDestructive
Set explicit heights for one or more worksheet rows.
Inputs: heights (required), filepath (required), sheet_name (required), dry_run, +1 more.
set_worksheet_protectionCDestructive
Enable or disable worksheet protection with optional capability flags.
Inputs: filepath (required), sheet_name (required), dry_run, enabled, +3 more.
set_worksheet_visibilityCDestructive
Set worksheet visibility to visible, hidden, or veryHidden.
Inputs: filepath (required), sheet_name (required), visibility (required), dry_run, +1 more.
suggest_read_strategyCRead-only
Recommend the best SheetForge read tool for the requested workbook target.
Inputs: filepath (required), goal, header_row, sheet_name, +2 more.
union_tablesCRead-only
Union comparable worksheet or table data across multiple workbook files.
Inputs: filepaths (required), limit, select, sort_by, +10 more.
unmerge_cellsCDestructive
Unmerge a range of cells.
Inputs: end_cell (required), filepath (required), sheet_name (required), start_cell (required), +2 more.
update_rows_by_keyCDestructive
Update existing table rows using a named key column.
Inputs: updates (required), filepath (required), key_column (required), sheet_name (required), +4 more.
upsert_excel_table_rowsCDestructive
Update matching rows in a native Excel table and append missing keys.
Inputs: rows (required), filepath (required), key_column (required), table_name (required), +5 more.
validate_excel_rangeCRead-only
Validate if a range exists and is properly formatted.
Inputs: filepath (required), sheet_name (required), start_cell (required), end_cell.
validate_formula_syntaxBRead-only
Validate Excel formula syntax without applying it.
Inputs: cell (required), formula (required), filepath (required), sheet_name (required).
write_data_to_excelBDestructive
Write rows to a worksheet, starting at start_cell. Formulas are not evaluated.
dry_run serializes an isolated candidate and reports package_fidelity and
ready_to_commit without saving. Writes recheck protected XLSX content before
replacing the source. This is not a guarantee of full XLSX fidelity.
Inputs: data (required), filepath (required), sheet_name (required), dry_run, +2 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 83 tools
Several tool clusters have genuinely unclear boundaries: get_data_validation_info vs inspect_data_validation_rules, append_table_rows vs append_excel_table_rows, and a four-way read overlap (read_data_from_excel, read_excel_as_table, quick_read, query_table) that only the verbose descriptions partially untangle. Multiple write paths (write_data_to_excel, apply_workbook_changeset, apply_table_patch, upsert_excel_table_rows, update_rows_by_key) also target overlapping mutations, so tool selection is error-prone despite detailed prose.
Everything is snake_case and mostly verb_noun, but the read verbs are scattered across read_/get_/inspect_/list_/describe_/profile_/audit_ with no rule distinguishing them (get_merged_cells vs inspect_named_range vs list_named_ranges). A few names invert the pattern (cross_workbook_lookup, search_in_sheet, freeze_panes, bulk_filter_workbooks), keeping it readable but not predictable.
83 tools is far beyond what a coherent Excel surface needs, and much of the bulk is near-duplicate read/write/validation variants rather than distinct capabilities. The set reads as accumulated feature creep, making it hard for an agent to discover the canonical tool for a task.
Coverage of the Excel domain is unusually thorough: reading, writing, formatting, tables, charts, pivots, named ranges, protection, print setup, validation/conditional-format inspection, formula analysis, recipes, patches, snapshots, and diffs. Missing pieces exist (creating conditional formatting or data validation rules, sorting, chart/pivot deletion or update, worksheet reordering, workbook-level protection), but agents can work around most of them.
Maintenance
Related MCP Connectors
The Excel engine for AI agents: read, check and edit Excel models over MCP.
An agent-first office suite Claude & ChatGPT read and write over one MCP URL.
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
Open-source Zapier/n8n alternative as an MCP server: agents build, run and debug your workflows.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables AI agents to create, read, and modify Excel workbooks without requiring Microsoft Excel installation.MIT
- AlicenseBqualityDmaintenanceMCP server for semantic spreadsheet operations that lets LLMs create and edit Excel workbooks by describing spreadsheet intent.42MIT
- AlicenseNot gradedqualityBmaintenanceMCP server for Excel-compatible formula evaluation and workbook operations, enabling agents to open, inspect, mutate, recalculate, and save .xlsx files in-memory over stdio.83 npmApache 2.0
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol (MCP) server that lets you manipulate Excel files without needing Microsoft Excel installed. Create, read, and modify Excel workbooks with your AI agent.MIT