{
  "openapi": "3.1.0",
  "info": {
    "title": "Datanotes",
    "version": "1.4.0",
    "description": "Database of Markdown notes. Every request needs `Authorization: Bearer <token>` (the owner's token or an app's). Send `X-Datanotes-Actor: {\"harness\": …, \"model\": …, \"session\": …}` to record on whose behalf a write is made."
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer"
      }
    }
  },
  "security": [
    {
      "bearer": []
    }
  ],
  "paths": {
    "/datanotes/tables/": {
      "post": {
        "operationId": "list_tables",
        "summary": "List every table: `name`, `catalog`, `schema`, `qualified` (`personal.metrics.mood` — use it",
        "description": "List every table: `name`, `catalog`, `schema`, `qualified` (`personal.metrics.mood` — use it\nwherever a table is expected; `metrics.mood` or `mood` also work when unambiguous), `path` and,\nwhen declared, `description` and `aliases` (other words for what it records). Tables are\ndefined in `database.yaml` (catalog → schema → table). Returns `{tables, views}`: `views` lists the stored views (same fields, no\npath): select them like tables. `system.information_schema` is read with `select_rows`.\n\nCall this first to find the table for what the user reports (match their words against\nname, description and aliases), and before creating tables or columns so you reuse existing\nones instead of creating duplicates.",
        "x-mcp-tools": [
          "list_tables"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/tables/describe/": {
      "post": {
        "operationId": "describe_table",
        "summary": "Describe a table (`catalog.schema.table` or a shorter unambiguous name): options (`path`/`filename` patterns, archive folder, `exclude` folders), typed columns with",
        "description": "Describe a table (`catalog.schema.table` or a shorter unambiguous name): options (`path`/`filename` patterns, archive folder, `exclude` folders), typed columns with\nlabel/aliases/description, dense vs sparse flag, untyped fields, and row count.\n\nBefore adding a column (e.g. a new metric), read `columns` and match your concept against\n`name`, `label`, `aliases` and `description`; reuse an existing column when it means the same.",
        "x-mcp-tools": [
          "describe_table"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/ddl/": {
      "post": {
        "operationId": "ddl",
        "summary": "Same as the MCP tools create_table, drop_table, add_column, rename_column, drop_column, alter_column, alter_table, define_base, set_table_bases, rename_value, add_constraint, drop_constraint, create_view, drop_view, clone_table.",
        "description": "**create_table**: Create table `catalog.schema.name` (definition in database.yaml; rows in\n`<root>/<catalog>/<schema>/<name>/`). Names: lowercase letters, digits, `_`; catalog/schema default\nto the database defaults.\n- `columns`: specs like `{\"name\": \"kind\", \"type\": \"enum\", \"values\": [\"a\",\"b\"], \"required\": true}`.\n  Types: string, integer, number, boolean, date, datetime, enum, link, list (+ `items`), json.\n  Attributes: required, default (`\"{now}\"`/`\"{today}\"`), min, max, step, values, `ordered` (enum in\n  order: filters/avg use the position), ref (link target, full `catalog.schema.table` or \"self\"),\n  unique, label, description, aliases, `generated` (e.g. `\"date(occurred_at)\"`, `\"{name} {surname}\"`),\n  `identity` (\"filename\" | \"created\"), `vocabulary` (allowed values = names of another table's rows),\n  `hierarchy: true` (one parent link to its own table), `dense` (written on every row),\n  `inverse` on a link column: the column of the `ref` table that links back (`friends` ↔\n  `friends`, `children` ↔ `parents`, `partner` ↔ `partner`); writes keep both sides in step.\n- `time_column`: rows named by that date/datetime; otherwise `options.filename` (e.g. `\"{name}\"`).\n- `options`: `description` and `aliases` (how agents find it), `filename`, `partition`, `exclude`.\n- `body`: markdown body of new rows (row_template). Shared columns come from bases: `set_table_bases`.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{\"stated\": \"the user said it\", …}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: \"link({occurred_at:YYYY-MM-DD})\"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\n\n**drop_table**: Drop a table. Refused while it has rows unless `cascade=\"archive\"`, which removes the\ndefinition from `database.yaml` and moves all rows to the table's archive folder (nothing is\nhard-deleted; undo restores). The transaction log is kept: `restore_table` can bring it back.\n\n**add_column**: Add a typed column. Sparse by default (written only on rows that have a value — use for\nmetrics, e.g. `{\"name\": \"metric_mood\", \"type\": \"integer\", \"min\": 1, \"max\": 5, \"label\":\n\"Mood\", \"aliases\": [\"mood\"], \"description\": \"Mood of the day, 1 = bad, 5 = great\"}`).\n`dense=true` adds it to every row with its `default`. Call `describe_table` first: never add\na column whose meaning an existing column (name/label/aliases/description) already covers.\nColumn names are permanent identifiers; only `rename_column` changes them.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{\"stated\": \"the user said it\", …}`): describe_table shows them and a refused value lists them.\nGenerated link columns: `generated: \"link({occurred_at:YYYY-MM-DD})\"` with `ref` = the days table links each row to the row of `ref` named by the template (its folder read from the schema; the target may not exist yet).\n\n**rename_column**: Rename a column in database.yaml and on every row. Refused if `to_column` is already a column\nof the table; a row that has a stray `to_column` key with a different value is a conflict, and\nnothing is written. Views and note text that mention the old name are not rewritten.\n\n**drop_column**: Remove a column from the schema and every row. Previous values are journaled; revert with\n`undo_migration`.\n\n**alter_column**: Change a column's attributes (type, min/max/step, values, required, default, label,\naliases, description, note; `null` removes an attribute; `dense` true/false). Refused with\nthe list of violating rows when existing values do not satisfy the new definition. A\ndifferent scale means a different column: add a new one instead of rescaling. To rename one\nenum value use `rename_value`.\n\n**alter_table**: Alter a table without paths: move it (`catalog`, `schema`), rename it (`name`), change\n`partition` / `filename` patterns, `description`, `aliases`, `exclude` folders, `row_template`\n(`clear_row_template=true` removes it) or `history` (\"on\" | \"off\" | \"inherit\"). Rows, archive and\ntransaction log follow; links are updated; renamed rows keep their old name in `aliases`. Refused\nwhen a row cannot fill a pattern. Use `dry_run` to see `plannedMoves`; undo with undo_migration.\n\n**define_base**: Create or replace a base: a named set of columns (same spec as `create_table`) that tables\ninherit, like a parent class (`bases` in `database.yaml`). Tables using it get the columns\nwith the same name and meaning; `ref: \"self\"` means the inheriting table (e.g. a `parent`\ncolumn with `hierarchy: true`). `extends` builds on other bases. Replacing a base changes\nevery inheriting table: `rename_columns` (`{\"old\": \"new\"}`) renames the column on their rows,\n`drop_columns` removes it from their rows; dropping a column without listing it is refused.\nAll affected rows are validated before any write.\nEnum columns: `values` and, for each, its meaning in `value_descriptions` (`{\"stated\": \"the user said it\", …}`): describe_table shows them and a refused value lists them.\n\n**set_table_bases**: Set the bases a table inherits from (`extends`, in order; `[]` removes them). Inherited\ncolumns come after `id` and before the table's own columns. An own column with the name of an\ninherited one is replaced by the inherited definition (rows must fit it); a table may only\nrestyle an inherited column (label, description, aliases, note, dense) with `alter_column`.\nDense and generated/identity columns are filled on existing rows.\n\n**rename_value**: Rename one value of an enum column (e.g. `high` → `very high`) in database.yaml and every\nrow, keeping its position, so an ordered scale is unchanged. Note text (queries, prose) is not\nrewritten. Refused if `to_value` already exists. Undo with `undo_migration`. Adding or\nremoving classes changes the scale: create a new table instead.\n\n**add_constraint**: ALTER TABLE ADD CONSTRAINT `name` CHECK: `check` is a where filter every row must match,\ne.g. `{\"value\": {\"gte\": 1, \"lte\": 5}}` (a condition on an empty value passes, like SQL).\nRefused while existing rows violate it (they are listed); then enforced on every write.\n\n**drop_constraint**: Remove the CHECK constraint `name` from `table`.\n\n**create_view**: Create (or `replace`) a view: a named select stored in database.yaml. Name it with the prefix\n`vw_` (e.g. `vw_open_tasks`): views share names and folders with tables. `query` takes the\nselect_rows parameters (table, columns, where, order_by, limit, join, group_by, aggregates, expand;\nrelative dates keep it current) and must run now. `comment` and `aliases` let agents find it;\n`labels` are column headings. Read it with select_rows(table=<view>). A note shows it with a\n```datanotes block containing `view: <name>` (drawn live by the client; nothing is written into\nthe note). Filters may read the note that shows the view: `{this.date}`, `{this.date+1d}` (a\nfrontmatter value, date arithmetic), `{this.link}` (a link to that note), `{this.name}`. The view\nalso gets a note in its schema folder.\n\n**drop_view**: Remove a view from `database.yaml` (undo with `undo_migration`).\n\n**clone_table**: CREATE TABLE `target` CLONE `source`: same definition plus independent copies of its rows\n(deep clone), optionally as of a `version` / `timestamp`. `shallow=true` copies the\ndefinition only (CREATE TABLE LIKE). `target`: `catalog.schema.table`, `schema.table` (in the\nsource's catalog) or a name (source's catalog and schema). Useful for experiments, e.g. a sandbox copy\nin the `agent` catalog.",
        "x-mcp-tools": [
          "create_table",
          "drop_table",
          "add_column",
          "rename_column",
          "drop_column",
          "alter_column",
          "alter_table",
          "define_base",
          "set_table_bases",
          "rename_value",
          "add_constraint",
          "drop_constraint",
          "create_view",
          "drop_view",
          "clone_table"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "columns": {
                        "items": {
                          "additionalProperties": true,
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "schema": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "catalog": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "time_column": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "options": {
                        "anyOf": [
                          {
                            "additionalProperties": {
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "items": {
                                    "type": "string"
                                  },
                                  "type": "array"
                                }
                              ]
                            },
                            "type": "object"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "fields": {
                        "anyOf": [
                          {
                            "additionalProperties": true,
                            "type": "object"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null,
                        "description": "Untyped fields of the table (name → default), kept on every row; a field cannot share a name with a column."
                      },
                      "body": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "create_table"
                      }
                    },
                    "required": [
                      "name",
                      "columns",
                      "op"
                    ],
                    "title": "create_table"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "cascade": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "drop_table"
                      }
                    },
                    "required": [
                      "table",
                      "op"
                    ],
                    "title": "drop_table"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "column": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "dense": {
                        "default": false,
                        "type": "boolean"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "add_column"
                      }
                    },
                    "required": [
                      "table",
                      "column",
                      "op"
                    ],
                    "title": "add_column"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "from": {
                        "type": "string"
                      },
                      "to": {
                        "type": "string"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "rename_column"
                      }
                    },
                    "required": [
                      "table",
                      "from",
                      "to",
                      "op"
                    ],
                    "title": "rename_column"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "drop_column"
                      }
                    },
                    "required": [
                      "table",
                      "name",
                      "op"
                    ],
                    "title": "drop_column"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "changes": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "alter_column"
                      }
                    },
                    "required": [
                      "table",
                      "name",
                      "changes",
                      "op"
                    ],
                    "title": "alter_column"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "catalog": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "schema": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "partition": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "filename": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "description": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "aliases": {
                        "anyOf": [
                          {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "history": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "exclude": {
                        "anyOf": [
                          {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "row_template": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "clear_row_template": {
                        "default": false,
                        "type": "boolean"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "alter_table"
                      }
                    },
                    "required": [
                      "table",
                      "op"
                    ],
                    "title": "alter_table"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "columns": {
                        "items": {
                          "additionalProperties": true,
                          "type": "object"
                        },
                        "type": "array"
                      },
                      "extends": {
                        "anyOf": [
                          {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "comment": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "rename_columns": {
                        "anyOf": [
                          {
                            "additionalProperties": {
                              "type": "string"
                            },
                            "type": "object"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "drop_columns": {
                        "anyOf": [
                          {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "define_base"
                      }
                    },
                    "required": [
                      "name",
                      "columns",
                      "op"
                    ],
                    "title": "define_base"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "bases": {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "set_table_bases"
                      }
                    },
                    "required": [
                      "table",
                      "bases",
                      "op"
                    ],
                    "title": "set_table_bases"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "column": {
                        "type": "string"
                      },
                      "from": {
                        "type": "string"
                      },
                      "to": {
                        "type": "string"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "rename_value"
                      }
                    },
                    "required": [
                      "table",
                      "column",
                      "from",
                      "to",
                      "op"
                    ],
                    "title": "rename_value"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "check": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "add_constraint"
                      }
                    },
                    "required": [
                      "table",
                      "name",
                      "check",
                      "op"
                    ],
                    "title": "add_constraint"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "table": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "drop_constraint"
                      }
                    },
                    "required": [
                      "table",
                      "name",
                      "op"
                    ],
                    "title": "drop_constraint"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "query": {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      "catalog": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "schema": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "comment": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "aliases": {
                        "anyOf": [
                          {
                            "items": {
                              "type": "string"
                            },
                            "type": "array"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "labels": {
                        "anyOf": [
                          {
                            "additionalProperties": {
                              "type": "string"
                            },
                            "type": "object"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "replace": {
                        "default": false,
                        "type": "boolean"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "create_view"
                      }
                    },
                    "required": [
                      "name",
                      "query",
                      "op"
                    ],
                    "title": "create_view"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "view": {
                        "type": "string"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "drop_view"
                      }
                    },
                    "required": [
                      "view",
                      "op"
                    ],
                    "title": "drop_view"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "source": {
                        "type": "string"
                      },
                      "target": {
                        "type": "string"
                      },
                      "version": {
                        "anyOf": [
                          {
                            "type": "integer"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "timestamp": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "default": null
                      },
                      "shallow": {
                        "default": false,
                        "type": "boolean"
                      },
                      "dry_run": {
                        "default": false,
                        "type": "boolean"
                      },
                      "op": {
                        "const": "clone_table"
                      }
                    },
                    "required": [
                      "source",
                      "target",
                      "op"
                    ],
                    "title": "clone_table"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/database/": {
      "post": {
        "operationId": "describe_database",
        "summary": "Describe the database: its folder (`root`), `metastore` (`database.yaml`), configuration",
        "description": "Describe the database: its folder (`root`), `metastore` (`database.yaml`), configuration\n(default catalog and schema, row partition and file-name formats, archive folder, time zone),\njournal folder, `bases` (shared column sets and the tables using them), `catalogs` → `schemas` → `tables` (with `rows` counts) and `views`.",
        "x-mcp-tools": [
          "describe_database"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/database/configure/": {
      "post": {
        "operationId": "configure_database",
        "summary": "Configure the database (persisted in database.yaml `config:`): `root` (rename the database",
        "description": "Configure the database (persisted in database.yaml `config:`): `root` (rename the database\nfolder; links follow; revert by renaming back), `default_catalog`, `default_schema`,\n`default_partition` (\"\" = flat) and `filename` (date formats for new time-based tables),\n`archive_folder`, `timezone` (IANA; completes date-times written without offset), `history`\n(transaction log for every table — only on the user's request). Returns describe_database.\nRenaming `root` moves the folder (links to its notes are rewritten); it is not journaled: to\nrevert, call it again with the old value.",
        "x-mcp-tools": [
          "configure_database"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "root": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "default_catalog": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "default_schema": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "default_partition": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "filename": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "archive_folder": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "timezone": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "history": {
                    "anyOf": [
                      {
                        "type": "boolean"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/insert/": {
      "post": {
        "operationId": "insert_row",
        "summary": "Insert a row (new note). Values are validated against the columns; the note path comes from",
        "description": "Insert a row (new note). Values are validated against the columns; the note path comes from\nthe table's `path`/`filename` patterns (e.g. an event logged today about last night lands in\nlast night's day folder when you set `occurred_at` to last night). `body` is the note text.\nGenerated / identity columns are computed (do not pass them); CHECK constraints are enforced.\nReturns `migrationId` (undo) and the created path in `plannedCreates`.",
        "x-mcp-tools": [
          "insert_row"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "values": {
                    "additionalProperties": true,
                    "type": "object"
                  },
                  "body": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "path": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null,
                    "description": "Optional note path (vault-relative), instead of the table's file-name pattern; `.md` is added if missing; it must stay inside the vault."
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table",
                  "values"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/update/": {
      "post": {
        "operationId": "update_rows",
        "summary": "Update every row matching `where`. `where`: keys AND-ed; values are equality or operators",
        "description": "Update every row matching `where`. `where`: keys AND-ed; values are equality or operators\neq, ne, gt, gte, lt, lte, in, contains, icontains (case/accent-insensitive, also inside lists —\nuse it for names and aliases), exists, within (a hierarchy link: that row and everything below);\ncombine with `or` / `and` / `not` (nestable); `path` is a pseudo-column. A dotted key follows a\nlink column: `{\"project.area\": \"[[Work]]\"}` matches rows whose `project` links a row with that `area`. `set_values` sets, `unset`\nremoves; all rows are validated first. `body` replaces the note body (only when one row matches).\n`expect_rows`: refuse unless exactly that many match. One row: prefer update_row.",
        "x-mcp-tools": [
          "update_rows"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "where": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "set": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "unset": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  },
                  "body": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "expect_rows": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/update-one/": {
      "post": {
        "operationId": "update_row",
        "summary": "Update exactly ONE row, addressed by its `id` (the system UUID) or its `path`; refused when",
        "description": "Update exactly ONE row, addressed by its `id` (the system UUID) or its `path`; refused when\nthe row does not exist (or id and path disagree). Same validation, journal and history as\n`update_rows`.\n\n- `set_values` / `unset`: columns to set or remove.\n- `body`: replace the whole note body; or edit it keeping the rest:\n  `body_sections` `{\"Storia\": \"…\"}` replaces the text under that heading (any level, up to the\n  next heading of the same level; added as `## Storia` when missing), `body_prepend` /\n  `body_append` add text before / after.\n- `expect`: compare-and-set — `{\"status\": \"open\"}` writes only if the row still has those\n  values (a person may have changed it since you read it); otherwise refused, nothing written.",
        "x-mcp-tools": [
          "update_row"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "id": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "path": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "set": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "unset": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "body": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "body_sections": {
                    "anyOf": [
                      {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "body_prepend": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "expect": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "body_append": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/delete/": {
      "post": {
        "operationId": "delete_rows",
        "summary": "Delete rows matching `where`. `mode`: \"archive\" (default, move to the table's archive",
        "description": "Delete rows matching `where`. `mode`: \"archive\" (default, move to the table's archive\nfolder) or \"delete\" (trash; content journaled for undo). `on_referenced`: \"restrict\"\n(default, refuse rows other notes link to), \"set_null\" (clear frontmatter links to them) or\n\"ignore\". Omitting `where` targets every row: always pass `where` unless you mean all.",
        "x-mcp-tools": [
          "delete_rows"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "where": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "mode": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "on_referenced": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/move/": {
      "post": {
        "operationId": "move_rows",
        "summary": "Move rows matching `where` to another table (e.g. split a domain out of `log` into its own",
        "description": "Move rows matching `where` to another table (e.g. split a domain out of `log` into its own\ntable): sets each row's `table` to the destination, applies `rename` (`{\"metric_distance_km\":\n\"distance_km\"}`), `set_values` and `drop`, adds the destination's missing dense fields, and\nvalidates every row against the destination first. Keys unknown to the destination are\nreported, never dropped silently — rename or drop them explicitly. `relocate=true` also moves\nthe files to the destination table's folder (named by its filename pattern). Undo with\n`undo_migration`.",
        "x-mcp-tools": [
          "move_rows"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "to_table": {
                    "type": "string"
                  },
                  "where": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "rename": {
                    "anyOf": [
                      {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "set": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "drop": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "relocate": {
                    "default": false,
                    "type": "boolean"
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table",
                  "to_table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/adopt/": {
      "post": {
        "operationId": "adopt_rows",
        "summary": "Turn existing notes (not rows of any table yet) into rows of `table`, keeping their body and",
        "description": "Turn existing notes (not rows of any table yet) into rows of `table`, keeping their body and\nlinks: `rename` keys (`{\"data\": \"occurred_at\"}`), `set_values` for all, `per_row` values by\nnote path (`{\"Home/x.md\": {\"zone\": \"[[Kitchen]]\"}}`), `drop` keys the table does not have.\nEvery note gets `table` and a system `id`; with `relocate` (default) it moves to the table's\nfolder, named by its filename pattern (links to it are rewritten). All notes are validated first:\nunknown keys and bad values are listed and nothing is written. Run with `dry_run` first; undo\nwith `undo_migration`.",
        "x-mcp-tools": [
          "adopt_rows"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "paths": {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "rename": {
                    "anyOf": [
                      {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "set": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "per_row": {
                    "anyOf": [
                      {
                        "additionalProperties": {
                          "additionalProperties": true,
                          "type": "object"
                        },
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "drop": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "relocate": {
                    "default": true,
                    "type": "boolean"
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table",
                  "paths"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/select/": {
      "post": {
        "operationId": "select_rows",
        "summary": "Query rows: `{table, total, rows: [{path, ...}]}`. `table` may be a view,",
        "description": "Query rows: `{table, total, rows: [{path, ...}]}`. `table` may be a view,\n`system.information_schema.<catalogs|schemata|tables|columns|views|check_constraints>`, or\n`base:<name>` — every table that extends that base (e.g. `base:record`: all event-like tables),\non the base's columns, each row tagged `_source` with its table.\n- `where`: as in update_rows; relative dates `\"{today}\"`, `\"{today-7d}\"`, `\"{now-24h}\"`; file columns\n  `file_name`, `file_link`, `file_modified`, `file_backlinks`.\n- `columns`, `order_by` (`-col` descending), `limit` (default 100, max 1000), `offset`,\n  `expand` (inline linked rows' frontmatter), `include_body` (the note body as `body`).\n- `join`: `{\"table\", \"on\": {\"date(occurred_at)+1\": \"date(timestamp)\"}, \"as\", \"type\": \"inner\"|\"left\",\n  \"columns\", \"where\"}` — matches attached under `as`.\n- `group_by` (column, `path` or `date(col)±n`; a list column counts once per item) + `aggregates`\n  `{\"n\": \"count\", \"kcal\": \"sum:meal.kcal\"}` (count, count:col, sum, avg, min, max).\n- Ordered enums compare by position. Time travel: `version` or `timestamp`.",
        "x-mcp-tools": [
          "select_rows"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "columns": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "where": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "order_by": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "limit": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "offset": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "expand": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "join": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "group_by": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "aggregates": {
                    "anyOf": [
                      {
                        "additionalProperties": {
                          "type": "string"
                        },
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "include_body": {
                    "default": false,
                    "type": "boolean"
                  },
                  "version": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "timestamp": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/check/": {
      "post": {
        "operationId": "check_table",
        "summary": "Validate every row against the table (required, types, ranges, enums, links, unknown",
        "description": "Validate every row against the table (required, types, ranges, enums, links, unknown\ncolumns, CHECK constraints, stale generated/identity values). Use it to find rows edited by hand that break the schema.",
        "x-mcp-tools": [
          "check_table"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/migrations/undo/": {
      "post": {
        "operationId": "undo_migration",
        "summary": "Revert a journaled table operation by its `migrationId`. Refused (nothing written) when any",
        "description": "Revert a journaled table operation by its `migrationId`. Refused (nothing written) when any\ntouched note changed since; the conflicts are listed. The revert is a new version (`UNDO`) in\nthe transaction log.",
        "x-mcp-tools": [
          "undo_migration"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "migration_id": {
                    "type": "string"
                  }
                },
                "required": [
                  "migration_id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/batch/": {
      "post": {
        "operationId": "batch",
        "summary": "Several writes that succeed or fail together. `operations`: `[{\"op\": ..., ...arguments}]` where",
        "description": "Several writes that succeed or fail together. `operations`: `[{\"op\": ..., ...arguments}]` where\n`op` is a row operation (`insert_row`, `update_row`, `update_rows`, `delete_rows`, `merge_rows`,\n`move_rows`, `adopt_rows`, `recompute_columns`, `align_relations`, `restore_table`) or a DDL op\n(`create_table`, `add_column`, `alter_column`, …), with the same arguments as its tool (e.g.\n`values` for insert_row, `set_values` for update_row / update_rows). They run in order, each seeing the previous ones; if one is\nrefused, the ones already applied are undone (`rolledBack`). Returns `steps` (per operation) and\n`migrationId`: undo_migration on it reverts the whole batch. Use it when a change spans several\nrows (create an event and update the people in it). `dry_run` checks each operation against the\ncurrent data only.",
        "x-mcp-tools": [
          "batch"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "operations": {
                    "items": {
                      "additionalProperties": true,
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "summary": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "operations"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/align-relations/": {
      "post": {
        "operationId": "align_relations",
        "summary": "Add the reciprocal links missing on a table's `inverse` link columns (e.g. Alice lists Carol",
        "description": "Add the reciprocal links missing on a table's `inverse` link columns (e.g. Alice lists Carol\nin `friends` but Carol does not list Alice). Run it after declaring `inverse` on existing data;\ncheck_table reports such rows (code `inverse`). Single-value links already pointing elsewhere\nare conflicts (nothing written). Writes through the tools already keep both sides in step.",
        "x-mcp-tools": [
          "align_relations"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "paths": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/tables/infer/": {
      "post": {
        "operationId": "infer_table",
        "summary": "Read-only schema inference from notes' frontmatter.",
        "description": "Read-only schema inference from notes' frontmatter.\n- `folder` (recursive; \"\" = whole vault) and/or `paths`: notes not yet in a table. Returns\n  `columns` (type, enum `values`, link `ref` to the table most targets belong to, `required`,\n  `unique`, `dense`, `from` when the property name is not a valid column name, `stats`),\n  `proposal` ready for create_table (`name`, `options.filename` or `timeColumn`, `columns`) and\n  `adopt` ready for adopt_rows (`paths`, `rename`, `relocate: false`), plus `notes` to read.\n  Review the proposal (names, enums, required) before creating; ask the user when unsure.\n- `table`: keys the table's rows use but the table does not declare (candidates for add_column,\n  or keys to drop from rows).\nA string column becomes an enum with at most `max_enum_values` distinct values (default 12).",
        "x-mcp-tools": [
          "infer_table"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "folder": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "paths": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "table": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "name": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "max_enum_values": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/search/semantic/": {
      "post": {
        "operationId": "semantic_search",
        "summary": "Find notes by meaning, not exact words: `{query, results: [{path, score, heading, snippet,",
        "description": "Find notes by meaning, not exact words: `{query, results: [{path, score, heading, snippet,\ntable?}]}`, one result per note (its best passage), best first. Use it for vague questions\n(\"the dinner where we talked about moving\", \"what did I decide about the car\") and to find the\nrows to read or update; then read_note / select_rows for the details. Filters: `tables`\n(qualified or short names), `folder`, `min_score` (cosine 0–1; ~0.5+ is usually relevant).\n`limit`: default 10, max 100. Fails with a clear message when semantic search is not enabled in\nthe engine settings.",
        "x-mcp-tools": [
          "semantic_search"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "query": {
                    "type": "string"
                  },
                  "limit": {
                    "default": 10,
                    "type": "integer"
                  },
                  "tables": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "folder": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "min_score": {
                    "anyOf": [
                      {
                        "type": "number"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "query"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/search/semantic/status/": {
      "post": {
        "operationId": "semantic_index",
        "summary": "Semantic search index: `status` (`enabled`, `provider`, `model`, `files`, `passages`, `pending`,",
        "description": "Semantic search index: `status` (`enabled`, `provider`, `model`, `files`, `passages`, `pending`,\n`running`, `lastSync`, `lastError`), `update` (embed notes changed since the last run; the\nengine also does it on its own about ten seconds after edits) or `rebuild` (re-embed\neverything: slow, and costs money with a paid provider — ask first).",
        "x-mcp-tools": [
          "semantic_index"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "default": "status",
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/migrations/list/": {
      "post": {
        "operationId": "list_migrations",
        "summary": "The operation journal, newest first: `migration_id` (for undo_migration), `op`, `summary`,",
        "description": "The operation journal, newest first: `migration_id` (for undo_migration), `op`, `summary`,\n`schema` (table), `executed_at`, `notes_changed`, `files`, `undone`, `undoes`, `failed`.\nFilters: `op` (e.g. \"update_rows\"), `table` (substring of the table name, e.g.\n\"personal.tasks.task\"), `since` (ISO date). `limit` default 50. The journal is kept in the\nvault's hidden `.datanotes/journal/` (not notes); entries older than 90 days are dropped.",
        "x-mcp-tools": [
          "list_migrations"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "limit": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "op": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "table": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "since": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/merge/": {
      "post": {
        "operationId": "merge_rows",
        "summary": "MERGE (upsert) `rows` into `table` by the key columns `on` (e.g. `[\"occurred_at\"]` or",
        "description": "MERGE (upsert) `rows` into `table` by the key columns `on` (e.g. `[\"occurred_at\"]` or\n`[\"id\"]`): a row matching an existing one updates it (`when_matched`: \"update\" default or\n\"ignore\"), the others are inserted (`when_not_matched`: \"insert\" default or \"ignore\").\nDate-times are compared after completion with the database time zone. A source key matching\nseveral rows, or repeated, is a conflict. One journaled, undoable operation.",
        "x-mcp-tools": [
          "merge_rows"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "on": {
                    "items": {
                      "type": "string"
                    },
                    "type": "array"
                  },
                  "rows": {
                    "items": {
                      "additionalProperties": true,
                      "type": "object"
                    },
                    "type": "array"
                  },
                  "when_matched": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "when_not_matched": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table",
                  "on",
                  "rows"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/history/": {
      "post": {
        "operationId": "describe_history",
        "summary": "DESCRIBE HISTORY: the table's versions, newest first — `version`, `timestamp`, `operation`",
        "description": "DESCRIBE HISTORY: the table's versions, newest first — `version`, `timestamp`, `operation`\n(CREATE TABLE, WRITE, UPDATE, DELETE, MERGE, ALTER TABLE, ADD COLUMNS, RESTORE, UNDO, …;\n`EXTERNAL_EDIT` = changed outside the engine: an editor, git, sync), `operationMetrics` and `migrationId` (undo).\nWorks for dropped tables too (full `catalog.schema.table`). Use a version with `select_rows`\n(time travel), `table_changes` or `restore_table`.",
        "x-mcp-tools": [
          "describe_history"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "limit": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/history/changes/": {
      "post": {
        "operationId": "table_changes",
        "summary": "Change data feed between two versions (both included, end defaults to latest): one entry",
        "description": "Change data feed between two versions (both included, end defaults to latest): one entry\nper row change with its values plus `_change_type` (insert, delete, update_preimage,\nupdate_postimage, metadata), `_commit_version`, `_commit_timestamp`, `_operation`, `path`.\nUse it to answer \"what changed since …\" without diffing full tables.",
        "x-mcp-tools": [
          "table_changes"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "start_version": {
                    "type": "integer"
                  },
                  "end_version": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "table",
                  "start_version"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/changes/": {
      "post": {
        "operationId": "list_changes",
        "summary": "Change feed across all tables: numbered row changes (`seq`), oldest first, from engine writes",
        "description": "Change feed across all tables: numbered row changes (`seq`), oldest first, from engine writes\nand from hand edits (`source: external`). Each has `table`, `op` (insert, update, delete, move,\nschema), `path`, `changes` ({column: {before, after}}), `actor`, `migration`. Agents' tool calls (reported by MCP servers) are `op: tool_call` events (`call`: tool, args, ok, value, servedBy), returned only when `ops` includes tool_call. Pass the returned\n`last` as `since` next time (`head` is the newest number); `wait_ms` (max 60000) waits for a new change (long poll); `limit` max 5000. `gap: true` means\nolder changes were dropped: re-read the tables. `where` filters rows as in select_rows (on the values after the change). Per-table versions: `table_changes`.",
        "x-mcp-tools": [
          "list_changes"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "since": {
                    "type": "integer",
                    "default": 0
                  },
                  "tables": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "ops": {
                    "anyOf": [
                      {
                        "items": {
                          "enum": [
                            "insert",
                            "update",
                            "delete",
                            "move",
                            "schema",
                            "tool_call"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "columns": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "where": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "exclude_actor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "limit": {
                    "type": "integer",
                    "default": 500
                  },
                  "wait_ms": {
                    "type": "integer",
                    "default": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/webhooks/": {
      "post": {
        "operationId": "list_webhooks",
        "summary": "Webhooks of the change feed: id, url, filter (tables, ops, columns, exclude_actor), `cursor` (last change delivered), `status` (ok, failing, disabled), `lastDelivery`, `lastError`. Secrets are not shown.",
        "description": "Webhooks of the change feed: id, url, filter (tables, ops, columns, exclude_actor), `cursor` (last change delivered), `status` (ok, failing, disabled), `lastDelivery`, `lastError`. Secrets are not shown.",
        "x-mcp-tools": [
          "list_webhooks"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/webhooks/create/": {
      "post": {
        "operationId": "create_webhook",
        "summary": "Push row changes to a URL (a service that would rather be called than poll `list_changes`): batches of up to 100 events POSTed as `{webhook, events, last}`, signed with `X-Datanotes-Signature: sha256=<HMAC of the body>`, retried with backoff until a 2xx. Starts from now unless `since`. Returns the webhook with its `secret` — shown only here: give it to the receiver.",
        "description": "Push row changes to a URL (a service that would rather be called than poll `list_changes`): batches of up to 100 events POSTed as `{webhook, events, last}`, signed with `X-Datanotes-Signature: sha256=<HMAC of the body>`, retried with backoff until a 2xx. Starts from now unless `since`. Returns the webhook with its `secret` — shown only here: give it to the receiver.",
        "x-mcp-tools": [
          "create_webhook"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "tables": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "ops": {
                    "anyOf": [
                      {
                        "items": {
                          "enum": [
                            "insert",
                            "update",
                            "delete",
                            "move",
                            "schema",
                            "tool_call"
                          ],
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "columns": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "exclude_actor": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "where": {
                    "anyOf": [
                      {
                        "additionalProperties": true,
                        "type": "object"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "since": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "url"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/webhooks/delete/": {
      "post": {
        "operationId": "delete_webhook",
        "summary": "Stop and remove a webhook (by `id` from list_webhooks).",
        "description": "Stop and remove a webhook (by `id` from list_webhooks).",
        "x-mcp-tools": [
          "delete_webhook"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "id": {
                    "type": "string"
                  }
                },
                "required": [
                  "id"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/history/restore/": {
      "post": {
        "operationId": "restore_table",
        "summary": "RESTORE TABLE to a `version` or `timestamp`: rows and definition return to that state —",
        "description": "RESTORE TABLE to a `version` or `timestamp`: rows and definition return to that state —\nrows added since are deleted, changed rows get their old content, removed rows come back (a\ndropped table is re-created). History is not rewritten: the restore is a new version, and\n`undo_migration` reverts it. Run with `dry_run` first and show the user what changes.",
        "x-mcp-tools": [
          "restore_table"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "version": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "timestamp": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/history/vacuum/": {
      "post": {
        "operationId": "vacuum_table",
        "summary": "Delete transaction-log history older than `retain_from_version` (default: keep only the",
        "description": "Delete transaction-log history older than `retain_from_version` (default: keep only the\nlatest version); time travel before it becomes impossible. Rows are not touched. `dry_run`\ndefaults to true: it lists the log files that would go. Only on the user's explicit request.",
        "x-mcp-tools": [
          "vacuum_table"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "retain_from_version": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "dry_run": {
                    "const": true
                  }
                },
                "required": [
                  "table",
                  "dry_run"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/rows/recompute/": {
      "post": {
        "operationId": "recompute_columns",
        "summary": "Bring generated and identity columns up to date (all rows, or only `paths`), e.g. after",
        "description": "Bring generated and identity columns up to date (all rows, or only `paths`), e.g. after\nrows were edited by hand (an editor, git, sync) or a generated expression changed with `alter_column`.\nAlso gives rows without an `id` a new one, and a duplicated note (same `id` as an older row)\na new id. `new_ids=true` regenerates every id in scope (new ones on every call): only on the user's\nexplicit request.\n`check_table` reports stale values with code `generated`. No-op when nothing is stale;\notherwise journaled (undo_migration) and a RECOMPUTE version in the table's history.",
        "x-mcp-tools": [
          "recompute_columns"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "table": {
                    "type": "string"
                  },
                  "paths": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "new_ids": {
                    "default": false,
                    "type": "boolean"
                  },
                  "dry_run": {
                    "default": false,
                    "type": "boolean"
                  }
                },
                "required": [
                  "table"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/graph/neighbors/": {
      "post": {
        "operationId": "graph_neighbors",
        "summary": "Direct neighbours of notes: what they link to (`out`) and what links to them (`in`,",
        "description": "Direct neighbours of notes: what they link to (`out`) and what links to them (`in`,\nbacklinks), with counts per edge label. `direction`: out, in or both (default).\n\n`from_nodes` selects the notes: `{\"paths\": [...]}` and/or `{\"table\": ..., \"where\": {...}}`.\nEdges are labelled with their link column (`people`, `event`, …) or `link` for other links.",
        "x-mcp-tools": [
          "graph_neighbors"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from": {
                    "additionalProperties": true,
                    "type": "object"
                  },
                  "direction": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "edges": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "from"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/graph/traverse/": {
      "post": {
        "operationId": "graph_traverse",
        "summary": "Breadth-first walk over links from `from_nodes` (`{\"paths\": [...]}` and/or `{\"table\", \"where\"}`).",
        "description": "Breadth-first walk over links from `from_nodes` (`{\"paths\": [...]}` and/or `{\"table\", \"where\"}`).\n\n- `direction`: out (default, follow links), in (follow backlinks) or both.\n- `edges`: edge labels to follow (link columns such as `people`, `event`, or `link`).\n- `tables`: return only notes of these tables; `through`: only walk on through these tables.\n- `min_depth` (default 1) / `max_depth` (default 2, max 10), `limit` (default 500).\n\nEach node comes with `depth` and `via` (one shortest route). Example — moods tied to events\nwith Alice: from `{\"table\": \"person\", \"where\": {\"name\": \"Alice\"}}`, direction `in`, edges\n`[\"people\", \"event\"]`, tables `[\"mood\"]`, max_depth 2. Feed the paths to `select_rows` with\n`where: {\"path\": {\"in\": [...]}}` to aggregate them.",
        "x-mcp-tools": [
          "graph_traverse"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from": {
                    "additionalProperties": true,
                    "type": "object"
                  },
                  "direction": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "edges": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "tables": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "through": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "min_depth": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "max_depth": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "limit": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "from"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/graph/path/": {
      "post": {
        "operationId": "graph_path",
        "summary": "Shortest chain of links between two sets of notes (each `{\"paths\": [...]}` and/or",
        "description": "Shortest chain of links between two sets of notes (each `{\"paths\": [...]}` and/or\n`{\"table\", \"where\"}`): `found`, `length` and `path`: the steps (`from`, `label`, `direction`, `to`).\n`direction` both by default; `max_depth` default 6 (max 10).",
        "x-mcp-tools": [
          "graph_path"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "from": {
                    "additionalProperties": true,
                    "type": "object"
                  },
                  "to": {
                    "additionalProperties": true,
                    "type": "object"
                  },
                  "direction": {
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "edges": {
                    "anyOf": [
                      {
                        "items": {
                          "type": "string"
                        },
                        "type": "array"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  },
                  "max_depth": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "default": null
                  }
                },
                "required": [
                  "from",
                  "to"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done (JSON)."
          },
          "400": {
            "description": "Bad request."
          },
          "401": {
            "description": "Missing or wrong bearer token."
          },
          "403": {
            "description": "An app beyond its permissions."
          },
          "404": {
            "description": "Unknown table, view or migration."
          },
          "422": {
            "description": "Refused (conflicts or violations): nothing written."
          }
        }
      }
    },
    "/datanotes/apps/": {
      "post": {
        "operationId": "apps_list",
        "summary": "List registered apps (owner only).",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/apps/me/": {
      "post": {
        "operationId": "apps_me",
        "summary": "The calling app's own entry (app token).",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/apps/create/": {
      "post": {
        "operationId": "apps_create",
        "summary": "Register an app (owner only). Returns its token once.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "pattern": "^[a-z0-9][a-z0-9-]*$"
                  },
                  "description": {
                    "type": "string"
                  },
                  "write": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Tables the app may write: catalog.schema.table, catalog.schema.*, catalog.* or *."
                  },
                  "ddl": {
                    "type": "boolean",
                    "description": "May the app change the schema?"
                  },
                  "maintain": {
                    "type": "boolean",
                    "description": "May the app also undo, restore, vacuum, configure and rebuild the semantic index? (For an agent's own token.)"
                  },
                  "mcp_url": {
                    "type": "string",
                    "description": "The app's MCP endpoint (Streamable HTTP): its tools are listed by /apps/tools/ and called with /apps/call/."
                  },
                  "mcp_token": {
                    "type": "string",
                    "description": "Bearer token the engine sends to the app's MCP endpoint."
                  },
                  "instructions": {
                    "type": "string",
                    "description": "Text for agents (instead of the app's own initialize instructions)."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/apps/update/": {
      "post": {
        "operationId": "apps_update",
        "summary": "Change an app. An app may change its own mcp_url, mcp_token, description and instructions; permissions are the owner's.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Owner only (an app updates itself)."
                  },
                  "description": {
                    "type": "string"
                  },
                  "write": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "ddl": {
                    "type": "boolean"
                  },
                  "maintain": {
                    "type": "boolean"
                  },
                  "mcp_url": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "mcp_token": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "instructions": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/apps/refresh/": {
      "post": {
        "operationId": "apps_refresh",
        "summary": "Fetch an app's tools and instructions again.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/apps/delete/": {
      "post": {
        "operationId": "apps_delete",
        "summary": "Remove an app (owner only).",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/apps/rotate-token/": {
      "post": {
        "operationId": "apps_rotate-token",
        "summary": "Give an app a new token (owner only).",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/apps/tools/": {
      "post": {
        "operationId": "apps_tools",
        "summary": "The registered apps' tools (MCP tool definitions, each with its `app`) and their instructions for agents.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/apps/call/": {
      "post": {
        "operationId": "apps_call",
        "summary": "Call an app's tool on the caller's behalf (the engine holds the app's credentials). Answers {ok, value, servedBy}.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tool"
                ],
                "properties": {
                  "tool": {
                    "type": "string"
                  },
                  "arguments": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Done."
          }
        }
      }
    },
    "/datanotes/changes/stream": {
      "get": {
        "operationId": "changes_stream",
        "summary": "The change feed as Server-Sent Events (id = sequence number). Resumes from Last-Event-ID or `since`.",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tables",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ops",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "columns",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "exclude_actor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "where",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "text/event-stream"
          }
        }
      }
    },
    "/datanotes/tool-calls/record/": {
      "post": {
        "operationId": "tool_calls_record",
        "summary": "Record an agent's tool call in the change feed (`tool_call` events): what an MCP server reports after each call.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tool"
                ],
                "properties": {
                  "tool": {
                    "type": "string"
                  },
                  "args": {
                    "type": "object"
                  },
                  "ok": {
                    "type": "boolean"
                  },
                  "durationMs": {
                    "type": "number"
                  },
                  "value": {},
                  "servedBy": {
                    "type": "string"
                  },
                  "session": {
                    "type": "string"
                  },
                  "resultChars": {
                    "type": "number"
                  },
                  "resultTokens": {
                    "type": "number"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recorded."
          }
        }
      }
    }
  }
}