MCP Server
The mcp extension exposes the spreadsheet server as a Model Context Protocol server, so AI clients such as Claude Code, Claude Desktop, IDE assistants, or your own agents can read and edit spreadsheets through MCP tools. It speaks the MCP Streamable HTTP transport at /mcp on the same HTTP server the REST API uses.
Enabling it
Declare it in the extensions option. When the api extension is present, /mcp is served on the API's HTTP server; without it, the extension creates its own HTTP server:
const mcp = require('./mcp');
server({
// ...
extensions: { api, mcp },
});
Besides /mcp itself, the extension serves GET /mcp/health, which reports the initialization state and the number of active sessions.
Connecting a client
# Claude Code
claude mcp add --transport http sheets https://sheets.example.com/mcp \
--header "Authorization: Bearer <token>"
// Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"sheets": {
"type": "http",
"url": "https://sheets.example.com/mcp",
"headers": { "Authorization": "Bearer <token>" }
}
}
}
When wiring your own client:
- Sessions. The transport is stateful: the first
initializerequest mints a session and returns anmcp-session-idheader, which must accompany every subsequent request (POSTfor calls,GETfor the notification stream,DELETEto close the session). Idle sessions are closed after 30 minutes by default; set theMCP_SESSION_TIMEOUTenvironment variable (milliseconds) to change this. - Authentication. The
Authorization: Bearer <token>header is read on every tool call and flows into the same hooks as every other request, sobeforeLoad/beforeChangedecide what the agent may do. An MCP client has the permissions of the token it carries. See Login & security. - Browser clients. CORS headers are only sent for origins listed in the
MCP_ALLOWED_ORIGINSenvironment variable (comma-separated). Non-browser MCP clients do not send anOriginheader and are unaffected. Request bodies are limited to 10 MB. - Multi-node deployments. Tool calls address documents by guid; with guid-routed instances, route
/mcptraffic to the right node the same way as REST traffic.
What the tools do
Writes issued through MCP go through the same pipeline as socket and REST edits: the document is loaded through beforeLoad, the change is validated by beforeChange, applied to the live in-memory document, persisted through your adapter and broadcast, so connected clients see the agent's edits in real time.
Every document tool takes the target guid as its first parameter, plus an optional worksheetId (worksheet id or name; the first worksheet is used when omitted).
Document lifecycle
| Tool | Description |
|---|---|
listSpreadsheets |
Documents available to the token's user, served by the list server option |
createSpreadsheet |
Create a new document from a configuration object; returns the new guid |
destroySpreadsheet |
Delete a document |
Reading
| Tool | Description |
|---|---|
getConfig |
Worksheet configuration (columns, dimensions, options); pass spreadsheet: true for the whole document |
getData |
Worksheet data, with options for calculated formula values (processed), the highlighted selection only (highlighted) and filtered rows (includeFilteredRows); empty rows are trimmed from the result |
Writing
| Tool | Description |
|---|---|
setValue |
Set cell values or formulas by coordinates, with an optional force flag for read-only cells |
setData / setRowData / setColumnData |
Bulk data writes |
insertRow / deleteRow / insertColumn / deleteColumn |
Structure changes |
createWorksheet |
Add a worksheet |
setHeader / setColumnOptions / setProperty |
Column titles, column options and cell properties |
setStyle / resetStyle |
Cell styling |
setMedia / deleteMedia |
Charts, images and shapes |
paste |
Paste a 2D block of data starting at the given coordinates |
The read-only tools (getConfig, getData, listSpreadsheets) carry the MCP readOnlyHint annotation, so clients that distinguish safe tools (for auto-approval) can do so; destroySpreadsheet is annotated with destructiveHint.
MCP or REST?
Use MCP when the caller is an AI client that discovers tools dynamically; use the REST API when you are writing conventional integrations. They address the same in-memory documents through the same authorization, so they can be mixed freely.