{
  "$schema": "https://modelcontextprotocol.io/schemas/server-card/v1.0",
  "version": "1.0",
  "protocolVersion": "2025-11-25",
  "serverInfo": {
    "name": "Bilig WorkPaper",
    "version": "0.164.11",
    "description": "Formula-backed WorkPaper MCP tools for workbook reads, input edits, recalculation, formula validation, and JSON persistence."
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/proompteng/bilig"
  },
  "homepage": "https://proompteng.github.io/bilig/",
  "license": "MIT",
  "authentication": {
    "required": false,
    "schemes": []
  },
  "transport": {
    "type": "stdio",
    "command": "npm",
    "args": [
      "exec",
      "--package",
      "@bilig/workpaper@latest",
      "--",
      "bilig-workpaper-mcp",
      "--workpaper",
      "./pricing.workpaper.json",
      "--init-demo-workpaper",
      "--writable"
    ]
  },
  "transports": [
    {
      "type": "streamable-http",
      "url": "https://bilig.proompteng.ai/mcp",
      "protocolVersion": "2025-11-25",
      "stateless": true
    },
    {
      "type": "stdio",
      "command": "npm",
      "args": [
        "exec",
        "--package",
        "@bilig/workpaper@latest",
        "--",
        "bilig-workpaper-mcp",
        "--workpaper",
        "./pricing.workpaper.json",
        "--init-demo-workpaper",
        "--writable"
      ]
    }
  ],
  "capabilities": {
    "tools": true,
    "resources": true,
    "prompts": true
  },
  "tools": [
    {
      "name": "list_sheets",
      "title": "List WorkPaper Sheets",
      "description": "Discover sheet names and used dimensions before reading or editing a WorkPaper. Returns metadata only; use read_range or read_cell for values.",
      "inputSchema": {
        "type": "object",
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "required": ["writable", "sheets"],
        "properties": {
          "sourcePath": {
            "type": "string",
            "description": "Absolute JSON file path when the server was started with --workpaper."
          },
          "writable": {
            "type": "boolean",
            "description": "Whether set_cell_contents persists edits back to the source JSON file."
          },
          "sheets": {
            "type": "array",
            "description": "Sheet names, ids, and current used dimensions.",
            "items": {
              "type": "object",
              "required": ["id", "name", "dimensions"],
              "properties": {
                "id": {
                  "type": "number",
                  "description": "Stable numeric sheet id inside the WorkPaper engine."
                },
                "name": {
                  "type": "string",
                  "description": "Sheet name to pass as sheetName in read and write calls."
                },
                "dimensions": {
                  "type": "object",
                  "description": "Current used rows and columns for the sheet.",
                  "properties": {
                    "rowCount": {
                      "type": "number",
                      "description": "Used row count for the sheet."
                    },
                    "columnCount": {
                      "type": "number",
                      "description": "Used column count for the sheet."
                    }
                  },
                  "additionalProperties": false
                }
              },
              "additionalProperties": false
            }
          }
        },
        "additionalProperties": false
      },
      "annotations": {
        "title": "List WorkPaper Sheets",
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "read_range",
      "title": "Read WorkPaper Range",
      "description": "Read calculated values plus serialized formulas/inputs for an A1 range. Use for audit readback after edits; use read_cell for one address.",
      "inputSchema": {
        "type": "object",
        "required": ["range"],
        "properties": {
          "range": {
            "type": "string",
            "description": "A1 range such as Summary!A1:B5. If omitted from the range, pass sheetName separately."
          },
          "sheetName": {
            "type": "string",
            "description": "Default sheet name when range omits a sheet name, for example Summary."
          }
        },
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "required": ["range", "values", "serialized"],
        "properties": {
          "range": {
            "type": "string",
            "description": "Canonical A1 range including the sheet name."
          },
          "values": {
            "type": "array",
            "description": "Two-dimensional array of evaluated cell values."
          },
          "serialized": {
            "type": "array",
            "description": "Two-dimensional array of raw serialized cell contents, including formulas."
          }
        },
        "additionalProperties": false
      },
      "annotations": {
        "title": "Read WorkPaper Range",
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "read_cell",
      "title": "Read WorkPaper Cell",
      "description": "Read one cell with calculated value, display text, formula text, and serialized content. Use after set_cell_contents to verify readback.",
      "inputSchema": {
        "type": "object",
        "required": ["sheetName", "address"],
        "properties": {
          "sheetName": {
            "type": "string",
            "description": "Existing sheet name, for example Inputs."
          },
          "address": {
            "type": "string",
            "description": "Single A1 cell address such as B3. Ranges are not accepted."
          }
        },
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "required": ["address", "value", "serialized", "formula", "displayValue"],
        "properties": {
          "address": {
            "type": "string",
            "description": "Canonical sheet-qualified A1 address."
          },
          "value": {
            "description": "Calculated cell value."
          },
          "serialized": {
            "type": ["string", "number", "boolean", "null"],
            "description": "Raw serialized cell content, preserving formulas."
          },
          "formula": {
            "type": ["string", "null"],
            "description": "Formula text without losing the original calculated value context, or null for literal cells."
          },
          "displayValue": {
            "type": "string",
            "description": "Formatted value as a user would see it."
          }
        },
        "additionalProperties": false
      },
      "annotations": {
        "title": "Read WorkPaper Cell",
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "set_cell_contents",
      "title": "Set WorkPaper Cell Contents",
      "description": "Write raw content to one cell, recalculate dependents, persist the WorkPaper JSON file when writable, and return before/after/restored readback.",
      "inputSchema": {
        "type": "object",
        "required": ["sheetName", "address", "value"],
        "properties": {
          "sheetName": {
            "type": "string",
            "description": "Existing sheet name, for example Inputs."
          },
          "address": {
            "type": "string",
            "description": "Single A1 cell address such as B3. Ranges are not accepted."
          },
          "value": {
            "type": ["string", "number", "boolean", "null"],
            "description": "Raw cell content. Formula strings must start with =."
          }
        },
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "required": ["editedCell", "before", "after", "restored", "persistence", "checks"],
        "properties": {
          "editedCell": {
            "type": "string",
            "description": "Canonical sheet-qualified address that was edited."
          },
          "before": {
            "type": "object",
            "description": "Cell readback before the edit.",
            "required": ["address", "value", "serialized", "formula", "displayValue"],
            "properties": {
              "address": {
                "type": "string",
                "description": "Canonical sheet-qualified A1 address."
              },
              "value": {
                "description": "Calculated cell value."
              },
              "serialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content, preserving formulas."
              },
              "formula": {
                "type": ["string", "null"],
                "description": "Formula text without losing the original calculated value context, or null for literal cells."
              },
              "displayValue": {
                "type": "string",
                "description": "Formatted value as a user would see it."
              }
            },
            "additionalProperties": false
          },
          "after": {
            "type": "object",
            "description": "Cell readback after recalculation.",
            "required": ["address", "value", "serialized", "formula", "displayValue"],
            "properties": {
              "address": {
                "type": "string",
                "description": "Canonical sheet-qualified A1 address."
              },
              "value": {
                "description": "Calculated cell value."
              },
              "serialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content, preserving formulas."
              },
              "formula": {
                "type": ["string", "null"],
                "description": "Formula text without losing the original calculated value context, or null for literal cells."
              },
              "displayValue": {
                "type": "string",
                "description": "Formatted value as a user would see it."
              }
            },
            "additionalProperties": false
          },
          "restored": {
            "type": "object",
            "description": "Cell readback after exporting and restoring WorkPaper JSON.",
            "required": ["address", "value", "serialized", "formula", "displayValue"],
            "properties": {
              "address": {
                "type": "string",
                "description": "Canonical sheet-qualified A1 address."
              },
              "value": {
                "description": "Calculated cell value."
              },
              "serialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content, preserving formulas."
              },
              "formula": {
                "type": ["string", "null"],
                "description": "Formula text without losing the original calculated value context, or null for literal cells."
              },
              "displayValue": {
                "type": "string",
                "description": "Formatted value as a user would see it."
              }
            },
            "additionalProperties": false
          },
          "persistence": {
            "type": "object",
            "description": "Persistence result for the WorkPaper JSON document.",
            "required": ["persisted", "serializedBytes"],
            "properties": {
              "persisted": {
                "type": "boolean",
                "description": "True when the server wrote the updated WorkPaper JSON file."
              },
              "path": {
                "type": "string",
                "description": "Absolute JSON file path written by the server when writable."
              },
              "serializedBytes": {
                "type": "number",
                "description": "UTF-8 byte length of the serialized WorkPaper document."
              }
            },
            "additionalProperties": false
          },
          "checks": {
            "type": "object",
            "description": "Boolean receipt for persisted state and restored readback.",
            "required": ["persisted", "restoredMatchesAfter", "previousSerialized", "newSerialized"],
            "properties": {
              "persisted": {
                "type": "boolean",
                "description": "Echo of whether the edit was persisted to disk."
              },
              "restoredMatchesAfter": {
                "type": "boolean",
                "description": "True when exported and re-imported JSON preserves the edited cell readback."
              },
              "previousSerialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content before the edit."
              },
              "newSerialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content after the edit."
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "annotations": {
        "title": "Set WorkPaper Cell Contents",
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "set_cell_contents_and_readback",
      "title": "Set WorkPaper Cell Contents And Read Back",
      "description": "Write 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.",
      "inputSchema": {
        "type": "object",
        "required": ["sheetName", "address", "value", "readbackRange"],
        "properties": {
          "sheetName": {
            "type": "string",
            "description": "Existing sheet name for the cell to edit, for example Inputs."
          },
          "address": {
            "type": "string",
            "description": "Single A1 cell address to edit, such as B3. Ranges are not accepted."
          },
          "value": {
            "type": "string",
            "description": "Raw cell content. Formula strings must start with =. Strict MCP hosts require a single parameter type, so pass evaluated numbers/booleans as formulas such as =0.4 or =TRUE()."
          },
          "readbackRange": {
            "type": "string",
            "description": "Dependent A1 range to read before and after the edit, for example Summary!A1:B5."
          },
          "readbackSheetName": {
            "type": "string",
            "description": "Default sheet name when readbackRange omits a sheet name."
          }
        },
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "required": [
          "editedCell",
          "readbackRange",
          "before",
          "after",
          "beforeReadback",
          "afterReadback",
          "restoredReadback",
          "persistence",
          "checks"
        ],
        "properties": {
          "editedCell": {
            "type": "string",
            "description": "Canonical sheet-qualified address that was edited."
          },
          "readbackRange": {
            "type": "string",
            "description": "Canonical sheet-qualified range read before and after the edit."
          },
          "before": {
            "type": "object",
            "description": "Edited cell before the edit.",
            "required": ["address", "value", "serialized", "formula", "displayValue"],
            "properties": {
              "address": {
                "type": "string",
                "description": "Canonical sheet-qualified A1 address."
              },
              "value": {
                "description": "Calculated cell value."
              },
              "serialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content, preserving formulas."
              },
              "formula": {
                "type": ["string", "null"],
                "description": "Formula text without losing the original calculated value context, or null for literal cells."
              },
              "displayValue": {
                "type": "string",
                "description": "Formatted value as a user would see it."
              }
            },
            "additionalProperties": false
          },
          "after": {
            "type": "object",
            "description": "Edited cell after recalculation.",
            "required": ["address", "value", "serialized", "formula", "displayValue"],
            "properties": {
              "address": {
                "type": "string",
                "description": "Canonical sheet-qualified A1 address."
              },
              "value": {
                "description": "Calculated cell value."
              },
              "serialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content, preserving formulas."
              },
              "formula": {
                "type": ["string", "null"],
                "description": "Formula text without losing the original calculated value context, or null for literal cells."
              },
              "displayValue": {
                "type": "string",
                "description": "Formatted value as a user would see it."
              }
            },
            "additionalProperties": false
          },
          "beforeReadback": {
            "type": "object",
            "description": "Dependent range before the edit.",
            "required": ["range", "values", "serialized"],
            "properties": {
              "range": {
                "type": "string",
                "description": "Canonical A1 range including the sheet name."
              },
              "values": {
                "type": "array",
                "description": "Two-dimensional array of evaluated cell values."
              },
              "serialized": {
                "type": "array",
                "description": "Two-dimensional array of raw serialized cell contents, including formulas."
              }
            },
            "additionalProperties": false
          },
          "afterReadback": {
            "type": "object",
            "description": "Dependent range after recalculation.",
            "required": ["range", "values", "serialized"],
            "properties": {
              "range": {
                "type": "string",
                "description": "Canonical A1 range including the sheet name."
              },
              "values": {
                "type": "array",
                "description": "Two-dimensional array of evaluated cell values."
              },
              "serialized": {
                "type": "array",
                "description": "Two-dimensional array of raw serialized cell contents, including formulas."
              }
            },
            "additionalProperties": false
          },
          "restoredReadback": {
            "type": "object",
            "description": "Dependent range after exporting and restoring WorkPaper JSON.",
            "required": ["range", "values", "serialized"],
            "properties": {
              "range": {
                "type": "string",
                "description": "Canonical A1 range including the sheet name."
              },
              "values": {
                "type": "array",
                "description": "Two-dimensional array of evaluated cell values."
              },
              "serialized": {
                "type": "array",
                "description": "Two-dimensional array of raw serialized cell contents, including formulas."
              }
            },
            "additionalProperties": false
          },
          "persistence": {
            "type": "object",
            "description": "Persistence result for the WorkPaper JSON document.",
            "required": ["persisted", "serializedBytes"],
            "properties": {
              "persisted": {
                "type": "boolean",
                "description": "True when the server wrote the updated WorkPaper JSON file."
              },
              "path": {
                "type": "string",
                "description": "Absolute JSON file path written by the server when writable."
              },
              "serializedBytes": {
                "type": "number",
                "description": "UTF-8 byte length of the serialized WorkPaper document."
              }
            },
            "additionalProperties": false
          },
          "checks": {
            "type": "object",
            "description": "Boolean receipt for computed readback and restored state.",
            "required": ["persisted", "readbackChanged", "restoredReadbackMatchesAfter", "previousSerialized", "newSerialized"],
            "properties": {
              "persisted": {
                "type": "boolean",
                "description": "Echo of whether the edit was persisted to disk."
              },
              "readbackChanged": {
                "type": "boolean",
                "description": "True when dependent readback values differ after the edit."
              },
              "restoredReadbackMatchesAfter": {
                "type": "boolean",
                "description": "True when exported and re-imported JSON preserves the dependent readback range."
              },
              "previousSerialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content before the edit."
              },
              "newSerialized": {
                "type": ["string", "number", "boolean", "null"],
                "description": "Raw serialized cell content after the edit."
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "annotations": {
        "title": "Set WorkPaper Cell Contents And Read Back",
        "readOnlyHint": false,
        "destructiveHint": true,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "get_cell_display_value",
      "title": "Get WorkPaper Cell Display Value",
      "description": "Return the formatted display string for one cell. Use when an agent needs what a user would see, not the raw numeric value.",
      "inputSchema": {
        "type": "object",
        "required": ["sheetName", "address"],
        "properties": {
          "sheetName": {
            "type": "string",
            "description": "Existing sheet name, for example Summary."
          },
          "address": {
            "type": "string",
            "description": "Single A1 cell address such as B2. Ranges are not accepted."
          }
        },
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "required": ["address", "displayValue"],
        "properties": {
          "address": {
            "type": "string",
            "description": "Canonical sheet-qualified A1 address."
          },
          "displayValue": {
            "type": "string",
            "description": "Formatted value string suitable for human readback."
          }
        },
        "additionalProperties": false
      },
      "annotations": {
        "title": "Get WorkPaper Cell Display Value",
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "export_workpaper_document",
      "title": "Export WorkPaper Document",
      "description": "Export the current WorkPaper JSON document for persistence, review, or handoff to another agent. Does not write files by itself.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "includeConfig": {
            "type": "boolean",
            "default": true,
            "description": "Include workbook configuration metadata in the exported JSON. Defaults to true."
          }
        },
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "required": ["document", "serializedBytes"],
        "properties": {
          "sourcePath": {
            "type": "string",
            "description": "Absolute JSON file path when the server was started with --workpaper."
          },
          "document": {
            "type": "object",
            "description": "Persisted WorkPaper JSON document.",
            "additionalProperties": false
          },
          "serializedBytes": {
            "type": "number",
            "description": "UTF-8 byte length of the serialized WorkPaper document."
          }
        },
        "additionalProperties": false
      },
      "annotations": {
        "title": "Export WorkPaper Document",
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    },
    {
      "name": "validate_formula",
      "title": "Validate WorkPaper Formula",
      "description": "Validate formula syntax with the WorkPaper parser before writing it to a cell. This checks syntax only; use set_cell_contents plus readback to evaluate.",
      "inputSchema": {
        "type": "object",
        "required": ["formula"],
        "properties": {
          "formula": {
            "type": "string",
            "description": "Formula string including the leading =, for example =SUM(Inputs!B2:B4)."
          }
        },
        "additionalProperties": false
      },
      "outputSchema": {
        "type": "object",
        "required": ["formula", "valid"],
        "properties": {
          "formula": {
            "type": "string",
            "description": "Formula string that was validated."
          },
          "valid": {
            "type": "boolean",
            "description": "True when the WorkPaper formula parser accepts the formula syntax."
          }
        },
        "additionalProperties": false
      },
      "annotations": {
        "title": "Validate WorkPaper Formula",
        "readOnlyHint": true,
        "destructiveHint": false,
        "idempotentHint": true,
        "openWorldHint": false
      }
    }
  ],
  "resources": [
    {
      "uri": "bilig://workpaper/manifest",
      "name": "workpaper_manifest",
      "title": "WorkPaper MCP Manifest",
      "description": "Live manifest of the current WorkPaper file, available tools, prompts, resources, and verification contract.",
      "mimeType": "application/json"
    },
    {
      "uri": "bilig://workpaper/agent-handoff",
      "name": "workpaper_agent_handoff",
      "title": "WorkPaper Agent Handoff",
      "description": "Compact instructions for agents that need to edit workbook formulas without spreadsheet UI automation.",
      "mimeType": "text/markdown"
    },
    {
      "uri": "bilig://workpaper/sheets",
      "name": "workpaper_sheets",
      "title": "WorkPaper Sheets",
      "description": "Current sheet names and used dimensions for the loaded WorkPaper document.",
      "mimeType": "application/json"
    },
    {
      "uri": "bilig://workpaper/current-document",
      "name": "workpaper_current_document",
      "title": "Current WorkPaper Document",
      "description": "Current persisted WorkPaper JSON document as exported from the in-memory engine.",
      "mimeType": "application/json"
    }
  ],
  "prompts": [
    {
      "name": "edit_and_verify_workpaper",
      "title": "Edit And Verify WorkPaper",
      "description": "Guide an agent through a safe WorkPaper edit: read before, validate target, write one cell, read computed output, export JSON, and report proof.",
      "arguments": [
        {
          "name": "task",
          "title": "Task",
          "description": "Human-readable workbook edit request."
        },
        {
          "name": "target_cell",
          "title": "Target Cell",
          "description": "Optional sheet-qualified A1 target such as Inputs!B3."
        },
        {
          "name": "output_range",
          "title": "Output Range",
          "description": "Optional dependent output range to read after recalculation, such as Summary!A1:B5."
        }
      ]
    },
    {
      "name": "debug_workpaper_formula",
      "title": "Debug WorkPaper Formula",
      "description": "Guide an agent through formula validation and readback when a WorkPaper formula or dependent output looks wrong.",
      "arguments": [
        {
          "name": "formula",
          "title": "Formula",
          "description": "Optional formula text, including the leading =."
        },
        {
          "name": "cell",
          "title": "Cell",
          "description": "Optional sheet-qualified A1 cell that contains or should contain the formula."
        },
        {
          "name": "symptom",
          "title": "Symptom",
          "description": "Optional description of the wrong value, parse failure, or behavior being debugged."
        }
      ]
    }
  ]
}
