add_sheet_columnmember+
Add one typed column to a grid table. Value kinds (text, long_text, number, boolean, select, multi_select, date, url) hold what a person or an agent writes: a url column stores one absolute http:// or https:// address as text, and a multi_select column stores an array of the options named in config.options (null clears it; the empty array is refused). The column is appended unless before_column_id places it. prompt, topic, and source columns hold the workspace's own tracked data as {"id","label"} values; an agent column runs one agent per row, reading its inputs from the columns named in input_bindings and writing its outputs into the columns named in output_bindings (use get_agent_ports to see the port names). A tool column runs ONE read-postured MCP tool per row with no agent and no model: name the tool in config.tool, map each of its arguments to a column through input_bindings (the binding key is the argument name), and bind the result port, which is the tool's own name, through output_bindings. Only a curated list of tools can back a column, and the refusal names them. An input binding may carry a PATH, which is how one column reads a single field out of another column's JSON instead of handing the whole blob downstream: a drafting column returning {"title","markdown"} feeds a scorer that wants those as two separate arguments. See input_bindings for the grammar. A draft column writes an article draft into the drafts inbox once per row, and is the only kind here that costs a model call: name the mode in config.mode, either "create" to write a new draft or "revise" to rewrite the one an earlier draft column already wrote. A create column reads source_url (required, the page currently winning the query), coverage_queries, prompt_id and prompt_text; a revise column reads draft and instructions, both required. Both write the port named draft, one JSON object of {draft_id,title,markdown,status}, so a later column reads title or markdown out of it at a path. A formula column is a JavaScript expression over the row's other columns and is free at any row count. Adding a column of any kind runs nothing and spends nothing.
add_sheet_rowsmember+
Append empty rows to a grid table (or insert them directly below after_row_id). The table must already have at least one column. Returns the created rows with their ids for set_sheet_cell. Runs nothing and spends nothing.
cancel_sheet_cellmember+
Return one QUEUED agent cell to idle, releasing its reservation against the table's ceiling. Free: cancel never spends. A running cell is refused with canceled=false and a reason (the worker owns it and it finishes on its own); a cell with no queued run is refused the same way. A refusal is an answer, not an error.
create_sheetmember+
Create a table. With grid=true this creates a BLANK spreadsheet table (a grid): no rows, no fan-out, and a credit estimate of zero; shape it with add_sheet_column and add_sheet_rows, fill cells with set_sheet_cell, and run agent columns with run_sheet_cell or run_sheet_column. Without grid this plans a bulk fan-out of one agent over explicit entities, typed records, or a saved segment, and returns the draft sheet, its queued rows, and a pre-run credit estimate. Creating a table of either kind runs nothing and spends nothing; run_sheet runs a planned fan-out.
delete_sheetmember+
Retire a table. It leaves the library and every read of it, while its runs and evidence stay reachable through list_runs and get_run. A queued or running table is refused. There is no restore through this tool. Spends nothing.
delete_sheet_columnmember+
Delete one column and every cell and run state stored against it. Permanent; there is no undo through this tool. Spends nothing.
delete_sheet_rowmember+
Delete one row and every cell and run state stored against it. Permanent; there is no undo through this tool. Spends nothing.
duplicate_sheetmember+
Copy a table into a fresh draft named "<name> copy": its columns, rows, and user-authored cells copy; agent results, cell runs, and run history stay with the source. A queued or running table is refused. Spends nothing.
duplicate_sheet_rowmember+
Copy one row's user-authored values into a new row directly below it. Agent results and run history are not copied, because evidence is never attributed to a row that did not run. Spends nothing.
estimate_sheet_chainmember+
Price a whole chain, not one column: every stage that feeds the named column, over every row, before anything is claimed. Returns the per-stage projection, the total, the table's credit ceiling and what it has already admitted. A row that stops early is never priced for the stages it will not reach. A read: claims nothing, queues nothing, spends nothing.
estimate_sheet_columnmember+
Price what running one agent column would cost, without running it. estimated_credits is the whole gesture's price: the named column PLUS every column that declares it runs after it, since running the first starts the rest. stages breaks that down per column and is exactly the set the run may touch; runnable_cells is the named column's own count. credits_per_cell is what ONE cell of that gesture costs, cascade included, which is the number a single-cell Run spends. Also returns the table's credit ceiling and what it has already admitted against it. A read: claims nothing, queues nothing, spends nothing.
export_sheetmember+
Return a grid table's full contents as CSV text: a Row number, then one column per stored column in position order, agent columns printing each cell's run status. The same file the REST CSV export streams, bounded at 262144 bytes: past that the text stops at the last complete row and truncated=true, and the complete file is the in-app download. Refused while the table is queued or running, or while any of its cells is queued or running, so the export is never a torn snapshot. A legacy batch table is refused too; read it with get_sheet. XLSX is not offered here. A read; spends nothing.
get_sheetmember+
Return a sheet and its per-row fan-out state. Result artifacts are omitted by default to keep polling and MCP context bounded; set include_artifacts=true to include byte-bounded output previews, provenance, approvals, and run links. Open the linked run to view or download a complete truncated value.
list_sheetsmember+
List the workspace's bulk sheets, newest first (the Sheets history), so a sheet stays findable without its deep link.
No arguments.
move_sheet_columnmember+
Reorder one column, either one step by direction (left or right) or to a destination with before_column_id (a column uuid, or the literal "end" to place it last). A destination wins over a direction when both are sent. Spends nothing.
move_sheet_rowmember+
Reorder one row, either one step by direction (up or down) or to a destination with before_row_id (a row uuid, or the literal "end" to place it last). A destination wins over a direction when both are sent. Spends nothing.
rename_sheetmember+
Rename a table and/or move its lifetime credit ceiling (100..25000 credits), the fence every cell admission is checked against. At least one of name or credit_ceiling is required. Changing the ceiling is a spend control, so it is refused unless the caller's role is owner or admin; renaming is open to every member. Lowering the ceiling below what the table has already admitted cancels nothing and simply refuses further runs. Spends nothing.
run_sheetmember+
Accept a planned sheet for durable background fan-out with server-enforced concurrency and credit caps. Returns acceptance plus the sheet's current state; use get_sheet to follow row progress.
run_sheet_cellmember+
Run one agent column for one row. SPENDS CREDITS when admitted: the cell is queued for durable execution and its dry-run estimate is reserved against the table's credit ceiling. It also starts this row's cells in every column that declares it runs after this one, which estimate_sheet_column prices as part of the same gesture. If the column carries a run_condition the row fails, the cell is recorded as skipped at zero spend. accepted=false with a reason (ceiling reached, already running, condition skipped) is a real answer, not an error, and means nothing ran and nothing was spent. Poll get_sheet for the result.
run_sheet_chainmember+
Run a whole chain from one call: every stage feeding the named column, in dependency order, admitting only the cells whose own upstreams are done for that row. Rows advance independently, so a slow row never holds another back. The chain is priced whole first and refused whole if the table cannot afford it, because part-funding a pipeline that cannot finish is worse than refusing it. A stage whose upstream is empty records a skip at zero spend.
run_sheet_columnmember+
Run one agent column across every runnable row, and the columns wired to run after it. SPENDS CREDITS for every admitted cell. Each admitted cell is priced by a dry run and reserved against the table's credit ceiling before anything runs; a refusal names the reason and spends nothing. Returns how many cells were admitted in the named column, how many the run_condition skipped (zero spend), and a per-row refusal list; refusals are answers, not errors. Downstream columns are admitted as each row's upstream finishes, so they report nothing here. Call estimate_sheet_column first: it prices this whole gesture, not just the named column.
set_sheet_cellmember+
Write one user-authored cell value in a value column (never an agent column). value is any JSON scalar; null clears the cell. A select column accepts only one of its configured options; a prompt, topic, or source column accepts exactly {"id":"...","label":"..."} naming data the workspace tracks (prompt and topic ids are uuids, a source id is its domain; the label is replaced with the canonical one) and refuses anything else. Runs nothing and spends nothing.
update_sheet_columnmember+
Edit one column: rename it, retype it between value kinds, replace its config (a select column's options, an agent column's run_condition), or rewire an agent column's agent and bindings. Absent fields are left unchanged; an empty bindings object clears that wiring. A retype leaves stored cell values as they are, and rewiring resets nothing retroactively: finished results stand and only future runs use the new wiring. A change to or from the agent kind is refused. Sending input_bindings replaces the whole map, paths included, so re-send the path on any binding that carried one or it reverts to reading the whole cell. Runs nothing and spends nothing.