> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dexi.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Tools

> The eighteen Dexi MCP tools, their parameters, and return shapes

Ten read tools (scope `notes:read`), six write tools (`notes:write`), and two spaced-repetition tools. Errors come back as MCP tool errors with a plain-language message (`Note not found`, `Folder not found: X`, …).

Every tool also accepts an optional `intent` parameter (string, ≤ 300 chars, omitted from the per-tool tables below): one short sentence on what the agent is trying to accomplish for the user. It never changes the tool's behavior — Dexi records it, along with the tool name and call outcome, to understand how the tools are used in aggregate and improve them. Tool arguments and note content are not recorded. Keep personal details out of it.

## Access restrictions

A connection may be [restricted](/mcp/oauth#access-restrictions) to notes in one folder, notes with one tag, or both. Inside a boundary:

* Every read tool sees only the user's **own** in-boundary notes (teammates' shared notes are excluded); out-of-boundary notes behave exactly like nonexistent ones (`Note not found`, `Folder not found`).
* `list_tags` and `list_folders` cover only in-boundary content — folder names and tags outside the boundary never appear.
* `create_note` keeps writes inside the boundary automatically: notes are filed into the restricted folder, and the restricted tag is appended to the text when missing.
* `update_note` refuses edits that would remove the restricted tag from a note (the error names the tag); deletes work only on in-boundary notes.
* Review tools cover only in-boundary cards.

## The note item

List and search tools return items in one shared shape:

```json Note item theme={null}
{
  "id": "2982e9b4-19fe-40fd-9a69-e23d45e53b13",
  "title": "Attention is all you need",
  "snippet": "Reading notes on the transformer paper — the key insight is…",
  "tags": ["@vaswani", "#ml", "#papers"],
  "source": "bookmark",
  "source_url": "https://arxiv.org/abs/1706.03762",
  "created": "2026-07-14T09:12:00+00:00",
  "updated": "2026-08-02T18:40:11+00:00"
}
```

* `snippet` is the first 300 characters of the body (`…` appended when truncated).
* `source` is `note`, `bookmark`, `email`, or `feed`; `source_url` is set for bookmarks and feed articles.
* Conditional keys: `folder` (name, only on your own filed notes), `properties` (the note's inline `key:: value` fields as raw JSON values — see [Bases](#bases); only when the note has any), `shared: true` + `owner` (only on a teammate's team-shared note — read-only for you), and `similarity` (0–1, only from `semantic_search` and `find_similar`).
* With `full_text: true` (accepted by `search_notes`, `semantic_search`, and `list_notes`), `snippet` is replaced by `text` — the body capped at 4,000 characters, with `text_truncated: true` when it was cut — and `size` is capped at 10. Use it to read a handful of results in one call instead of one `get_note` per item.

`get_note`, `create_note`, and `update_note` return the same shape with `snippet` replaced by `text` — the full plain-text body.

## Read tools

### search\_notes

Full-text search over titles and body text, ranked by relevance. Supports web search syntax: `"quoted phrases"`, `OR` between terms, and `-word` to exclude; plain terms must all match. When nothing matches every term, the search retries with any-term matching and sets `relaxed: true` on the response. Covers bookmarks, saved emails, and feed articles too — every item in Dexi is backed by a note. Use `semantic_search` instead when looking for concepts rather than exact words.

A query wrapped in slashes runs as a **regex search** instead: `/colou?r/` matches titles and bodies with a case-insensitive POSIX regular expression (Postgres syntax). Regex results are unranked — newest matches come first — and never trigger the any-term retry. An invalid or pathologically slow pattern returns a tool error naming the problem.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `query` | string | 1–200 chars | required |
| `page` | int | ≥ 1 | 1 |
| `size` | int | 1–50 (≤ 10 with `full_text`) | 10 |
| `full_text` | bool | bodies inline instead of snippets | `false` |

Returns `{items, total, page, relaxed}`.

### semantic\_search

Find notes by meaning using vector embeddings — surfaces conceptually related content even when no words are shared with the query (e.g. "machine learning" matches notes about neural networks). Each result carries a `similarity` score; only results above \~0.55 similarity are returned, so an empty list means nothing conceptually close exists — fall back to `search_notes` for exact words.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `query` | string | 1–500 chars | required |
| `size` | int | 1–50 (≤ 10 with `full_text`) | 10 |
| `full_text` | bool | bodies inline instead of snippets | `false` |

