Excel MCP server for reading, writing, formatting, and automating .xlsx workbooks with Model Context Protocol and openpyxl
Project description
SheetForge MCP
SheetForge MCP is an Excel MCP server for .xlsx automation over the Model Context Protocol. It lets AI agents, MCP clients, and automation workflows read, write, search, format, chart, and restructure Excel workbooks with Python and openpyxl, without launching Microsoft Excel or LibreOffice.
If you are looking for an MCP server for Excel, spreadsheet automation, workbook inspection, Excel report generation, or .xlsx editing from AI tools, SheetForge MCP is built for that workflow.
Package name: sheetforge-mcp
CLI command: sheetforge-mcp
Current release: 0.4.2
Excel MCP Server Features
- workbook creation and metadata
- worksheet creation, renaming, copying, deletion, and visibility
- structured reads, compact table reads, 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 49 MCP tools across these groups:
- workbook overview:
create_workbook,create_worksheet,get_workbook_metadata,profile_workbook,list_named_ranges,list_all_sheets,list_tables - data access:
quick_read,read_excel_table,read_data_from_excel,read_excel_as_table,search_in_sheet,write_data_to_excel,append_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,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,validate_excel_range,get_data_validation_info - analysis and structure:
create_table,list_charts,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 - keep
create_chart_from_seriesfor backward compatibility or existing prompts that already rely on it
The most agent-friendly read tools are:
profile_workbook: one-call inventory for sheets, tables, charts, named ranges, and key layout/protection state, including chartoccupied_rangefor grid-anchored worksheet chartsquick_read: single-call compact table read that auto-selects the first sheet when neededread_excel_table: read a native Excel table bytable_namewithout guessing worksheet boundslist_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 payloadsearch_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_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 rows
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. - 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 - 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.
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_excel_as_table(..., compact=True)returns onlyheadersandrowsunless truncation metadata is needed.quick_read,read_excel_as_table, andread_excel_tablecan now returnrecordsplus inferredschemahints when you opt intorow_mode="objects"andinfer_schema=True.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. 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.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sheetforge_mcp-0.4.2.tar.gz.
File metadata
- Download URL: sheetforge_mcp-0.4.2.tar.gz
- Upload date:
- Size: 49.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
438ee32100e11dd9b1c9911d460e24ae95dbce1c18ce2829f9782bdfadf834ae
|
|
| MD5 |
12e24e66e16b0a830e2f7a945b9b0bbd
|
|
| BLAKE2b-256 |
aaf067ec28d37ecd896584014aa02e5897113853919995aef0baf4706c004d3b
|
Provenance
The following attestation bundles were made for sheetforge_mcp-0.4.2.tar.gz:
Publisher:
publish.yml on iHeldan/sheetforge-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sheetforge_mcp-0.4.2.tar.gz -
Subject digest:
438ee32100e11dd9b1c9911d460e24ae95dbce1c18ce2829f9782bdfadf834ae - Sigstore transparency entry: 1278417413
- Sigstore integration time:
-
Permalink:
iHeldan/sheetforge-mcp@3b3c906cd240c9722b22f62f0259159dc9d25a12 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/iHeldan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3b3c906cd240c9722b22f62f0259159dc9d25a12 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file sheetforge_mcp-0.4.2-py3-none-any.whl.
File metadata
- Download URL: sheetforge_mcp-0.4.2-py3-none-any.whl
- Upload date:
- Size: 57.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2cc2e1606eeec56c43b890403286dff532bbb93efb1e25e64168958aa563a75f
|
|
| MD5 |
3ac7833e15adc708704b22199cdbb30c
|
|
| BLAKE2b-256 |
9adac9b793e47d200cabd50f5a03d0ff74efc50e965868d62facbe6507cb5acd
|
Provenance
The following attestation bundles were made for sheetforge_mcp-0.4.2-py3-none-any.whl:
Publisher:
publish.yml on iHeldan/sheetforge-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sheetforge_mcp-0.4.2-py3-none-any.whl -
Subject digest:
2cc2e1606eeec56c43b890403286dff532bbb93efb1e25e64168958aa563a75f - Sigstore transparency entry: 1278417471
- Sigstore integration time:
-
Permalink:
iHeldan/sheetforge-mcp@3b3c906cd240c9722b22f62f0259159dc9d25a12 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/iHeldan
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@3b3c906cd240c9722b22f62f0259159dc9d25a12 -
Trigger Event:
workflow_dispatch
-
Statement type: