Server Agent: Self-Hosted AI Assistant for Spreadsheets

The server agent is a self-hosted AI assistant for spreadsheets that does not export your data to a chat window. It works on the live spreadsheet, with tools, under the rules your users already follow. Every change it makes reaches everyone on the document.

icon jspreadsheet

Published on October 5, 2026

Introducing

@jspreadsheet/server-agent adds an AI chat to Jspreadsheet Server. A user types a request: add a total per region, highlight the overdue tasks, chart Q2 by product. The agent reads the document, picks the steps, and calls spreadsheet tools until the job is done, streaming its answer as it goes.

The server owns the live document, so the agent never works on a copy. Its edits take the path a person's edits take: validated by your hooks, applied to the document, persisted by your adapter, broadcast to every connected browser.

An AI assistant editing a Jspreadsheet worksheet

How it works

The document is the context

Every prompt carries a description of the open workbook: worksheets, columns, data, formulas. The model answers about the numbers in the document, not an export from an hour ago. The part of the context that does not change between turns is cached, so a long conversation does not pay for the document on every message.

Edits go through spreadsheet tools

The agent changes the spreadsheet through more than 20 tools that map onto the Jspreadsheet API:

  • Data: setValue, setData, setRowData, setColumnData, paste, and reading with getData and getConfig.
  • Structure: insertRow, deleteRow, insertColumn, deleteColumn, createWorksheet, setHeader, setColumnProperties, setCellProperties.
  • Presentation: setStyle, resetStyle, setFilter, and setMedia / deleteMedia for charts, images and shapes.
  • History: undo and redo.

Formulas stay formulas. Ask for a total and the cell holds =SUM(B2:C2), not a number that goes stale.

Attachments

Users attach files to a message. Spreadsheets are read with SheetJS, PDFs become text, and images reach the model on demand through viewImage. "Put the table from this screenshot into Sheet2" works.

Built for production

A model open to your users is a cost decision as much as a feature. The agent leaves every policy to you, through three hooks:

  • allow(guid, auth, request) runs before a prompt reaches the model. Return false, or a message, and the request ends with HTTP 429 before anything is spent. The request carries the caller's address, the prompt and the size of the attachments.
  • usage.set(guid, usage, auth, request) receives the token count of every model call: input, output, cache reads, cache writes.
  • prompt stores the conversations, in sessions, in whatever store you run.

Quotas are a few lines: count tokens per user or per address in usage.set, refuse in allow once the daily budget is gone. The package README has a Redis example with a per-address limit, a site-wide budget and a rate limit.

const agent = require('@jspreadsheet/server-agent');

agent({
    allow: async (guid, auth, request) => await quota.check(request.ip),
    usage: { set: async (guid, usage, auth, request) => quota.add(request.ip, usage) },
});

server({
    // ...
    extensions: { api, agent },
});

The model is a setting. CLAUDE_MODEL=claude-haiku-4-5 for a fast, cheap assistant on a public page; a larger model for heavier analysis.

Where you see it

The Intrasheets assistant is a client of the agent: a chat pane next to the workbook, with sessions, attachments and streamed answers. Your application can call the same route, POST /api/<guid>/prompt, and render the stream its own way.

For AI clients outside your application, Claude Code or an IDE assistant, the MCP server exposes the same documents under the same rules through the Model Context Protocol.

Useful links

Server Agent documentation
AI with Jspreadsheet Server
Intrasheets demo