Returns `{items}` (no total/pagination — it's a ranked window).

### list\_notes

Browse newest-first with filters. The right tool for "what did I save this week?" or "what changed since yesterday 9am?"-style questions.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `page` | int | ≥ 1 | 1 |
| `size` | int | 1–50 (≤ 10 with `full_text`) | 10 |
| `source` | enum | `all` `bookmark` `email` `feed` `note` | `all` |
| `tag` | string | `"#hashtag"`, `"@mention"`, or a bare word matching either | — |
| `folder` | string | folder name (case-insensitive) or `"unfiled"`; unknown name errors — call `list_folders` first | — |
| `period` | enum | `today` `yesterday` `week` | — |
| `since` | string | ISO 8601 date or datetime (`2026-08-13`, `2026-08-13T09:00:00Z`); inclusive lower bound on `created`, or on `updated` when `sort` is `updated`. A value without a timezone is read in your profile timezone. Composable with the other filters | — |
| `sort` | enum | `created` `updated` | `created` |
| `full_text` | bool | bodies inline instead of snippets | `false` |

Returns `{items, total, page}`.

### get\_note

Fetch one note in full: complete body text, title, tags, source kind, and source URL.

| Parameter | Type | Constraints |
| - | - | - |
| `note_id` | string | note UUID (from search or list results) |

Returns a full note object (with `text`). Invisible or unknown ids error with `Note not found`.

### find\_similar

The notes most semantically similar to a given note — related reading, duplicates, connected ideas. Each result carries `similarity`.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `note_id` | string | note UUID | required |
| `size` | int | 1–50 | 10 |

Returns `{items}`.

### list\_tags

The user's tags with usage counts, most-used first. Hashtags (`#topic`) categorize subjects; mentions (`@name`) reference people or entities. Tags are parsed automatically from note text — they are not set directly.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `kind` | enum | `hashtag` `mention` | `hashtag` |
| `limit` | int | 1–200 | 50 |

Returns `{tags: [{tag, count}]}`.

### list\_folders

The user's folders with note counts, plus how many notes are unfiled. Folders are personal organization — a note lives in at most one folder (tags handle cross-cutting topics). Pass a folder's name to `list_notes` to browse its contents.

No parameters. Returns `{folders: [{name, note_count}], unfiled_count}`.

## Bases

A base is a saved database-style view over notes: Obsidian-style filters (`status == "reading"`, `file.hasTag("book")`, `file.mtime > now() - "1 week"`) over a note's inline properties, tags, folder, source and dates, plus one or more named views (table, cards, list or map) with their own filters, columns and sort. Users build them in the app (Bases in the sidebar) or import Obsidian `.base` files; `list_bases` and `query_base` let an assistant run one instead of re-implementing a filter the user already saved, and `get_base` / `create_base` / `update_base` / `delete_base` let it manage the definitions themselves ("make me a reading list grouped by topic").

Inline properties are lines of the form `key:: value` in a note's body (`status:: reading`, `due:: 2026-09-10`, `rating:: 4`, `authors:: [A, B]`). Dexi parses them on every save — including notes written through `create_note` / `update_note` — into typed values (number, boolean, ISO date, list, `[[link]]`, `#tag`, else string).

### list\_bases

The user's saved bases with their view names and types.

No parameters. Returns `{bases: [{name, views: [{name, type}]}]}`.

### query\_base

Run a saved base: the base's filters (and the chosen view's own filters) applied to every note the user can see, in the view's sort order.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `name` | string | base name, case-insensitive | required |
| `view` | string | view name within the base | the first view |
| `page` | int | ≥ 1 | 1 |
| `size` | int | 1–50 | 10 |
| `full_text` | bool | see [the note item](#the-note-item) | `false` |

The filter language, property syntax and `.base` format are documented in [Properties and bases](/properties-and-bases). Returns `{base, view, columns: [key…], items: [note item…], total, page}` — `columns` are the view's configured column keys (`file.name`, `rating`, `formula.score`, …), each item carries `properties` when the note has any, and `formulas` (name → computed value) when the base defines formulas. A grouped view adds `group` (the group's label) to each item and a top-level `groups: [{label, count, summaries?}]` in display order; a view with column summaries adds `summaries` (column key → value over the whole result). Errors: `Base not found: X` (call `list_bases`), `Unknown view: X`, or a message when the base's filter is invalid or timed out. Under an [access restriction](#access-restrictions), results are limited to in-boundary notes and definitions are never returned.

