SheetForge MCP
SheetForge MCP: read, write, and reshape Excel workbooks over MCP
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.8.0
Repository docs track the current main-branch tool surface, which currently exposes 76 MCP tools.
Why SheetForge
- agent-friendly reads via
suggest_read_strategy,describe_dataset,query_table, andaggregate_table - safer workbook creation:
create_workbooknow refuses to overwrite an existing.xlsx - smarter worksheet boundaries so compact readers stop at the main contiguous data block and surface trailing-row hints instead of over-reading sparse footer noise
- workbook and layout awareness via
profile_workbook,describe_sheet_layout,list_tables,list_charts, andanalyze_range_impact - safer local mutation through
dry_run, compact write responses, guarded native-table append/upsert flows, and workbook diff/audit/repair loops - local-first performance and privacy with
openpyxl, no desktop Excel dependency, and no cloud-auth requirement
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
.xlsxreports - Excel 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+ .xlsxworkbooks- either
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 or remote server process.
EXCEL_FILES_PATH=/path/to/excel-files uvx sheetforge-mcp streamable-http
Default endpoint:
http://127.0.0.1:8017/mcp
Example client config:
{
"mcpServers": {
"excel": {
"url": "http://127.0.0.1:8017/mcp"
}
}
}
SSE
SSE is kept for compatibility, but new integrations should prefer streamable-http.
EXCEL_FILES_PATH=/path/to/excel-files uvx sheetforge-mcp sse
Default endpoint:
http://127.0.0.1:8017/sse
File Path Rules
- In
stdiomode,filepathvalues must be absolute paths. - In
streamable-httpandssemode, relative paths are resolved underEXCEL_FILES_PATH. - Absolute paths are accepted in every transport.
- In
streamable-httpandssemode, the server createsEXCEL_FILES_PATHautomatically if it does not exist.
Environment Variables
| Variable | Default | Used by | Purpose |
|---|---|---|---|
FASTMCP_HOST | 127.0.0.1 | HTTP and SSE | Bind address for the server process |
FASTMCP_PORT | 8017 | HTTP and SSE | Port for the server process |
EXCEL_FILES_PATH | ./excel_files | HTTP and SSE | Base directory for relative workbook paths |
Tooling Overview
The server currently registers 76 MCP tools across these groups:
- workbook overview:
create_workbook,create_worksheet,get_workbook_metadata,profile_workbook,describe_sheet_layout,audit_workbook,plan_workbook_repairs,apply_workbook_repairs,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_tables - data 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_key - worksheet 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_columns - formatting 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_cells - formulas 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_rules - analysis and structure:
create_table,list_charts,find_free_canvas,create_chart,create_chart_from_series,create_pivot_table
For chart authoring, prefer create_chart as the primary entry point:
- use
data_rangefor the simple contiguous-data path - use explicit
seriesplus optionalcategories_rangefor non-contiguous or hand-authored charts - use top-level
widthandheightto control chart size in centimeters; defaults are15 x 7.5 - use
placementwhen you want SheetForge to position the chart relative to worksheet content, a source range, or a named table instead of guessingtarget_cellmanually - use
placement={"relative_to": "free_canvas"}when a busy dashboard needs the first non-overlapping chart slot instead of a simple right/below placement rule - keep
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, 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 revealsdiff_workbooks: compares two workbook files and reports structural changes plus sampled cell-value diffs, which is useful for before/after verification in agent workflowsanalyze_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, now withstart_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, withcompact=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 a worksheet
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_name- normalized field names are ASCII-safe transliterations, so headers like
Näyttökerratbecomenayttokerrat infer_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 inference- truncated pages now include
next_start_row, which you can pass back to the same tool for the next page - non-tabular range reads can also return
continuations.downandcontinuations.rightcursor tokens so agents can continue large 2D windows without recomputing coordinates suggest_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 writes- worksheet-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 scans describe_datasetnow surfacesdata_end_rowandignored_trailing_row_countwhen later non-empty rows are treated as a separate block below a large blank gapquery_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 calls- aggregate 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 stale- token-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 tokens rename_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-free- formatting color inputs accept
RRGGBB,#RRGGBB,AARRGGBB, or#AARRGGBB, so prompts do not need to strip CSS-style#prefixes first audit_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 -> safe mutation -> verification
Start with
list_all_sheetsorprofile_workbook, inspect layout-heavy tabs withdescribe_sheet_layout, runanalyze_range_impactbefore overwriting an important range, then confirm the before/after result withdiff_workbooks. - 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 dev
Run tests:
uv run --extra dev pytest -q
Run lint checks:
uv run --extra dev ruff check src tests
Run the package locally:
uv run sheetforge-mcp stdio
Build distributions locally:
uv build
Release 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. - 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/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 safetymanifest.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/O - agent-friendly responses: consistent JSON envelopes, compact writes, and
dry_runpreviews reduce context waste - workbook introspection:
profile_workbook,list_all_sheets,list_tables, andlist_chartsmake unfamiliar spreadsheets easier to navigate - safer 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 references - layout 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 sizing - practical 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 remotely over HTTP
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 metadata- compact tabular readers still include
structure_token,content_token, andsnapshot_metadata, even when the tabular payload itself is minimized quick_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)now use a temp-file plus atomic replace path and reopen verification instead of trusting in-memory state alone. format_rangesbatches multiple formatting operations into one workbook pass, and now reports per-rangeerrorswithout discarding successful ranges in the same batch.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.
Verwandte Server
Time Server
Get the current time and convert time between different timezones.
Excel MCP Server
Read and write data from Microsoft Excel files. Supports text, formulas, sheet creation, and Windows-only live editing.
Mealie
Interact with your Mealie recipe database to manage and find recipes.
MCP Google Calendar Plus
A server for full Google Calendar management, including creating, updating, and deleting events. Requires Google OAuth2 authentication.
Handwriting OCR
Recognize and extract text from handwritten documents using the Handwriting OCR service.
PM33 MCP Server
AI-native product management MCP server with 17 tools and 11 resources. WSJF backlog optimization, portfolio scheduling, Monte Carlo forecasting, velocity analytics, competitive intelligence, strategic alignment, PRD generation, sprint management. Integrates with Jira, Linear, and Asana.
Weavely AI Forms & Surveys
Build, style, and publish forms & surveys conversationally.
StashDog MCP Server
A server providing natural language tools to manage your StashDog inventory.
Markdownify
Converts various file types and web content, such as PDFs, images, audio, and web pages, into Markdown format.
MCP MD2PDF Server
Convert Markdown documents to PDF with support for Mermaid diagrams.