Query operations
Operations that read rows and notes: select_rows, link targets, text and semantic search, the link graph. 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.
select_rows
Section titled “select_rows”Select Rows · read-only
Query rows: {table, total, rows: [{path, ...}]}. table may be a view,
system.information_schema.<catalogs|schemata|tables|columns|views|check_constraints>, or
base:<name> — every table that extends that base (e.g. base:record: all event-like tables),
on the base’s columns, each row tagged _source with its table.
where: as in update_rows; relative dates"{today}","{today-7d}","{now-24h}"(on a date column a date-time counts by its day); file columnsfile_name,file_link,file_modified,file_backlink_count.columns,order_by(-coldescending),limit(default 100, max 1000),offset,expand(inline linked rows’ frontmatter),include_body(the note body asbody).join:{"table", "on": {"date(occurred_at)+1": "date(timestamp)"}, "as", "type": "inner"|"left", "columns", "where"}— matches attached underas.group_by(column,pathordate(col)±n; a list column counts once per item) +aggregates{"n": "count", "kcal": "sum:meal.kcal"}(count, count:col, sum, avg, min, max).this_note: vault path of the note the result is for:{this.*}tokens in a view’s query and inwhereread it ({this.date},{this.link},{this.name},{this.path}); without it (or a front matter key the note lacks) a token stays as written and matches no row, whatever the operator (withinincluded).- Ordered enums compare by position. Time travel:
version(of one table) ortimestamp. Withtimestampa join, a view, a union orbase:<name>reads every table in it as of that time (versions: the version read of each); a table that did not exist then adds no rows to a union or base.versionis refused where several tables are read; information_schema has no history. Views and bases keep today’s definition, and links followed bywhere(project.kind,within) orexpandread the linked rows as they are now.
Examples: Catalogs, schemas and the database, Tables, Columns and types, Views, Bases, Relations and hierarchies, Validation, CHECK constraints, Hand edits, Read and filter rows, Joins and aggregates, Write and move rows, Batch writes, Import existing notes, Journal and undo, Table history and time travel, Restore a table or the database.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
table |
string | yes | ||
columns |
string[] \ | null | null |
|
where |
object \ | null | null |
|
order_by |
string \ | string[] \ | null | |
limit |
integer \ | null | null |
|
offset |
integer \ | null | null |
|
expand |
string[] \ | null | null |
|
join |
object \ | null | null |
|
group_by |
string \ | string[] \ | null | |
aggregates |
object \ | null | null |
|
include_body |
boolean | false |
||
version |
integer \ | null | null |
|
timestamp |
string \ | null | null |
|
this_note |
string \ | null | null |
list_link_targets
Section titled “list_link_targets”List Link Targets · read-only
The rows a link column may point to, for one row: what an agent or a picker offers before writing the link. A link column can filter its targets:
ref_where: awherefilter every target must match ({"kind": {"in": ["area", "project"]}}).ref_by: a column of the row picks the targets’ level:{"column": "kind", "map": {"area": null, "project": ["area"], "workstream": ["project"]}}: a workstream’s parent must have kind project;nullis a top level (the link must stay empty); any other level needs the link; a value missing from the map is refused.levels: ["area", "project", "workstream"]writes the same chain short (each level’s parent is the level before it).target_columnreads another column of the target (default: the same name). describe_table shows the expanded map. Writes refuse other targets (coderef, listing the valid ones), a link to the row itself (ref), a link to no row of the table (broken_link) and a missing link a level needs (required). Pass the row (row: path, link or name; a name rows in different folders share is refused, listing their paths) and/or its values (values, e.g.{"kind": "workstream"}for a new row). Returns{rows: [{name, link, path, <level column>}], total, required, empty, reason}(no rows, and the reason, for a level the map lacks); write a row’slinkas the value.
Examples: Relations and hierarchies.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
table |
string | yes | ||
column |
string | yes | A link column (or list of links) with ref. | |
row |
string \ | null | null |
|
values |
object \ | null | null |
|
limit |
integer \ | null | null |
read_note
Section titled “read_note”Read Note · read-only
Read a note or another file of the vault: {path, content, front_matter, tags, modified_at, created_at, size}. content is the whole text, front matter included; tags are without #,
from the text and the front matter; the times are in the database’s time zone. A missing file is
an error. path: vault-relative, forward slashes.
Examples: Relations and hierarchies, Hand edits, Import existing notes, Read and search notes.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
path |
string | yes | The file’s vault path, with its extension (“Films/Metropolis.md”). |
list_folder
Section titled “list_folder”List Folder · read-only
The direct children of a vault folder: {folder, folders, files}, each a vault path, sorted;
dot-files and dot-folders are left out. folder “” is the vault root. A missing folder is an
error.
Examples: Catalogs, schemas and the database, Tables, Columns and types, Write and move rows, Read and search notes.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
folder |
string | "" |
Vault-relative folder; “” is the vault root. |
search_notes
Section titled “search_notes”Search Notes · read-only
Plain-text search: every word of query must occur, case- and accent-insensitive, in the
note’s path or text; there are no operators. Returns {query, results: [{path, score, matches: [{start, end, context}]}], total}, best first: at most 200 notes (total counts them all) and 20
matches per note. context_length: characters of context on each side (default 100, max 1000).
Examples: Read and search notes.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
string | yes | ||
context_length |
integer | 100 |
Characters of context on each side of a match (at most 1000). |
semantic_search
Section titled “semantic_search”Semantic Search · read-only
Find notes by meaning, not exact words: {query, results: [{path, score, heading, snippet, table?}]}, one result per note (its best passage), best first. Use it for vague questions
(“the dinner where we talked about moving”, “what did I decide about the car”) and to find the
rows to read or update; then read_note / select_rows for the details. Filters: tables
(qualified or short names), folder, min_score (cosine 0–1; ~0.5+ is usually relevant).
limit: default 10, max 100. Fails with a clear message when semantic search is not enabled in
the engine settings.
Examples: Find notes by meaning.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
query |
string | yes | ||
limit |
integer | 10 |
||
tables |
string[] \ | null | null |
|
folder |
string \ | null | null |
|
min_score |
number \ | null | null |
graph_neighbors
Section titled “graph_neighbors”Graph Neighbors · read-only
Direct neighbours of notes: what they link to (out) and what links to them (in,
backlinks), with counts per edge label. direction: out, in or both (default).
from_nodes selects the notes: {"paths": [...]} and/or {"table": ..., "where": {...}}.
Edges are labelled with their link column (people, event, …) or link for other links.
Examples: Walk the link graph.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from_nodes |
object | yes | ||
direction |
"out" \ |
"in" \ |
"both" \ |
null |
edges |
string[] \ | null | null |
graph_traverse
Section titled “graph_traverse”Graph Traverse · read-only
Breadth-first walk over links from from_nodes ({"paths": [...]} and/or {"table", "where"}).
direction: out (default, follow links), in (follow backlinks) or both.edges: edge labels to follow (link columns such aspeople,event, orlink).tables: return only notes of these tables;through: only walk on through these tables.min_depth(default 1) /max_depth(default 2, max 10),limit(default 500).
Each node comes with depth and via (one shortest route). Example — moods tied to events
with Alice: from {"table": "person", "where": {"name": "Alice"}}, direction in, edges
["people", "event"], tables ["mood"], max_depth 2. Feed the paths to select_rows with
where: {"path": {"in": [...]}} to aggregate them.
Examples: Walk the link graph.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from_nodes |
object | yes | ||
direction |
"out" \ |
"in" \ |
"both" \ |
null |
edges |
string[] \ | null | null |
|
tables |
string[] \ | null | null |
|
through |
string[] \ | null | null |
|
min_depth |
integer \ | null | null |
|
max_depth |
integer \ | null | null |
|
limit |
integer \ | null | null |
graph_path
Section titled “graph_path”Graph Path · read-only
Shortest chain of links between two sets of notes (each {"paths": [...]} and/or
{"table", "where"}): found, length and path: the steps (from, label, direction, to).
direction both by default; max_depth default 6 (max 10).
Examples: Walk the link graph.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
from_nodes |
object | yes | ||
to_nodes |
object | yes | ||
direction |
"out" \ |
"in" \ |
"both" \ |
null |
edges |
string[] \ | null | null |
|
max_depth |
integer \ | null | null |