Skip to content

Auxiliary operations

Operations that describe and check the database, configure it and maintain its indexes. The overview lists every operation by kind. The MCP server, datanotes mcp, offers each operation as an MCP tool of the same name, and engineTools() of datanotes/mcp gives the same definitions to your own MCP server. DatanotesClient.call(name, args) runs one from code. Over HTTP each one is POST /datanotes/operations/<name>/, with its arguments as the JSON body: the HTTP API reference lists them.

Every write is validated. Writes to rows and to the schema are journaled and undone with undo_migration; configure_database, the webhook operations, vacuum_table and sync_semantic_index are not journaled.

List Tables · read-only

List every table: name, catalog, schema, qualified (personal.metrics.mood — use it wherever a table is expected; metrics.mood or mood also work when unambiguous), path and, when declared, description, aliases (other words for what it records) and tags. Tables are defined in metastore.yaml (catalog → schema → table): read it freely, but it is read-only for agents and changes only through the schema operations (create_table, add_column, …). Returns {tables, views}: views lists the stored views (same fields, no path): select them like tables. system.information_schema is read with select_rows.

Call this first to find the table for what the user reports (match their words against name, description and aliases), and before creating tables or columns so you reuse existing ones instead of creating duplicates.

Examples: Tables, Views.

Describe Table · read-only

Describe a table (catalog.schema.table or a shorter unambiguous name): qualified, name, catalog, schema, description, aliases, layout (folder, row_folder: the folder pattern of new rows, archive), options (partition, filename, archive, exclude), typed columns with label/aliases/description and the dense flag, untyped_fields, row_count, and when set: tags, bases (the bases it inherits from, in order), constraints (its CHECKs, name → where), row_template, history, autolink_target, fields (their values).

Before adding a column (e.g. a new metric), read columns and match your concept against name, label, aliases and description; reuse an existing column when it means the same.

missing_descriptions ({table, columns}), present only when something has no description (a table defined before descriptions were required), names what lacks one: write them with alter_table description and alter_column changes.description, asking the user when the meaning is unclear.

Examples: Catalogs, schemas and the database, Tables, Bases, Relations and hierarchies.

Parameter Type Required Default Description
table string yes

Describe Database · read-only

Describe the database: its folder (root), metastore (metastore.yaml: read it freely, but it is read-only for agents and changes only through the schema operations), configuration (default catalog and schema, row partition and file-name formats, archive folder, time zone, history, automatic links), journal folder, bases (shared column sets and the tables using them), catalogs → schemas → tables (with row_count, tags, and unreadable_count when some rows’ front matter cannot be read) and views; catalogs and schemas show their comment (set with comment_on). A table or base defined before descriptions were required has missing_descriptions: what lacks one, for alter_table / alter_column (define_base for a base) to fill, so every table and column says what it holds.

Examples: Catalogs, schemas and the database, Hand edits.

Configure Database · destructive write

Configure the database (persisted in metastore.yaml config:): root (rename the database folder; links follow; revert by renaming back), default_catalog, default_schema, default_partition (“” = flat) and default_filename (date formats for new time-based tables), archive_folder, timezone (IANA; completes date-times written without offset), history (transaction log for every table: true in a database the engine creates, false when config lacks it, as in a metastore from before 3.0.0; change it only on the user’s request), autolink (the text a write puts in a body links the notes it mentions; on by default). Returns describe_database. Renaming root moves the folder (links to its notes are rewritten; the tables’ archive and exclude folders inside it follow); the move is listed in the journal as move_database (undo and time travel read older entries with the new paths) and cannot be undone. Settings changes are not journaled (no migration_id, nothing for undo_migration): to revert, call it again with the previous values.

The metastore changes only through operations: never edit metastore.yaml by hand (no validation).

Examples: Catalogs, schemas and the database, Tables, Automatic links, Table history and time travel.

Parameter Type Required Default Description
root string \ null null
default_catalog string \ null null
default_schema string \ null null
default_partition string \ null null
default_filename string \ null null
archive_folder string \ null null
timezone string \ null null
history boolean \ null null
autolink boolean \ null null

Check Table · read-only

Validate every row against the table (required, types, ranges, enums, links, unknown columns, CHECK constraints, those that follow links included, filtered link targets (ref_where / ref_by), stale generated/identity values, missing inverse links, front matter that cannot be read: code unreadable, with no column, for a note whose table line names the table but whose YAML is broken, which every other read leaves out). A CHECK violation has code check and the CHECK’s name as constraint (every other code names its column), as in the violations of list_changes. Use it to find rows edited by hand that break the schema. Without table, every table is checked: each row then names its table, tables_checked counts the tables checked, and a table that cannot be checked is listed in errors ({table, error}) while the others are. The rows with violations are paged: limit (default 500, at most 5000) from offset; total counts them all. (Hand edits are also checked as they happen: see violations in list_changes.)

Examples: Relations and hierarchies, Hand edits, Find rows that break the schema.

Parameter Type Required Default Description
table string \ null null
limit integer 500 Rows with violations returned (paging).
offset integer 0 Rows with violations skipped first (paging).

Infer Table · read-only

Read-only schema inference from notes’ front matter.

  • folder (recursive; “” = whole vault) and/or paths: notes not yet in a table. Returns columns (type, enum values, link ref to the table most targets belong to, required, unique, dense, from when the front matter key is not a valid column name, stats), proposal, the create_table arguments (name, description, filename or time_column, columns), and adopt ready for adopt_rows (paths, rename, relocate: false), plus hints to read. The notes cannot say what the table and its columns mean: description is null on the proposal and on every column. Write each one (ask the user when unsure), and review the names, enums and required columns, before you pass the proposal to create_table, which refuses null descriptions.
  • table: keys the table’s rows use but the table does not declare (candidates for add_column, each with a description to write, or keys to drop from rows). A string column becomes an enum when its values repeat: at least 3 notes, at most max_enum_values distinct values (default 12), each used twice on average, short texts.

Examples: Hand edits, Import existing notes.

Parameter Type Required Default Description
folder string \ null null
paths string[] \ null null
table string \ null null
name string \ null null
max_enum_values integer \ null null

Describe Semantic Index · read-only

The semantic search index: enabled, provider, model, files, passages, pending, running, last_sync, last_error. sync_semantic_index brings it up to date.

Examples: Find notes by meaning.

Sync Semantic Index · destructive write

Bring the semantic search index up to date: embed the notes changed since the last run (the engine also does it on its own about ten seconds after edits). rebuild: true re-embeds everything: slow, and costs money with a paid provider — ask first.

Examples: Find notes by meaning.

Parameter Type Required Default Description
rebuild boolean false Re-embed every note, not only the changed ones.