datanotes 2.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/NOTICE +9 -0
- package/README.md +203 -28
- package/SECURITY.md +92 -45
- package/dist/THIRD-PARTY-NOTICES.txt +682 -0
- package/dist/api/catalog.d.cts +69 -0
- package/dist/api/catalog.d.ts +50 -2
- package/dist/api/cli-options.d.cts +39 -0
- package/dist/api/cli-options.d.ts +39 -0
- package/dist/api/client.d.cts +122 -0
- package/dist/api/client.d.ts +56 -34
- package/dist/api/docs.d.cts +211 -0
- package/dist/api/docs.d.ts +211 -0
- package/dist/api/guidance.d.cts +81 -0
- package/dist/api/guidance.d.ts +81 -0
- package/dist/api/index.cjs +7470 -2771
- package/dist/api/index.d.cts +14 -0
- package/dist/api/index.d.ts +11 -7
- package/dist/api/index.js +7470 -2771
- package/dist/api/local.cjs +118 -6
- package/dist/api/local.d.cts +95 -0
- package/dist/api/local.d.ts +70 -6
- package/dist/api/local.js +104 -6
- package/dist/api/mcp.cjs +17387 -0
- package/dist/api/mcp.d.cts +108 -0
- package/dist/api/mcp.d.ts +108 -0
- package/dist/api/mcp.js +17337 -0
- package/dist/api/otlp.d.cts +113 -0
- package/dist/api/otlp.d.ts +63 -15
- package/dist/api/redact.d.cts +42 -0
- package/dist/api/redact.d.ts +42 -0
- package/dist/api/requests.d.cts +26 -0
- package/dist/api/requests.d.ts +14 -16
- package/dist/api/results.d.cts +16 -0
- package/dist/api/results.d.ts +2 -1
- package/dist/api/tokens.d.cts +12 -0
- package/dist/api/tokens.d.ts +5 -0
- package/dist/api/tracing.d.cts +107 -0
- package/dist/api/tracing.d.ts +107 -0
- package/dist/datanotes.cjs +69597 -28329
- package/dist/docs/administration/configuration.md +59 -0
- package/dist/docs/administration/docker.md +80 -0
- package/dist/docs/administration/git-sync.md +71 -0
- package/dist/docs/administration/limits.md +153 -0
- package/dist/docs/administration/run-the-service.md +237 -0
- package/dist/docs/administration/status.md +61 -0
- package/dist/docs/administration/use-with-obsidian.md +75 -0
- package/dist/docs/api/operations/add_column.md +49 -0
- package/dist/docs/api/operations/add_constraint.md +55 -0
- package/dist/docs/api/operations/adopt_rows.md +50 -0
- package/dist/docs/api/operations/align_relations.md +41 -0
- package/dist/docs/api/operations/alter_column.md +46 -0
- package/dist/docs/api/operations/alter_table.md +67 -0
- package/dist/docs/api/operations/batch.md +48 -0
- package/dist/docs/api/operations/changes_stream.md +28 -0
- package/dist/docs/api/operations/check_table.md +29 -0
- package/dist/docs/api/operations/clone_table.md +48 -0
- package/dist/docs/api/operations/comment_on.md +42 -0
- package/dist/docs/api/operations/configure_database.md +52 -0
- package/dist/docs/api/operations/create_table.md +78 -0
- package/dist/docs/api/operations/create_view.md +54 -0
- package/dist/docs/api/operations/create_webhook.md +37 -0
- package/dist/docs/api/operations/define_base.md +52 -0
- package/dist/docs/api/operations/delete_rows.md +43 -0
- package/dist/docs/api/operations/delete_webhook.md +31 -0
- package/dist/docs/api/operations/describe_database.md +30 -0
- package/dist/docs/api/operations/describe_history.md +40 -0
- package/dist/docs/api/operations/describe_semantic_index.md +24 -0
- package/dist/docs/api/operations/describe_table.md +38 -0
- package/dist/docs/api/operations/docs.md +13 -0
- package/dist/docs/api/operations/drop_column.md +41 -0
- package/dist/docs/api/operations/drop_constraint.md +39 -0
- package/dist/docs/api/operations/drop_table.md +43 -0
- package/dist/docs/api/operations/drop_view.md +38 -0
- package/dist/docs/api/operations/engine_status.md +23 -0
- package/dist/docs/api/operations/graph_neighbors.md +34 -0
- package/dist/docs/api/operations/graph_path.md +32 -0
- package/dist/docs/api/operations/graph_traverse.md +43 -0
- package/dist/docs/api/operations/identify_session.md +24 -0
- package/dist/docs/api/operations/infer_table.md +43 -0
- package/dist/docs/api/operations/insert_row.md +48 -0
- package/dist/docs/api/operations/list_changes.md +35 -0
- package/dist/docs/api/operations/list_folder.md +28 -0
- package/dist/docs/api/operations/list_link_targets.md +44 -0
- package/dist/docs/api/operations/list_migrations.md +35 -0
- package/dist/docs/api/operations/list_tables.md +32 -0
- package/dist/docs/api/operations/list_webhooks.md +23 -0
- package/dist/docs/api/operations/manual_index.md +14 -0
- package/dist/docs/api/operations/manual_page.md +22 -0
- package/dist/docs/api/operations/merge_rows.md +44 -0
- package/dist/docs/api/operations/move_rows.md +52 -0
- package/dist/docs/api/operations/openapi.md +13 -0
- package/dist/docs/api/operations/openapi_post.md +20 -0
- package/dist/docs/api/operations/read_note.md +29 -0
- package/dist/docs/api/operations/recompute_columns.md +44 -0
- package/dist/docs/api/operations/record_tool_call.md +37 -0
- package/dist/docs/api/operations/rename_column.md +44 -0
- package/dist/docs/api/operations/rename_value.md +45 -0
- package/dist/docs/api/operations/restore_database.md +51 -0
- package/dist/docs/api/operations/restore_table.md +46 -0
- package/dist/docs/api/operations/search_notes.md +28 -0
- package/dist/docs/api/operations/select_rows.md +61 -0
- package/dist/docs/api/operations/semantic_search.md +34 -0
- package/dist/docs/api/operations/semantic_search_docs.md +26 -0
- package/dist/docs/api/operations/set_table_bases.md +44 -0
- package/dist/docs/api/operations/status.md +13 -0
- package/dist/docs/api/operations/stop_engine.md +23 -0
- package/dist/docs/api/operations/sync_semantic_index.md +33 -0
- package/dist/docs/api/operations/table_changes.md +31 -0
- package/dist/docs/api/operations/tags/auxiliary.md +14 -0
- package/dist/docs/api/operations/tags/change-feed.md +8 -0
- package/dist/docs/api/operations/tags/history.md +17 -0
- package/dist/docs/api/operations/tags/queries.md +15 -0
- package/dist/docs/api/operations/tags/rows-dml.md +16 -0
- package/dist/docs/api/operations/tags/schema-ddl.md +22 -0
- package/dist/docs/api/operations/tags/service.md +15 -0
- package/dist/docs/api/operations/tags/tokens.md +13 -0
- package/dist/docs/api/operations/tokens_create.md +34 -0
- package/dist/docs/api/operations/tokens_delete.md +29 -0
- package/dist/docs/api/operations/tokens_list.md +21 -0
- package/dist/docs/api/operations/tokens_me.md +20 -0
- package/dist/docs/api/operations/tokens_rotate.md +29 -0
- package/dist/docs/api/operations/tokens_update.md +34 -0
- package/dist/docs/api/operations/undo_migration.md +46 -0
- package/dist/docs/api/operations/update_row.md +60 -0
- package/dist/docs/api/operations/update_rows.md +46 -0
- package/dist/docs/api/operations/vacuum_table.md +37 -0
- package/dist/docs/api.md +135 -0
- package/dist/docs/develop/build-an-app.md +320 -0
- package/dist/docs/develop/build-on-datanotes.md +138 -0
- package/dist/docs/develop/change-feed-and-webhooks.md +70 -0
- package/dist/docs/develop/client.md +116 -0
- package/dist/docs/develop/concurrency.md +188 -0
- package/dist/docs/develop/http-api.md +89 -0
- package/dist/docs/develop/telemetry.md +285 -0
- package/dist/docs/guides/agents/docs-offline.md +99 -0
- package/dist/docs/guides/agents/how-agents-use-datanotes.md +124 -0
- package/dist/docs/guides/agents/prompts.md +495 -0
- package/dist/docs/guides/agents/reading-errors.md +112 -0
- package/dist/docs/guides/data-quality/check-constraints.md +379 -0
- package/dist/docs/guides/data-quality/check-table.md +63 -0
- package/dist/docs/guides/data-quality/hand-edits.md +507 -0
- package/dist/docs/guides/data-quality/sync-between-devices.md +51 -0
- package/dist/docs/guides/data-quality/validation.md +90 -0
- package/dist/docs/guides/database-objects/bases.md +480 -0
- package/dist/docs/guides/database-objects/catalogs-and-schemas.md +897 -0
- package/dist/docs/guides/database-objects/columns.md +1332 -0
- package/dist/docs/guides/database-objects/relations.md +1454 -0
- package/dist/docs/guides/database-objects/tables.md +1340 -0
- package/dist/docs/guides/database-objects/views.md +1003 -0
- package/dist/docs/guides/history/back-up.md +203 -0
- package/dist/docs/guides/history/change-data-feed.md +247 -0
- package/dist/docs/guides/history/journal-and-undo.md +262 -0
- package/dist/docs/guides/history/restore.md +341 -0
- package/dist/docs/guides/history/table-history.md +657 -0
- package/dist/docs/guides/history/vacuum.md +26 -0
- package/dist/docs/guides/read-and-write/automatic-links.md +768 -0
- package/dist/docs/guides/read-and-write/batch.md +139 -0
- package/dist/docs/guides/read-and-write/import-notes.md +896 -0
- package/dist/docs/guides/read-and-write/joins-and-aggregates.md +251 -0
- package/dist/docs/guides/read-and-write/read-and-filter.md +536 -0
- package/dist/docs/guides/read-and-write/write-rows.md +573 -0
- package/dist/docs/guides/search/link-graph.md +241 -0
- package/dist/docs/guides/search/semantic.md +133 -0
- package/dist/docs/guides/search/text.md +142 -0
- package/dist/docs/guides/security/security-model.md +110 -0
- package/dist/docs/guides/security/tokens.md +60 -0
- package/dist/docs/guides/security/who-did-what.md +44 -0
- package/dist/docs/index.md +113 -0
- package/dist/docs/llms.txt +33 -0
- package/dist/docs/reference/cli.md +143 -0
- package/dist/docs/reference/compatibility.md +83 -0
- package/dist/docs/reference/errors.md +72 -0
- package/dist/docs/reference/glossary.md +161 -0
- package/dist/docs/reference/operations/auxiliary.md +116 -0
- package/dist/docs/reference/operations/history.md +168 -0
- package/dist/docs/reference/operations/queries.md +169 -0
- package/dist/docs/reference/operations/rows.md +185 -0
- package/dist/docs/reference/operations/schema.md +316 -0
- package/dist/docs/reference/operations.md +96 -0
- package/dist/docs/reference/settings.md +43 -0
- package/dist/docs/release-notes.md +188 -0
- package/dist/docs/start/connect-agents.md +204 -0
- package/dist/docs/start/how-it-works.md +349 -0
- package/dist/docs/start/quick-start.md +128 -0
- package/package.json +60 -15
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Give each program its own token
|
|
2
|
+
|
|
3
|
+
> Create named tokens with their own permissions, so the engine limits what each program or agent can do and the journal says who wrote what.
|
|
4
|
+
|
|
5
|
+
A named token lets a program, a device or an agent call the engine with only the permissions it needs. The owner token can do everything; a named token reads everything and writes only what you allow. The journal records the token’s name with every write it makes, so you can tell who changed what.
|
|
6
|
+
|
|
7
|
+
To see a token at work in a complete program, follow [Build an app on Datanotes](https://datanotes.dev/develop/build-an-app/). For the ways to build on the engine, read [Build on Datanotes](https://datanotes.dev/develop/build-on-datanotes/). [Who did what](https://datanotes.dev/guides/security/who-did-what/) shows how the journal names each token.
|
|
8
|
+
|
|
9
|
+
## Create a token
|
|
10
|
+
|
|
11
|
+
You create a token with the owner token, and the engine answers with the new token. The engine shows it once and keeps only its Secure Hash Algorithm (SHA-256) hash, in `tokens.json` in its store:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
curl -X POST http://127.0.0.1:27150/datanotes/tokens/create/ \
|
|
15
|
+
-H "Authorization: Bearer your_owner_token" \
|
|
16
|
+
-H "Content-Type: application/json" \
|
|
17
|
+
-d '{"name": "film-diary", "write": ["main.public.*"]}'
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This request creates a token named `film-diary` that may write rows of every table in the `main.public` schema, such as `film` and `actor`. The answer holds the token in `token` and the registry’s entry in `entry`. The name is kebab-case, and `owner` is reserved.
|
|
21
|
+
|
|
22
|
+
## Manage your tokens
|
|
23
|
+
|
|
24
|
+
The owner manages tokens with these routes under `/datanotes/`:
|
|
25
|
+
|
|
26
|
+
* **`tokens/`**: lists the tokens, with their permissions and when each one was last used
|
|
27
|
+
* **`tokens/update/`**: changes a token’s description, permissions or `autolink` default
|
|
28
|
+
* **`tokens/rotate/`**: gives a token a new value; the old one stops working at once
|
|
29
|
+
* **`tokens/delete/`**: revokes a token
|
|
30
|
+
|
|
31
|
+
`datanotes status` lists every token with its permissions, never its value.
|
|
32
|
+
|
|
33
|
+
## Choose what a token can do
|
|
34
|
+
|
|
35
|
+
A named token can always read. Every other permission comes from its entry:
|
|
36
|
+
|
|
37
|
+
* **Row writes**: only on tables that match a pattern in `write`: `catalog.schema.table`, `catalog.schema.*`, `catalog.*` or `*`
|
|
38
|
+
* **Schema changes**: only with `"ddl": true`
|
|
39
|
+
* **Maintenance**: only with `"maintain": true`, meant for an agent’s own token; it covers configuration, undo, restore, vacuum and rebuilding the semantic index
|
|
40
|
+
|
|
41
|
+
Whatever its permissions, a named token can’t create or delete tokens and webhooks, list tokens, rotate them or read the engine’s status: those stay the owner’s. A token may list webhooks and read its own entry with `tokens/me/`. With `tokens/update/`, it may change its own `description` and `autolink`.
|
|
42
|
+
|
|
43
|
+
## Turn automatic links off for a sync program
|
|
44
|
+
|
|
45
|
+
By default, the text a write puts in a note links the notes it mentions. The engine calls this [automatic links](https://datanotes.dev/guides/read-and-write/automatic-links/). A sync program copies text from elsewhere, such as tasks, calendar events or receipts. That text should stay as it came, so give its token `"autolink": false`:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
curl -X POST http://127.0.0.1:27150/datanotes/tokens/create/ \
|
|
49
|
+
-H "Authorization: Bearer your_owner_token" \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-d '{"name": "tasks-sync", "write": ["main.public.task"], "autolink": false}'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
A token’s `autolink` is the default of its writes:
|
|
55
|
+
|
|
56
|
+
* **`insert_row`, `update_row` and `update_rows`** take it, inside a `batch` too.
|
|
57
|
+
* **A write’s own `autolink`** still wins over it.
|
|
58
|
+
* **Without it**, the token’s writes follow the database’s `autolink` setting.
|
|
59
|
+
|
|
60
|
+
Turn it off for the tokens of sync programs and of modules that write text for you. Keep it unset for an agent’s token. To change it later, call `tokens/update/` with `autolink`. Pass `null` to follow the database setting again. `tokens/` and `tokens/me/` list it with the other fields of the entry.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# See who did what
|
|
2
|
+
|
|
3
|
+
> Every write records who made it: the token, the program or agent, its model and session. Read it in the journal, the history and the change feed.
|
|
4
|
+
|
|
5
|
+
Every write records its actor: the credential that made it, and, when the caller says so, the program or agent behind it, its model and its session. The journal, the history and the change feed show it, so you can tell who changed what and undo one agent’s work without touching the rest.
|
|
6
|
+
|
|
7
|
+
## What the actor records
|
|
8
|
+
|
|
9
|
+
The actor has these fields:
|
|
10
|
+
|
|
11
|
+
* **`auth`**: the credential, `owner` or the name of a [named token](https://datanotes.dev/guides/security/tokens/); the engine sets it, and no header can claim it
|
|
12
|
+
* **`harness`** and **`harness_version`**: the program or MCP client, such as `claude-code`
|
|
13
|
+
* **`model`**: the model behind an agent
|
|
14
|
+
* **`session`**: the agent’s session
|
|
15
|
+
* **`tool`**: the tool the agent called
|
|
16
|
+
|
|
17
|
+
A program sends the other fields with the `X-Datanotes-Actor` header, or the client’s `actor` option, as [Record who makes each write](https://datanotes.dev/develop/http-api/#record-who-makes-each-write) shows. `datanotes mcp` fills them from the MCP connection, as [Every write names the agent that made it](https://datanotes.dev/guides/agents/how-agents-use-datanotes/#every-write-names-the-agent-that-made-it) explains.
|
|
18
|
+
|
|
19
|
+
## See which token made a change
|
|
20
|
+
|
|
21
|
+
Every write records the credential as `auth` in its actor: `owner`, or the token’s name. When a program forwards an agent’s `X-Datanotes-Actor` header, the engine records both, as “harness / model via token”. A program that writes for itself, without the header, appears under its token’s name.
|
|
22
|
+
|
|
23
|
+
`list_migrations` shows this name in the `by` field of each change, and `list_changes` shows the whole actor.
|
|
24
|
+
|
|
25
|
+
## Report what an agent does
|
|
26
|
+
|
|
27
|
+
A program that serves its own Model Context Protocol (MCP) server can report its agents to the engine, with any token:
|
|
28
|
+
|
|
29
|
+
* **`POST /datanotes/sessions/identify/`**: names the model and harness behind an agent’s session; later writes that carry the session in `X-Datanotes-Actor` record them
|
|
30
|
+
* **`POST /datanotes/tool-calls/record/`**: records a tool call on the change feed, with `served_by` naming who served it
|
|
31
|
+
|
|
32
|
+
Tool calls appear on the change feed as events with `kind: "tool_call"`, sent only to consumers that ask for that kind. The `call` field holds `tool`, `ok`, `served_by`, `duration_ms`, `summary` and `session`, the arguments cut at 300 characters, the value cut at 1,000, and the result’s size in `result_chars` and `result_tokens`.
|
|
33
|
+
|
|
34
|
+
A large result costs less to report when the program cuts it first. The engine answers `takes_summary: true` when it accepts a cut call. Then send the value cut at 1,000 characters, and the result’s `summary` next to it. The event is the same as for the whole call. `datanotes mcp` does this after its first report.
|
|
35
|
+
|
|
36
|
+
## Read who did what
|
|
37
|
+
|
|
38
|
+
Three operations read the record:
|
|
39
|
+
|
|
40
|
+
* **`list_migrations`**: the journal, newest first, each write with `by`, the actor’s name
|
|
41
|
+
* **`describe_history`**: the commits of one table or of every table, with the full actor; it needs history on
|
|
42
|
+
* **`list_changes`**: every change with its actor, and with `kinds: ["tool_call"]` every tool call an MCP server reported
|
|
43
|
+
|
|
44
|
+
`restore_database` with `before_migration` brings every table back to the moment before an agent’s first write: [Restore a table or the database](https://datanotes.dev/guides/history/restore/) shows it.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Use your Markdown notes as a database
|
|
2
|
+
|
|
3
|
+
> Datanotes runs your vault, a folder of Markdown notes, as typed database tables for you and your agents.
|
|
4
|
+
|
|
5
|
+
Datanotes turns the notes you already keep into typed tables that you, your programs and your agents share. The engine checks every write. Every write through the engine is journaled and can be undone.
|
|
6
|
+
|
|
7
|
+
- [Get Started](https://datanotes.dev/start/quick-start/)
|
|
8
|
+
- [Connect an Agent](https://datanotes.dev/start/connect-agents/)
|
|
9
|
+
|
|
10
|
+
## Why use Datanotes
|
|
11
|
+
|
|
12
|
+
Your notes stay plain Markdown files. The engine adds what a database gives you.
|
|
13
|
+
|
|
14
|
+
* [Tables from your notes](https://datanotes.dev/guides/database-objects/tables/)
|
|
15
|
+
|
|
16
|
+
Each note with a `table` property is a row. One file, `metastore.yaml`, defines the columns.
|
|
17
|
+
|
|
18
|
+
* [Every write checked](https://datanotes.dev/guides/data-quality/validation/)
|
|
19
|
+
|
|
20
|
+
The engine checks types, links, unique values and CHECK rules. It refuses a bad write and changes nothing.
|
|
21
|
+
|
|
22
|
+
* [All or nothing, with many clients](https://datanotes.dev/develop/concurrency/)
|
|
23
|
+
|
|
24
|
+
Agents, programs and your phone write at the same time. Each write is checked on the latest data and applies whole or not at all.
|
|
25
|
+
|
|
26
|
+
* [Joins, views and bases](https://datanotes.dev/guides/read-and-write/joins-and-aggregates/)
|
|
27
|
+
|
|
28
|
+
Filter, join and aggregate rows. Save a query as a view, and share columns through bases.
|
|
29
|
+
|
|
30
|
+
* [History, time travel and undo](https://datanotes.dev/guides/history/journal-and-undo/)
|
|
31
|
+
|
|
32
|
+
The journal records every write through the engine and who made it. Undo a write, or, with history on, read a table as it was last week.
|
|
33
|
+
|
|
34
|
+
* [Made for agents](https://datanotes.dev/start/connect-agents/)
|
|
35
|
+
|
|
36
|
+
Claude, Cursor and Codex call every operation through the Model Context Protocol (MCP). Each refusal says how to fix the call.
|
|
37
|
+
|
|
38
|
+
* [HTTP API and client](https://datanotes.dev/develop/http-api/)
|
|
39
|
+
|
|
40
|
+
Programs call the same operations over HTTP, or from JavaScript with `datanotes/client`.
|
|
41
|
+
|
|
42
|
+
* [Search by text, meaning and links](https://datanotes.dev/guides/search/text/)
|
|
43
|
+
|
|
44
|
+
Search the text of every note, find notes by meaning, and walk the links between them.
|
|
45
|
+
|
|
46
|
+
* [Git sync and store backup](https://datanotes.dev/administration/git-sync/)
|
|
47
|
+
|
|
48
|
+
The engine commits and pushes your vault with git. A private repository backs up undo and history too.
|
|
49
|
+
|
|
50
|
+
* [Edit notes by hand](https://datanotes.dev/guides/data-quality/hand-edits/)
|
|
51
|
+
|
|
52
|
+
Use Obsidian, VS Code or git. The engine checks each edit and reports what it breaks.
|
|
53
|
+
|
|
54
|
+
## What you can build
|
|
55
|
+
|
|
56
|
+
The guides build one example you can follow: a diary of classic films in the public domain.
|
|
57
|
+
|
|
58
|
+
* [A second brain for your agent](https://datanotes.dev/guides/agents/how-agents-use-datanotes/)
|
|
59
|
+
|
|
60
|
+
Tell your agent you watched Metropolis with Anna. It logs the viewing and finds it when you ask next month.
|
|
61
|
+
|
|
62
|
+
* [Databases in your notes](https://datanotes.dev/guides/database-objects/relations/)
|
|
63
|
+
|
|
64
|
+
Keep films, actors, genres and viewings as linked tables. Every row stays a note you can open and edit.
|
|
65
|
+
|
|
66
|
+
* [Apps over your vault](https://datanotes.dev/develop/build-an-app/)
|
|
67
|
+
|
|
68
|
+
Build film night, a TypeScript app that lists the films to watch and logs each viewing.
|
|
69
|
+
|
|
70
|
+
* [Several agents, one memory](https://datanotes.dev/guides/security/tokens/)
|
|
71
|
+
|
|
72
|
+
Give each agent and script its own token. The journal shows which one wrote what.
|
|
73
|
+
|
|
74
|
+
## Run it on your notes
|
|
75
|
+
|
|
76
|
+
You need Node.js 22 or newer and a folder for your database: an empty one, or a folder of notes.
|
|
77
|
+
|
|
78
|
+
1. Start the engine on your folder:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npx -y datanotes serve --database your_database_folder
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
2. Connect your agent. This command adds Datanotes to Claude Code, and [Connect your agents](https://datanotes.dev/start/connect-agents/) covers Cursor, Codex and others:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
claude mcp add datanotes -- \
|
|
88
|
+
npx -y datanotes mcp --database your_database_folder
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
3. Ask in your own words:
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
Make a table of the classic films I watch, then add Nosferatu (1922).
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Then read the page that fits what you want to do next:
|
|
98
|
+
|
|
99
|
+
* [Run Datanotes on your notes](https://datanotes.dev/start/quick-start/)
|
|
100
|
+
|
|
101
|
+
Create a table, add a row and see a refusal.
|
|
102
|
+
|
|
103
|
+
* [Prompts for your agent](https://datanotes.dev/guides/agents/prompts/)
|
|
104
|
+
|
|
105
|
+
Prompts to copy, with the tools they call.
|
|
106
|
+
|
|
107
|
+
* [Build on Datanotes](https://datanotes.dev/develop/build-on-datanotes/)
|
|
108
|
+
|
|
109
|
+
Programs, apps and your own MCP server.
|
|
110
|
+
|
|
111
|
+
* [How it works](https://datanotes.dev/start/how-it-works/)
|
|
112
|
+
|
|
113
|
+
Tables, rows, the journal and the store.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Datanotes
|
|
2
|
+
|
|
3
|
+
> The engine of your second brain: Markdown notes as database tables, for you and your agents.
|
|
4
|
+
|
|
5
|
+
Datanotes runs a folder of Markdown notes as typed database tables defined in `metastore.yaml`, for people, programs and AI agents. The engine (`npx datanotes serve`) exposes an HTTP API; `datanotes/client` calls it from JavaScript; agents connect through its MCP server, `npx datanotes mcp`. Every write is validated, journaled and undoable.
|
|
6
|
+
|
|
7
|
+
Every page of the site is also published as Markdown: add `.md` to its path (`https://datanotes.dev/start/quick-start.md` for `https://datanotes.dev/start/quick-start/`; the home page is `https://datanotes.dev/index.md`), or ask for the page itself with `Accept: text/markdown`.
|
|
8
|
+
|
|
9
|
+
## Documentation Sets
|
|
10
|
+
|
|
11
|
+
- [Abridged documentation](https://datanotes.dev/llms-small.txt): a compact version of the documentation for Datanotes, with non-essential content removed
|
|
12
|
+
- [Complete documentation](https://datanotes.dev/llms-full.txt): the full documentation for Datanotes
|
|
13
|
+
- [Get started](https://datanotes.dev/_llms-txt/get-started.txt): what Datanotes is, running the engine on your notes, connecting agents, and how the engine works
|
|
14
|
+
- [Database objects](https://datanotes.dev/_llms-txt/database-objects.txt): catalogs and schemas, tables, columns and types, views, bases, relations and hierarchies, with the engine's real answers
|
|
15
|
+
- [Data quality](https://datanotes.dev/_llms-txt/data-quality.txt): validation of every write, CHECK constraints, hand edits, check_table and a vault synced between devices
|
|
16
|
+
- [Read and write data](https://datanotes.dev/_llms-txt/read-and-write-data.txt): filters, joins and aggregates, writing and moving rows, automatic links, batches, importing existing notes
|
|
17
|
+
- [Search](https://datanotes.dev/_llms-txt/search.txt): reading and searching notes, semantic search, the link graph
|
|
18
|
+
- [History and recovery](https://datanotes.dev/_llms-txt/history-and-recovery.txt): the journal and undo, table history and time travel, the change data feed, restores and vacuum
|
|
19
|
+
- [Agents](https://datanotes.dev/_llms-txt/agents.txt): how an agent works with the vault, prompts with the tools they call, reading errors, the docs offline
|
|
20
|
+
- [Security](https://datanotes.dev/_llms-txt/security.txt): named tokens and permissions, who did what, the security model
|
|
21
|
+
- [Develop](https://datanotes.dev/_llms-txt/develop.txt): HTTP API, JavaScript client, concurrent writes, building an app or your own MCP server, the change feed and webhooks, telemetry
|
|
22
|
+
- [Operations reference](https://datanotes.dev/_llms-txt/operations-reference.txt): every operation of the API (also the MCP tools), by kind, with its parameters
|
|
23
|
+
- [Administration](https://datanotes.dev/_llms-txt/administration.txt): running the service, Docker, git sync, datanotes status, configuration
|
|
24
|
+
|
|
25
|
+
## Notes
|
|
26
|
+
|
|
27
|
+
- The complete documentation includes all content from the official documentation
|
|
28
|
+
- The content is automatically generated from the same source as the official documentation
|
|
29
|
+
|
|
30
|
+
## Optional
|
|
31
|
+
|
|
32
|
+
- [Connect agents](https://datanotes.dev/start/connect-agents.md): how an agent reaches the engine: the MCP server datanotes mcp, its configuration in MCP clients, and named tokens for agents
|
|
33
|
+
- [OpenAPI](https://datanotes.dev/openapi.json): OpenAPI 3.1 description of the /datanotes/* routes
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Command line
|
|
2
|
+
|
|
3
|
+
> The datanotes command and its options.
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
datanotes 3.1.0: Markdown notes as database tables, for you and your agents.
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
datanotes serve --database <folder> [options] run the engine and its HTTP API (/datanotes/*)
|
|
11
|
+
datanotes status --database <folder> [--json] the running engine's health
|
|
12
|
+
datanotes stop --database <folder> [--timeout-s <s>] stop the running engine gracefully
|
|
13
|
+
datanotes store path --database <folder> where the engine keeps the database's store
|
|
14
|
+
datanotes store new-id --database <folder> a new database id (a copied folder gets its own store)
|
|
15
|
+
datanotes store backup --database <folder> show or set the store's git backup (--remote <url>, --off)
|
|
16
|
+
datanotes store restore --from <url> --database <folder> restore the store from its git backup
|
|
17
|
+
datanotes store convert-log --to <files|segments> --database <folder> rewrite the transaction log in that format
|
|
18
|
+
Every command takes --vault <folder> instead of --database for a vault holding the database.
|
|
19
|
+
datanotes mcp --database <folder> MCP server over stdio, on the engine running on the folder
|
|
20
|
+
(or one it starts for the session)
|
|
21
|
+
datanotes mcp --url <url> --token-file <f> MCP server over stdio, on an engine at an address
|
|
22
|
+
datanotes mcp serve [options] MCP server over Streamable HTTP at /mcp (each agent sends its token)
|
|
23
|
+
datanotes --version | --help
|
|
24
|
+
dnotes is a short name for datanotes: every command works under both names.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
Options of serve:
|
|
28
|
+
--database <folder> the database folder (or DATANOTES_DATABASE): metastore.yaml at its
|
|
29
|
+
root (created there for a new database); paths start with the catalog
|
|
30
|
+
--vault <folder> or a vault holding the database (or DATANOTES_VAULT), for apps such as
|
|
31
|
+
Obsidian: the database is the folder of the vault's one metastore.yaml
|
|
32
|
+
(a new database: datanotes/); paths start at the vault's root
|
|
33
|
+
--store <folder> the engine's store (or DATANOTES_STORE; default <data home>/<database id>)
|
|
34
|
+
--settings <file> settings file (or DATANOTES_SETTINGS; default settings.json in the store)
|
|
35
|
+
--host <address> listen address (or DATANOTES_HOST; default 127.0.0.1)
|
|
36
|
+
--port <port> HTTP port for this run (or DATANOTES_PORT; default: the setting
|
|
37
|
+
httpServerPort, 27150); 0 for any free port, printed at start
|
|
38
|
+
--watch events|poll how file changes are seen (or DATANOTES_WATCH; default events)
|
|
39
|
+
--poll-ms <ms> poll interval (or DATANOTES_POLL_MS; default 3000)
|
|
40
|
+
--embedding-key-file <file> file with the API key of the embedding provider (or DATANOTES_EMBEDDING_KEY_FILE;
|
|
41
|
+
DATANOTES_EMBEDDING_KEY gives the key itself)
|
|
42
|
+
--git-sync commit, pull and push the vault (or DATANOTES_GIT_SYNC=1; --git-no-push)
|
|
43
|
+
--git-interval-min <min> minutes between two syncs (or DATANOTES_GIT_INTERVAL_MIN; default 10)
|
|
44
|
+
--git-quiet-s <s> a sync also <s> seconds after the last write (or DATANOTES_GIT_QUIET_S; default 60)
|
|
45
|
+
DATANOTES_GIT_NETWORK_TIMEOUT_S: the time limit of a pull or push (default 600)
|
|
46
|
+
--store-backup back up the store to git for this run (or DATANOTES_STORE_BACKUP=1; the
|
|
47
|
+
setting storeBackupEnabled keeps it on; --no-store-backup or =0 turns it off)
|
|
48
|
+
--store-backup-remote <url> the store backup's git remote; turns the backup on
|
|
49
|
+
(or DATANOTES_STORE_BACKUP_REMOTE; default: the setting storeBackupRemote)
|
|
50
|
+
--store-backup-interval-s <s> every <s> seconds (at least 10), when the store changed: a commit
|
|
51
|
+
between two operations, then a push (or DATANOTES_STORE_BACKUP_INTERVAL_S;
|
|
52
|
+
default: the setting storeBackupIntervalSeconds, 60)
|
|
53
|
+
--log <file> append console output to a file
|
|
54
|
+
DATANOTES_INDEX_CHECK=1: check the engine's indexes against the vault
|
|
55
|
+
after every operation, and log any difference as an error (slow: debugging)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
Options of status (the engine is found through the lock in its store, called with the owner's token):
|
|
59
|
+
--database <folder> the database folder (or DATANOTES_DATABASE; --vault <folder> for a vault)
|
|
60
|
+
--store <folder> the engine's store, when serve was given one (or DATANOTES_STORE)
|
|
61
|
+
--settings <file> settings file with the owner's token (or DATANOTES_SETTINGS;
|
|
62
|
+
default settings.json in the store)
|
|
63
|
+
--url <url> --token <token> call this engine instead, e.g. on another machine (or DATANOTES_URL, DATANOTES_TOKEN)
|
|
64
|
+
--json the report as JSON
|
|
65
|
+
Exit codes: 0 healthy; 1 needs attention (git sync blocked, store backup failing, a webhook failing, change feed not
|
|
66
|
+
running, hand edits breaking the tables' rules in the last 24 h); 2 no engine running on the folder (or
|
|
67
|
+
not reachable); 3 an engine runs but its status could not be read (no owner token, token refused, an error).
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Options of stop (the engine finishes the requests under way, makes its last git sync and store backup
|
|
71
|
+
commit and push, releases its lock and exits):
|
|
72
|
+
--database <folder> the database folder (or DATANOTES_DATABASE; --vault <folder> for a vault)
|
|
73
|
+
--store <folder> the engine's store, when serve was given one (or DATANOTES_STORE)
|
|
74
|
+
--settings <file> settings file with the owner's token (or DATANOTES_SETTINGS;
|
|
75
|
+
default settings.json in the store)
|
|
76
|
+
--url <url> --token <token> stop this engine instead (or DATANOTES_URL, DATANOTES_TOKEN)
|
|
77
|
+
--timeout-s <seconds> how long to wait for the engine to exit (default 60)
|
|
78
|
+
--json the report as JSON
|
|
79
|
+
Exit codes: 0 stopped; 1 not stopped (not answering, or still running after the timeout: stop it by
|
|
80
|
+
force); 2 no engine running on the folder; 3 the stop could not be asked (another machine, still
|
|
81
|
+
starting, token refused).
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
Options of store:
|
|
85
|
+
--database <folder> the database folder (or DATANOTES_DATABASE; --vault <folder> for a vault)
|
|
86
|
+
--json store path, store backup, store convert-log: the answer as JSON
|
|
87
|
+
--remote <url> store backup: turn it on, pushing to this git repository (a first push now)
|
|
88
|
+
--ssh-command <cmd> store backup, with --remote: the store repository's core.sshCommand
|
|
89
|
+
(default: the vault repository's), e.g. C:/Windows/System32/OpenSSH/ssh.exe
|
|
90
|
+
--interval-s <seconds> store backup: every <seconds> (at least 10, default 60), when the
|
|
91
|
+
store changed: a commit between two operations, then a push
|
|
92
|
+
--off store backup: turn it off (the store's repository stays)
|
|
93
|
+
--from <url> store restore: the git repository of the store backup
|
|
94
|
+
--port <port> store restore: the HTTP port in the new settings (default 27150)
|
|
95
|
+
--force store restore: restore over a store that exists (kept aside, renamed)
|
|
96
|
+
--no-backup store restore: leave the store backup off in the new settings
|
|
97
|
+
--to <files|segments> store convert-log: segments (a few large files) or files (one per
|
|
98
|
+
version, what Datanotes 3.0 reads); sets transactionLogFormat
|
|
99
|
+
new-id, backup, restore and convert-log run only while no engine runs on the database, and
|
|
100
|
+
hold its store while they run: an engine started meanwhile refuses to start.
|
|
101
|
+
The data home holds one store per database: %LOCALAPPDATA%\Datanotes (Windows),
|
|
102
|
+
~/Library/Application Support/Datanotes (macOS), $XDG_DATA_HOME/datanotes or
|
|
103
|
+
~/.local/share/datanotes (Linux); DATANOTES_DATA_HOME moves it.
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
Options of mcp (stdio):
|
|
107
|
+
--database <folder> the database folder (or DATANOTES_DATABASE); acts with the owner's token,
|
|
108
|
+
and stops the engine it started when the client closes
|
|
109
|
+
--vault <folder> or a vault holding the database (or DATANOTES_VAULT)
|
|
110
|
+
--url <url> the engine's address (or DATANOTES_URL), with
|
|
111
|
+
--token-file <file> a file holding the token (or DATANOTES_TOKEN_FILE, or the token in DATANOTES_TOKEN)
|
|
112
|
+
DATANOTES_ENGINE_START_TIMEOUT_S: how long --database waits for the engine
|
|
113
|
+
it starts, in seconds (default 60; a large database starts slowly)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
Options of mcp serve:
|
|
117
|
+
--url <url> the engine (default http://127.0.0.1:27150, or DATANOTES_URL)
|
|
118
|
+
--host <address> listen address (default 127.0.0.1, or DATANOTES_MCP_HOST)
|
|
119
|
+
--port <n> port (default 27151, or DATANOTES_MCP_PORT)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
Tools of mcp (both modes; default: every tool except create_webhook and delete_webhook):
|
|
123
|
+
--profile <name> read (read-only tools), write (no schema changes, no webhooks) or
|
|
124
|
+
all (every tool, webhooks included) (or DATANOTES_MCP_PROFILE)
|
|
125
|
+
--tools <names> only these tools, separated by commas (or DATANOTES_MCP_TOOLS)
|
|
126
|
+
--except <names> none of these tools, separated by commas (or DATANOTES_MCP_EXCEPT)
|
|
127
|
+
--owner-tools also offer create_webhook and delete_webhook
|
|
128
|
+
(or DATANOTES_MCP_OWNER_TOOLS=1)
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
Logs of mcp (both modes):
|
|
132
|
+
--otlp-endpoint <url> export logs over OTLP/HTTP, e.g. http://127.0.0.1:4318 (or the standard
|
|
133
|
+
OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_SERVICE_NAME)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
Docs of mcp (both modes): the tools list_docs, read_docs and search_docs read the docs of this
|
|
137
|
+
version from the package (dist/docs), or from the folder in DATANOTES_DOCS_DIR; search_docs also
|
|
138
|
+
ranks them by meaning when the engine has semantic search on (hybrid search)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
Agents connect through the MCP server: npx -y datanotes mcp (https://datanotes.dev/start/connect-agents/).
|
|
142
|
+
Docs: https://datanotes.dev
|
|
143
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Compatibility
|
|
2
|
+
|
|
3
|
+
> How Datanotes numbers its versions, what counts as its public interface, and how to write clients that keep working.
|
|
4
|
+
|
|
5
|
+
Datanotes follows [semantic versioning](https://semver.org). The version number tells you what an update can change.
|
|
6
|
+
|
|
7
|
+
## Versions
|
|
8
|
+
|
|
9
|
+
* **Major** (4.0.0): can change or remove parts of the public interface. The release notes list those changes first, with what to do.
|
|
10
|
+
* **Minor** (3.1.0): adds to the public interface without breaking what works.
|
|
11
|
+
* **Patch** (3.0.1): fixes bugs and changes nothing you rely on.
|
|
12
|
+
|
|
13
|
+
The [release notes](https://datanotes.dev/release-notes/) describe every version.
|
|
14
|
+
|
|
15
|
+
## The public interface
|
|
16
|
+
|
|
17
|
+
These parts of Datanotes follow the version rules:
|
|
18
|
+
|
|
19
|
+
* Operations, their arguments and their answer fields
|
|
20
|
+
* HTTP routes and headers
|
|
21
|
+
* Violation codes
|
|
22
|
+
* The commands the package installs (`datanotes` and `dnotes`), their options and their exit codes
|
|
23
|
+
* Environment variables and settings
|
|
24
|
+
* The words of `metastore.yaml`
|
|
25
|
+
|
|
26
|
+
These cases fall outside them:
|
|
27
|
+
|
|
28
|
+
* **Security fixes**: a fix can change a behavior. The release notes say so.
|
|
29
|
+
* **Bugs**: Datanotes fixes behavior that contradicts the documentation.
|
|
30
|
+
* **Undocumented behavior**: only what the docs describe is covered.
|
|
31
|
+
* **Messages**: the text of refusals and hints can improve in any version.
|
|
32
|
+
* **Node.js versions**: support follows the Node.js long-term support releases.
|
|
33
|
+
|
|
34
|
+
## Downgrade to 3.0
|
|
35
|
+
|
|
36
|
+
From 3.1, the engine writes the transaction log in segments by default. Datanotes 3.0 can’t read segments, so convert the log before you downgrade:
|
|
37
|
+
|
|
38
|
+
1. Stop the engine.
|
|
39
|
+
|
|
40
|
+
2. Convert every table’s log to one file per version:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
datanotes store convert-log --to files --vault ~/notes
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
3. Install Datanotes 3.0 and start it.
|
|
47
|
+
|
|
48
|
+
The command also sets `transactionLogFormat` to `files`, so a 3.1 engine started on the store again keeps writing files. [How the engine writes the log](https://datanotes.dev/start/how-it-works/#how-the-engine-writes-the-log) describes both formats.
|
|
49
|
+
|
|
50
|
+
## Write tolerant clients
|
|
51
|
+
|
|
52
|
+
Answers can gain fields, and enums can gain values. Write your client to accept them:
|
|
53
|
+
|
|
54
|
+
* Ignore fields you don’t know.
|
|
55
|
+
* Handle an enum value you don’t know, for example as “other”.
|
|
56
|
+
* Read refusals by their HTTP status, not by their text.
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { DatanotesClient } from "datanotes/client";
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
const db = new DatanotesClient({
|
|
63
|
+
url: "http://127.0.0.1:27150",
|
|
64
|
+
token: process.env.DATANOTES_TOKEN ?? "",
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
type Created = { planned_creates: string[] };
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
const r = await db.call("insert_row", {
|
|
72
|
+
table: "film",
|
|
73
|
+
values: { title: "Metropolis" },
|
|
74
|
+
});
|
|
75
|
+
// read the fields you need: new ones may appear
|
|
76
|
+
if (r.ok) console.log((r.value as Created).planned_creates);
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## How the tests check it
|
|
80
|
+
|
|
81
|
+
The repository keeps the public interface in `contract/datanotes-3.txt`. It has one line for every operation, argument, answer field, route, installed command, command option, environment variable, setting and violation code.
|
|
82
|
+
|
|
83
|
+
The test suite fails when a line goes or changes within a major version, so a breaking change cannot ship by accident. A second test checks every new name against the naming rules.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Errors
|
|
2
|
+
|
|
3
|
+
> Every kind of error the engine and the MCP server answer, with its status, what its hint gives and the page its docs link names.
|
|
4
|
+
|
|
5
|
+
Every error of the engine says three things: what is wrong (`error`), how to fix it (`hint`) and where to read more (`docs`, a page of this site in Markdown, with its anchor). The HTTP API sends them as JSON fields; the MCP server and `DatanotesError` end the text with a `Hint:` and a `Docs:` line. The docs line of `DatanotesError` gives the address, then the `read_docs` call that reads the same section offline; `datanotes mcp` gives only the call:
|
|
6
|
+
|
|
7
|
+
```text
|
|
8
|
+
insert_row refused — nothing was written:
|
|
9
|
+
invalid datanotes/main/public/film/Sunrise.md: status must be one of: to watch; watched
|
|
10
|
+
Hint: Use one of the allowed values listed in the message, written exactly; describe_table shows what each one means. To add a value, alter_column the enum.
|
|
11
|
+
Docs: https://datanotes.dev/guides/database-objects/columns.md#describe-what-each-enum-value-means (offline: read_docs("guides/database-objects/columns#describe-what-each-enum-value-means"))
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
[Read the engine’s errors](https://datanotes.dev/guides/agents/reading-errors/) shows how an agent uses them.
|
|
15
|
+
|
|
16
|
+
## Kinds of error
|
|
17
|
+
|
|
18
|
+
| Error | Status | The hint gives | Docs |
|
|
19
|
+
| ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
20
|
+
| Unknown tool or operation | MCP tool error; 400 | The closest tools | [Operations](https://datanotes.dev/reference/operations/) |
|
|
21
|
+
| Argument unknown, missing or of the wrong type | MCP tool error, before the call | The argument meant, and the tool’s arguments with their types | The operation’s reference |
|
|
22
|
+
| Bad input to an operation or a route | 400 | Its own where the answer is data, else the operation’s arguments | The topic’s page, or the operation’s reference |
|
|
23
|
+
| Table or view not found | 404 | The closest names and aliases, the tables and views, or the view’s table where a table is needed | [Find the table that matches a request](https://datanotes.dev/guides/database-objects/tables/#find-the-table-that-matches-a-request), [Store a query as a view](https://datanotes.dev/guides/database-objects/views/#store-a-query-as-a-view) |
|
|
24
|
+
| Ambiguous table name | 409 | The full names | [Place tables in catalogs and schemas](https://datanotes.dev/guides/database-objects/catalogs-and-schemas/#place-tables-in-catalogs-and-schemas) |
|
|
25
|
+
| Unknown column | 400 | The closest column, the table’s columns, `describe_table` and `add_column` | [Describe a table before writing to it](https://datanotes.dev/guides/database-objects/tables/#describe-a-table-before-writing-to-it) |
|
|
26
|
+
| Unknown filter operator | 400 | The operator meant, every operator, and the shape of a condition | [Compare values with operators](https://datanotes.dev/guides/read-and-write/read-and-filter/#compare-values-with-operators) |
|
|
27
|
+
| Bad expression or aggregate | 400 | The columns and the shape | [Group rows and compute totals](https://datanotes.dev/guides/read-and-write/joins-and-aggregates/#group-rows-and-compute-totals) |
|
|
28
|
+
| Unknown base, constraint, catalog, schema, enum value or link column | 400 | The closest name, the list, and the operation that lists them | The topic’s page |
|
|
29
|
+
| A name that isn’t an identifier | 400 | The name it could be | [Place tables in catalogs and schemas](https://datanotes.dev/guides/database-objects/catalogs-and-schemas/#place-tables-in-catalogs-and-schemas) |
|
|
30
|
+
| A table, base or column without a description, or one removed | 400 | Every missing description, and the call’s shape with each in place | [Describe every table and column](https://datanotes.dev/guides/database-objects/tables/#describe-every-table-and-column) |
|
|
31
|
+
| Row not found | 400 | The closest note name, and how to find a row’s `path` or `id` | [Update one row](https://datanotes.dev/guides/read-and-write/write-rows/#update-one-row) |
|
|
32
|
+
| A value breaks a rule (a violation) | 422 | The hint of its kind: [Violations](#violations) | The page of its kind |
|
|
33
|
+
| A conflict: `expect`, linked rows, rows that break a new CHECK, a column others read, `cascade`, a name taken, merge keys | 422 | What the conflict means and what to do | [Guard a write against concurrent edits with `expect`](https://datanotes.dev/guides/read-and-write/write-rows/#guard-a-write-against-concurrent-edits-with-expect), [Delete a row that other notes link to](https://datanotes.dev/guides/database-objects/relations/#delete-a-row-that-other-notes-link-to), [Enforce rules with CHECK constraints](https://datanotes.dev/guides/data-quality/check-constraints/#enforce-rules-with-check-constraints), [Drop a table and archive its rows](https://datanotes.dev/guides/database-objects/tables/#drop-a-table-and-archive-its-rows), [Insert or update rows with `merge_rows`](https://datanotes.dev/guides/read-and-write/write-rows/#insert-or-update-rows-with-merge_rows) |
|
|
34
|
+
| A write that failed partway, rolled back by the engine | 503, with the result as the body | Free the file, then send the write again | [The engine rolls back a write it cannot finish](https://datanotes.dev/guides/history/journal-and-undo/#the-engine-rolls-back-a-write-it-cannot-finish) |
|
|
35
|
+
| A write that failed partway, and its rollback too | 500, with the result as the body | `undo_migration` | [Undo a write](https://datanotes.dev/guides/history/journal-and-undo/#undo-a-write) |
|
|
36
|
+
| Undo refused, or migration not found | 409, 404 | Undone already, the later changes, `list_migrations` | [Undo a write](https://datanotes.dev/guides/history/journal-and-undo/#undo-a-write), [Undo refuses to overwrite later changes](https://datanotes.dev/guides/history/journal-and-undo/#undo-refuses-to-overwrite-later-changes) |
|
|
37
|
+
| No history, no such version, a time before the table existed | 400 | `alter_table` with `history: "on"`, `describe_history`, `timestamp` | [Turn history on for a table](https://datanotes.dev/guides/history/table-history/#turn-history-on-for-a-table), [List the versions of a table](https://datanotes.dev/guides/history/table-history/#list-the-versions-of-a-table) |
|
|
38
|
+
| A batch with an operation refused or unknown | 422, 400 | Each operation’s own; fix it and send the whole batch again | [Group several writes with `batch`](https://datanotes.dev/guides/read-and-write/batch/#group-several-writes-with-batch) |
|
|
39
|
+
| A token beyond its permissions | 403 | The permissions, and who changes them | [Choose what a token can do](https://datanotes.dev/guides/security/tokens/#choose-what-a-token-can-do) |
|
|
40
|
+
| Token missing or wrong | 401 | Which token to send, as a bearer token | [Authenticate your requests](https://datanotes.dev/develop/http-api/#authenticate-your-requests) |
|
|
41
|
+
| Unknown operation, route, argument, method or body | 404, 400, 405 | The closest operation, route or argument, and the routes in `openapi.json` | [Call the engines routes](https://datanotes.dev/develop/http-api/#call-the-engines-routes) |
|
|
42
|
+
| Note or folder not found | 404 | Vault paths, `list_folder` and `search_notes` | [Read a note](https://datanotes.dev/guides/search/text/#read-a-note) |
|
|
43
|
+
| Change feed, webhooks or semantic search off | 400, 503 | How to turn it on | [Follow every change with the change feed](https://datanotes.dev/guides/history/change-data-feed/#follow-every-change-with-the-change-feed), [Turn on semantic search](https://datanotes.dev/guides/search/semantic/#turn-on-semantic-search) |
|
|
44
|
+
| Engine unreachable | Thrown by the client; 502 from the MCP server | Start the engine, or check its address | [How the mcp server reaches the engine](https://datanotes.dev/start/connect-agents/#how-the-mcp-server-reaches-the-engine) |
|
|
45
|
+
| The engine can’t listen: a port in use or reserved, an address of another machine | Exit code 1 of `datanotes serve` | Another `--port`, `--port 0`, or an address of this machine | [Choose the port](https://datanotes.dev/administration/run-the-service/#choose-the-port) |
|
|
46
|
+
| A request while the engine stops | 503 | Wait for the stop, then start the engine again | [Stop the engine](https://datanotes.dev/administration/run-the-service/#stop-the-engine) |
|
|
47
|
+
| Unexpected error | 500 | None: it isn’t a mistake of the caller | None |
|
|
48
|
+
|
|
49
|
+
A refused write writes nothing, so the caller can fix the call and send it again. Hand edits that break a rule aren’t errors: `check_table` and the change feed report them as violations.
|
|
50
|
+
|
|
51
|
+
## Violations
|
|
52
|
+
|
|
53
|
+
A write the engine refuses lists its violations, each with a `code`; `check_table` and the change feed report the violations of hand edits with the same codes.
|
|
54
|
+
|
|
55
|
+
| Code | Hint | Docs |
|
|
56
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
57
|
+
| `required` | Give a value to every required column; describe_table marks them (required: true) and lists an enum’s values. | [Describe a table before writing to it](https://datanotes.dev/guides/database-objects/tables/#describe-a-table-before-writing-to-it) |
|
|
58
|
+
| `type` | Give each value the column’s type (describe_table shows it): numbers unquoted, dates as YYYY-MM-DD, links as “\[\[Note]]”, lists as JSON arrays. | [Create a table with typed columns](https://datanotes.dev/guides/database-objects/tables/#create-a-table-with-typed-columns) |
|
|
59
|
+
| `enum` | Use one of the allowed values listed in the message, written exactly; describe_table shows what each one means. To add a value, alter_column the enum. | [Describe what each enum value means](https://datanotes.dev/guides/database-objects/columns/#describe-what-each-enum-value-means) |
|
|
60
|
+
| `vocabulary` | Use one of the values listed in the message, or first insert the new value as a row of the vocabulary table. | [Take allowed values from another table](https://datanotes.dev/guides/database-objects/relations/#take-allowed-values-from-another-table) |
|
|
61
|
+
| `min` | Give a value inside the column’s range (the message names the bound); describe_table shows its min and max. | [Describe a table before writing to it](https://datanotes.dev/guides/database-objects/tables/#describe-a-table-before-writing-to-it) |
|
|
62
|
+
| `max` | Give a value inside the column’s range (the message names the bound); describe_table shows its min and max. | [Describe a table before writing to it](https://datanotes.dev/guides/database-objects/tables/#describe-a-table-before-writing-to-it) |
|
|
63
|
+
| `step` | Give a multiple of the column’s step (describe_table shows it). | [Describe a table before writing to it](https://datanotes.dev/guides/database-objects/tables/#describe-a-table-before-writing-to-it) |
|
|
64
|
+
| `broken_link` | Link to a note that exists, as “\[\[Note name]]”: list_link_targets(table, column) lists the rows the column may point to. | [Point a column to a row of another table](https://datanotes.dev/guides/database-objects/relations/#point-a-column-to-a-row-of-another-table) |
|
|
65
|
+
| `ref` | Link to a row of the table the column points to (its ref) that its ref_where / ref_by allow: list_link_targets(table, column) lists them. | [Limit link targets with `ref_by` and `ref_where`](https://datanotes.dev/guides/database-objects/relations/#limit-link-targets-with-ref_by-and-ref_where) |
|
|
66
|
+
| `unique` | Another row already has this value: choose another one, or update that row instead (select_rows finds it). | [Update one row](https://datanotes.dev/guides/read-and-write/write-rows/#update-one-row) |
|
|
67
|
+
| `unknown_column` | Write only the table’s columns: describe_table lists them. To keep a new front matter key, add_column first. | [Describe a table before writing to it](https://datanotes.dev/guides/database-objects/tables/#describe-a-table-before-writing-to-it) |
|
|
68
|
+
| `check` | The row breaks a CHECK constraint of the table (named in the message, with its rule): change the values so the rule holds. describe_table lists the table’s constraints. | [Enforce rules with CHECK constraints](https://datanotes.dev/guides/data-quality/check-constraints/#enforce-rules-with-check-constraints) |
|
|
69
|
+
| `generated` | A generated column is computed by the engine: do not write it; recompute_columns sets it again. | [Recompute generated columns after a hand edit](https://datanotes.dev/guides/data-quality/hand-edits/#recompute-generated-columns-after-a-hand-edit) |
|
|
70
|
+
| `cycle` | A row cannot be its own ancestor: point the hierarchy column to a row that is not below this one. | [Build a tree of rows with a parent link](https://datanotes.dev/guides/database-objects/relations/#build-a-tree-of-rows-with-a-parent-link) |
|
|
71
|
+
| `inverse` | Both sides of a two-way link must agree: write one side, or run align_relations to repair them. | [Repair two-way links with `align_relations`](https://datanotes.dev/guides/database-objects/relations/#repair-two-way-links-with-align_relations) |
|
|
72
|
+
| `unreadable` | The note’s front matter is not valid YAML (the message quotes the parser), so every read leaves the row out: open the note and fix the YAML, such as a quote or bracket left open or a line without `key: value`. read_note shows its text. | [Find rows whose front matter can’t be read](https://datanotes.dev/guides/data-quality/hand-edits/#find-rows-whose-front-matter-cant-be-read) |
|