Skip to content

Tables and versions

A table is named by a path, such as research/competitors: up to five parts of letters, digits, _ and -, joined by /. The parts before the last are its folders. Paths are lowercase, so Research/Competitors and research/competitors are one table. In SQL, a table is named by its path in double quotes:

SELECT category, count(*) FROM "research/competitors" GROUP BY 1

Each column has a type (text, integer, double, decimal, boolean, date, timestamp and so on), read from the data written. Values that don’t all fit one type stay text exactly as written, and the write says so in a warning.

A table can be renamed, and its history, links and API follow it.

Every write makes a new version: version 1, 2, 3 and on. A version never changes once made, so a version number always reads the same rows.

A write has a mode:

  • create: a new table. Refused if the path is taken.
  • append: adds the rows.
  • upsert: updates the rows whose key columns match, and adds the rest. A column left out of a row keeps its value.
  • replace: the rows become the table’s contents.

All but create make the table if there is none. Rows whose columns don’t fit the table are refused, naming the columns that conflict and how to fix them.

Each version records:

  • who made it: an agent (by the name its client gives, such as “Claude Code”), an API token (by its name), or a person in the app;
  • the message given with the write, such as “added 40 rows from Crunchbase”;
  • the run label, which an agent or script sets to group the writes of one task;
  • when, and what changed: rows added, updated and removed, and columns added.

table_history answers this list, and the table’s History panel in the app shows it with a diff of each version.

restore_version makes an earlier version the latest again. It does this by making a new version with the old one’s rows, so the versions after it are kept and the restore can be undone too.

delete_table moves a table to the trash and frees its path. Its versions are kept. restore_version brings it back, and so does the Trash page in the app. Nothing deletes a table for good.

Because the tool is marked destructive, MCP clients ask their user before calling it.

A table and each of its columns can have a description: what it holds, where it came from, its units. update_table_info sets them, and describe_table answers them, so the next session (or another agent) knows what it’s reading. Describing a table changes no data and makes no version.