A side-by-side look at the Bilig and Xlsx Tools MCP MCP servers: transport, auth, tools, quality signals, and the config to install either one in Claude, Cursor, Windsurf or VS Code.
Verdict: choose Bilig for workplace & productivity work over a hosted endpoint; choose Xlsx Tools MCP for workplace & productivity as a local process. You can also run both side by side in one mcpServers block.
list_sheets, read_range, read_cell.restore_backup, list_configured_files, list_sheets.Rows where the two servers differ are marked.
| Spec | ||
|---|---|---|
| Category | Workplace & Productivity | Workplace & Productivity |
| Quality signal | 63/100 · Good | 59/100 · Good |
| Install command | Confirmed | Confirmed |
| Transport | Remote HTTP/SSE | Local subprocess (stdio) |
| Auth | No auth required | Not declared |
| Pricing | Free | Not declared |
| Required env vars | None listed | None listed |
| Verified owner | Community listing | Community listing |
| GitHub stars | 35 | 3 |
| Directory activity | 2 views 0 installs 0 upvotes | 2 views 0 installs 0 upvotes |
| Tools | 8 | 29 |
| Full listing | View Bilig | View Xlsx Tools MCP |
list_sheetsDiscover sheet names and used dimensions before reading or editing a WorkPaper. Returns metadata only; use read_range or read_cell for values.read_rangeRead calculated values plus serialized formulas/inputs for an A1 range. Use for audit readback after edits; use read_cell for one address.read_cellRead one cell with calculated value, display text, formula text, formula diagnostics, and serialized content. Use after set_cell_contents to verify readback.set_cell_contentsWrite raw content to one cell and recalculate dependents in memory only. Start with --writable when the edit should persist to JSON.set_cell_contents_and_readbackWrite raw content to one cell, recalculate dependents, read a dependent range in the same tool call, and return persistence proof. Use this for stateless MCP clients such as hosted Open WebUI integrations.get_cell_display_valueReturn the formatted display string for one cell. Use when an agent needs what a user would see, not the raw numeric value.export_workpaper_documentExport the current WorkPaper JSON document for persistence, review, or handoff to another agent. Does not write files by itself.validate_formulaValidate formula syntax with the WorkPaper parser before writing it to a cell. This checks syntax only; use set_cell_contents plus readback to evaluate.restore_backupRestore a backup file over a target workbook atomically.
Args:
backup_path: Path to the .bak file to restore from.
target_path: Path to the target .xlsx/.xlsm file to overwrite.
list_configured_filesList files preloaded at server startup (via the XLSX_MCP_FILES env var).
Call this first if unsure which files are available — every other tool's `path`
argument accepts these names directly (or can be omitted if only one is configured),
no filesystem search needed.
list_sheetsList every sheet in a workbook with its approximate row/column counts.
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
get_workbook_infoGet workbook-level metadata: sheets, exact dimensions, active sheet, defined names.
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
read_sheetRead cell values from a sheet.
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
sheet: Sheet name.
cell_range: Optional A1-style range (e.g. "B2:F20"). Omit to read the full used area.
max_rows: Optional cap on the number of rows returned, to bound response size for large sheets.
offset_row: Skip a number of data rows (0-indexed from first data row).
format: "array" (default 2D list), "records" (list of dicts, first row as keys), or "markdown" (table string).
get_cellGet full detail for a single cell: value, formula, number format, font, fill, merge, comment.
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
sheet: Sheet name.
cell: Cell reference, e.g. "C5".
search_workbookSearch cell values across one or all sheets for a substring match.
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
query: Substring to search for.
sheet: Restrict the search to one sheet; omit to search every sheet.
match_case: Case-sensitive match when True.
limit: Optional cap on the number of matches returned, to bound response size for large sheets.
aggregate_sheetGroup and aggregate sheet data with pandas (e.g. sum sales by region).
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
sheet: Sheet name.
group_by: Column names to group by (taken from the header row).
agg: Mapping of column name to aggregation function, e.g. {"amount": "sum"}.
cell_range: Optional A1-style range to read before aggregating.
has_header: Whether the first row of the range holds column names.
create_workbookCreate a new .xlsx workbook.
Args:
path: Path for the new file. New files aren't preloaded, so this must be a real path.
sheets: Sheet names to create (defaults to a single "Sheet1").
overwrite: Replace an existing file at path when True.
write_cellsWrite values and/or formulas into specific cells, then recalculate the workbook.
Set `recalculate=False` to skip the LibreOffice recompute (e.g. for structurally
complex workbooks you don't want round-tripped).
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
sheet: Sheet name.
cells: List of {"cell": "A1", "value": ...} or {"cell": "B1", "formula": "=A1*2"}.
create_sheet_if_missing: Create the sheet first if it doesn't exist yet.
recalculate: Run the LibreOffice recompute pass after saving.
Returns:
Write result including `errors_found` — any Excel error values produced by recalculation.
append_rowsAppend rows after the last used row of a sheet, then recalculate the workbook.
Set `recalculate=False` to skip the LibreOffice recompute (e.g. for structurally
complex workbooks you don't want round-tripped).
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
sheet: Sheet name.
rows: List of rows, each a list of cell values in column order.
create_sheet_if_missing: Create the sheet first if it doesn't exist yet.
recalculate: Run the LibreOffice recompute pass after saving.
create_sheetAdd a new empty sheet to an existing workbook.
Args:
path: Path to the .xlsx file, or the name of a preloaded file. Omit if only
one file is configured.
sheet: Name for the new sheet.
index: Zero-based position to insert at; omit to append at the end.
Paste either block (or both) into your client config, e.g. claude_desktop_config.json or ~/.cursor/mcp.json. We only show a config when the install command is confirmed.
{
"mcpServers": {
"proompteng-bilig": {
"url": "https://bilig.proompteng.ai/mcp"
}
}
}
{
"mcpServers": {
"xlsx-tools-mcp": {
"command": "uvx",
"args": [
"xlsx-tools-mcp"
]
}
}
}