### get\_base

A base's full definition — filters, formulas, property display names and views — as JSON and as Obsidian `.base` YAML. Read it before `update_base`.

| Parameter | Type | Constraints |
| - | - | - |
| `name` | string | base name, case-insensitive |

Returns `{name, definition, yaml}`.

### create\_base

Save a new base. Scope `notes:write`.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `name` | string | 1–100 chars, unique per user (case-insensitive) | required |
| `definition` | object | the `.base` document as JSON: `{filters, formulas, properties, views: [{type, name, filters, order, sort, groupBy, summaries, limit, …}]}` — exactly one of `definition` / `yaml` | — |
| `yaml` | string | the same as Obsidian `.base` YAML (≤ 64 KB); unsupported pieces are dropped and listed in `warnings` | — |

Returns `{name, views: [{name, type}], warnings: [string]}`. Every expression is validated exactly as in the app; an error reads `Invalid expression at views.0.filters: … (at character N)` so the leaf can be fixed, and a structural problem `Invalid base definition at views.0.type: …`. A duplicate name errors (`update_base` to change the existing one).

### update\_base

Replace a base's definition and/or rename it. Scope `notes:write`. The definition is replaced whole — `get_base`, change the piece the user asked about, send the full document back.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `name` | string | current name, case-insensitive | required |
| `definition` / `yaml` | object / string | as for `create_base` | — |
| `new_name` | string | 1–100 chars | — |

At least one of `definition`, `yaml`, `new_name`. Returns `{name, views, warnings}`.

### delete\_base

Delete a saved base (the notes it showed are untouched). Scope `notes:write`. `{name}` → `{deleted: name}`.

These four tools refuse on an [access-restricted](#access-restrictions) connection — definitions are neither read nor written there; `list_bases` and `query_base` keep working.

## Write tools

### create\_note

Create a new note from plain text. Include `#hashtags` and `@mentions` inline — Dexi turns them into tags automatically. A line of the form `key:: value` (e.g. `status:: reading`, `due:: 2026-09-10`) becomes a structured property that [bases](#bases) can filter and sort on.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `title` | string | ≤ 500 chars | `""` |
| `text` | string | plain text body | `""` |

Returns the created note (full shape with `text`). On a free plan at the note cap, errors with the limit message instead of creating.

### update\_note

Update a note's title and/or body. `mode: "append"` adds text to the end of the existing body — safe for adding thoughts to an existing note, or for setting a property with a `key:: value` line. `mode: "replace"` overwrites the entire body, and any rich formatting (headings, links, lists) is lost — read the note first and prefer append unless a rewrite was asked for.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `note_id` | string | note UUID; must be your own note | required |
| `title` | string | ≤ 500 chars; omit to keep | — |
| `text` | string | omit to keep | — |
| `mode` | enum | `replace` `append` | `replace` |

Returns the updated note. Omitting both `title` and `text` in replace mode errors with `Nothing to update`.

### delete\_note

Permanently delete a note. Cannot be undone, and also removes the attached bookmark, saved email, or feed-article record if the note came from one. The tool is flagged destructive; assistants should confirm with the user before deleting anything not explicitly asked for.

| Parameter | Type | Constraints |
| - | - | - |
| `note_id` | string | note UUID; must be your own note |

Returns `{deleted: true, id, title}`.

## Spaced repetition

Notes tagged with the user's review deck tags (Settings → Review) enroll in an SM-2 review schedule. These tools let an assistant run a review session in conversation.

### get\_due\_reviews

Cards due for review. Quiz the user on the title/topic before revealing the body, then call `grade_review`.

| Parameter | Type | Constraints | Default |
| - | - | - | - |
| `limit` | int | 1–50 | 10 |

Returns `{items: [{id, title, text, due_at, interval_days, repetitions, is_new}], due_count}` — `is_new` means never graded.

### grade\_review

Record recall quality and reschedule the card. Requires scope `notes:write`.

| Parameter | Type | Constraints |
| - | - | - |
| `note_id` | string | note UUID |
| `grade` | int | 1=Again (forgot — back in \~10 min), 2=Hard, 3=Good, 4=Easy |

Returns `{id, grade, due_at, interval_days, ease_factor, repetitions}`. A note not enrolled in review errors with `Note is not in review`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.