cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / docs / agents / mcp.md
mcp.md 10.7K rendered
1---2title: "MCP server"3sidebar_position: 24---56# MCP server78`012 mcp` is a [Model Context Protocol](https://modelcontextprotocol.io)9server over standard input and output, so any MCP host (Claude Code,10Codex, Claude Desktop, ChatGPT, editors) can read and change the11workbooks in the folders open to it. One server works on every12workbook: each tool takes the workbook's `path`. It is the same code as13[the commands](README.md#with-a-shell): reads are `012 describe` and14`012 get`, and every write is typed through the checks `012 set` makes,15as one change, saved atomically at once.1617```mermaid18flowchart LR19 host[MCP host] -- "stdio: tools with a path, resources, prompts" --> server["012 mcp"]20 server -- "open, read" --> file[("budget.012, q3/plan.012, data.csv")]21 server -- "one change, Batch, atomic save" --> file22 person["012 budget.012, 012 set, git"] --> file23```2425A file is opened afresh for every call, so what the screen, a script26or git saved meanwhile is what the next call sees. To work in a running27012 instead, on the workbook on your screen with its changes as28suggestions, attach with `012 mcp --attach`: [Live mode](live.md).2930## Adding it to a host3132`012 agent --install-mcp` writes the entry that starts this 012, by its33absolute path and with no workbook, into the host's configuration:3435```sh36012 agent --install-mcp claude-code # Claude Code: ~/.claude.json, as claude mcp add --scope user does37012 agent --install-mcp codex # Codex: [mcp_servers.012] in ~/.codex/config.toml38012 agent --install-mcp claude-desktop # Claude Desktop: claude_desktop_config.json39012 agent --install-mcp codex --print # show the entry, write nothing40012 agent --install-mcp claude-desktop --root ~/Documents # open these folders to it41```4243The file is copied beside itself (`config.toml.bak-20260929-150405`)44before it changes, the host's other servers and settings stay as they45were, and running it again when the entry is there changes nothing.46It names other entries that start 012, such as one made earlier for a47single workbook, which the new entry replaces. Restart the host to48start the server; install again after moving 012.4950Other hosts take the command and arguments `--print` shows. A file51named after `mcp` (`012 mcp budget.012`) is the workbook of tools52called without a path, open wherever it is.5354## Which files it opens5556A `path` is confined to the folders the host shares as its roots57(Claude Code shares the project's), or when it shares none, to the58folders `--root` names (any number of them), or else the working59directory, or the home folder when that's the file system's root, as60where Claude Desktop starts servers. A relative path is looked for in61each folder in turn; an absolute one must be inside one. Hidden files62and folders and links that lead outside are refused, as63[`012 serve`](../terminal/ssh.md#security-model) refuses them. Roots are deprecated in64the protocol's 2026-07-28 version, whose clients the server can't ask,65so they get `--root`'s folders.6667`describe` without a path lists the workbooks in those folders: `.012`68files, and the files 012 [imports](../files/README.md#import-and-download) (CSV, XLSX,69JSON, SQLite and the rest), four folders deep, without hidden folders70or `node_modules`. Imported files are read as the app opens them, and71are read only: `create_workbook` with `from` makes a `.012` workbook72of one, to change. A path that doesn't exist is an error naming73`create_workbook`, which makes a new workbook and never replaces a file.7475## Flags7677| Flag | Does |78|---|---|79| `file.012` | The workbook of tools called without a path |80| `--root dir` | A folder workbooks may be in, when the host shares no roots; give it again for more |81| `--read-only` | Offers only the tools that read |82| `--force` | Lets writes change [protected ranges](../sheets/notes-protection.md#protected-sheets-and-ranges), as `012 set --force` |83| `--notebooks` | Offers `run_notebook_cell`, which runs a [notebook](../nushell/notebooks.md) cell with nu, if the workbook was saved on this computer |84| `--trust` | With `--notebooks`, runs the cells of a workbook saved on another computer, and marks it trusted here |85| `--jev` | Answers [JEV functions](../formulas/jev.md) over the network, each question once a session |8687Without them nothing runs a program or reaches the network: notebook88outputs are read as the file keeps them, and JEV functions show `#N/A`.89`shell = off` in the [configuration](../reference/config.md#shell) keeps90notebook cells from running even with `--notebooks`.9192## Tools9394Every tool but `describe` takes `path`, the workbook, required unless95the server was started with a file. References are written as in96formulas (`B7`, `Q3!A1:C9`, `'Q3 plan'!A:A`, a named range, a table,97`Sales[Amount]`, a sheet's name), and inputs as a person types them, in98en-US form. Values keep their types both ways: writes take money,99percentages, dates, times, durations and sizes as100[values with their types](../reference/json.md#values)101(`{"currency": 3.5}`, `{"date": "2026-09-29"}`) as well as typed102entries (`$3.50`), and reads return them the same way beside the text103each cell shows, so a model can check what it wrote. Every write takes104`dry_run`, which returns the change without making it.105106| Tool | Does |107|---|---|108| `describe` | Without a path, the workbooks open to the server; with one, its sheets, used ranges, guessed header rows and column names, tables, outputs, charts, pivots, notebook cells and names, as [`012 describe`](../reference/json.md#describe) |109| `read_range` | A range's values as rows, typed, each cell as shown, and its formulas by cell |110| `evaluate` | A formula's value, computed in the workbook (at `at`, or below the data) without writing it: its text, why it's an error, an array's spill |111| `find` | Cells by what they show or, with `in_formulas`, their formulas' text, as Edit > Find |112| `list_errors` | The formulas showing errors after recalculating, as `012 recalc` lists them, without saving |113| `create_workbook` | A new `.012` workbook at `path`, empty, made `from` a file 012 imports or another workbook, or holding `data`, a table as `write_table` writes it; it never replaces a file |114| `write_cells` | Entries typed into cells, or values with their types, and number formats, as one change, as `012 set` |115| `write_table` | Rows of records under a header, each column formatted as its values' type, as one change, as importing a NUON table |116| `apply_operations` | Several operations as one change: `set`, `write_table`, `clear`, `insert_rows`, `delete_rows`, `insert_columns`, `delete_columns`, `add_sheet`, `rename_sheet`, `delete_sheet`, `define_name`, `sort` |117| `sort` | A range's rows sorted by columns, named by letter or header |118| `filter` | A filter on a range by conditions (`gt`, `contains` and the rest) or values to hide, or the sheet's filter removed |119| `create_chart` | A chart of a range, its type, title and place given or guessed as Insert > Chart guesses them |120| `create_pivot` | A pivot table on a new sheet: rows, columns and summarized values by header |121| `run_notebook_cell` | With `--notebooks`: one code cell run, its output kept and sent on to its sheet |122123A write returns `saved`, `changes` (as [`012 diff`](../reference/json.md#diff)124lists them) and `warnings`; a refused one is an error naming the cell,125with nothing changed. Every result's schema is in126[JSON output](../reference/json.md#mcp-tools).127128## Views in the chat129130Hosts that draw tool results as pages show what `read_range` read and131the chart `create_chart` made beside the result, as 012 draws them: the132[web page](../files/README.md#web-pages) export's grid with its column133and row headers, fonts, number formats, styles and charts as SVG, in134the host's light or dark theme. Clicking a cell, or the arrow keys,135puts the pointer on it and shows what was typed in it in the formula136bar. The grid scrolls under its headers in at most 480 pixels inline137(less when the host has less room, the whole frame full screen), and a138smaller range takes only its own height.139140Two kinds of hosts do this, and the view works in both:141142| Host | Finds the page by | Its page | The page reads |143|---|---|---|---|144| [MCP Apps](https://github.com/modelcontextprotocol/ext-apps) (Claude, and the extension's other hosts) | the tool's `_meta.ui.resourceUri` | `ui://012/view`, `text/html;profile=mcp-app` | the `ui/initialize` handshake's theme and room, then `ui/notifications/tool-result` |145| The [OpenAI Apps SDK](https://developers.openai.com/apps-sdk) (ChatGPT, Codex) | the tool's `_meta["openai/outputTemplate"]` | `ui://012/view.skybridge`, `text/html+skybridge` | `window.openai`: `toolResponseMetadata`, `theme`, `maxHeight`, `displayMode`, and `openai:set_globals` events |146147What the page draws is in the result's `_meta["o12/view"]`, for every148client, whether or not it declared the extension: the workbook's name,149where the range or chart is, and its HTML, at most 200 rows of what150`read_range` returned. Both kinds of hosts hand a result's `_meta` to151the page (the Apps SDK as `window.openai.toolResponseMetadata`) and152keep it from the model, which reads the result itself,153`structuredContent` and the same JSON as text, with no HTML: about ten154kilobytes for 60 rows of currency, typed values and text shown. The page asks for nothing from the network and155calls no tools.156157## Resources158159Hosts that let people attach data to a conversation list these; the160scheme is `o12` since a URI's scheme starts with a letter. The161workbook is named as tools name it (relative to the first folder open162to the server, or absolute, `o12:///Users/me/budget.012/...`), each163part of its path and a sheet's name percent-encoded:164165| URI | Is |166|---|---|167| `o12://budget.012/Sheet1!A1:D40` | A range, as `read_range` returns it; each sheet's used range is listed |168| `o12://budget.012/table/Sales` | A table, header row included; each table is listed |169| `o12://budget.012/notebook/Notes/2` | A notebook cell's source, and its output as NUON or why it failed; each code cell is listed |170171The list holds the five workbooks the tools used last (and the file172named on the command line) and follows them: a change that adds a sheet173or table updates it, and hosts that listen are told. The templates174reach any range of any workbook open to the server.175176## Prompts177178| Prompt | Asks |179|---|---|180| `summarize_workbook` | What each sheet of a workbook (`path`) holds and what its numbers say, without changing anything |181| `fix_errors` | The formulas showing errors in a workbook (`path`) explained, fixes checked with `evaluate` and previewed before they're made |182| `add_column` | A column of formulas computing something beside a range (`path`, `range`, `column`) |183| `chart` | The chart that best answers a question about a range (`path`, `range`, `question`) |