Formula-backed WorkPaper stdio MCP server for workbook reads, input edits, recalculation, formula validation, and JSON persistence.
The Bilig WorkPaper MCP server provides a focused, well-scoped toolkit for spreadsheet operations with generally solid schema definitions and clear descriptions. All four tools have explicit input schemas with proper JSON structure, type declarations, and parameter descriptions. Tool names follow clear verb_noun patterns (list_, read_, set_). Descriptions are action-oriented and explain WHAT (reads/writes cells) and WHEN (after edits, for audit readback). However, there are gaps in parameter-level constraint documentation, missing enum declarations for constrained inputs, and no documented return/output schemas. Error handling and recovery guidance is absent from descriptions. Tool composition is appropriate, each tool has a single responsibility with clear chaining potential (list → read → set → read for audit). Security consideration noted: the set_cell_contents tool is properly flagged as WRITE risk. Overall, this is a solid B-range implementation with above-average naming and schema completeness, but missing output documentation and recovery guidance that would elevate it to A range.
Discover sheet names and used dimensions before reading or editing a WorkPaper. Returns metadata only; use read_range or read_cell for values.
Read one cell with calculated value, display text, formula text, and serialized content. Use after set_cell_contents to verify readback.
Read calculated values plus serialized formulas/inputs for an A1 range. Use for audit readback after edits; use read_cell for one address.
Write raw content to one cell, recalculate dependents, persist the WorkPaper JSON file when writable, and return before/after/restored readback.
Output schemas not documented for any tool. LLMs cannot plan downstream calls or extract needed fields when response structure is opaque.
No error handling or recovery guidance in tool descriptions. If set_cell_contents fails (invalid formula, locked cell, type mismatch), LLM has no guidance on what to do next.
Missing input validation constraints. 'range' parameter accepts free-form strings with no enum or pattern constraint. LLM could pass invalid A1 ranges (e.g., 'Summary!A1:A', 'BadRange123', 'cell A1') without validation guidance.
Parameter format examples in descriptions should be replaced with formal constraints. 'A1 cell address such as B3' is informal; a pattern constraint or enum would be machine-parseable and prevent LLM hallucination of formats like 'B03' or 'b3'.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 71 | 2026-07-28+ | v2 |
No field chaining documentation. If list_sheets returns a sheet name, is it safe to pass directly to read_range? If read_cell returns a formula, can it be passed directly to set_cell_contents? Undocumented field names/types break tool composition chains.
sheetName parameter accepts free-form strings with no validation. LLM could pass typos or non-existent sheets. Contrast with list_sheets which discovers valid names, tie them together: 'Must be a sheet name from list_sheets() response.'