If a Mastra agent needs spreadsheet math, keep the workbook code in ordinary TypeScript. Mastra should get small tool wrappers: one tool reads a summary range, and one tool writes a validated input cell and returns the formula readback.
That keeps the agent boundary boring. @bilig/headless owns formulas,
serialization, and restore checks; createTool owns the schema and the tool
name the model sees.
git clone https://github.com/proompteng/bilig.git
cd bilig/examples/headless-workpaper
npm install
npm run agent:framework-adapters
The Mastra lane returns tool IDs and a verified write result:
{
"toolIds": ["read-workpaper-summary", "set-workpaper-input-cell"],
"writeResult": {
"editedCell": "Inputs!B3",
"checks": {
"formulasPersisted": true,
"restoredMatchesAfter": true,
"expectedArrChanged": true
}
}
}
The example mirrors the createTool({ id, description, inputSchema,
outputSchema, execute }) shape from the Mastra docs:
export const setWorkPaperInputCell = createTool({
id: 'set-workpaper-input-cell',
description: 'Set one WorkPaper input cell and return formula readback.',
inputSchema: setInputCellInputSchema,
outputSchema: workPaperWriteOutputSchema,
execute: async ({ context }) => setWorkPaperInputCellInWorkbook(context),
})
Use a narrow input schema. For the demo, the write tool accepts only the
Inputs sheet and an A1-style address. That keeps an agent from treating the
workbook like an arbitrary mutation surface.
@bilig/headless WorkPaper construction in your application code.Official Mastra reference: https://mastra.ai/reference/tools/create-tool.
Runnable source:
examples/headless-workpaper/agent-framework-adapters.ts.