Skip to main content
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 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:
Note item
  • 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; 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. Returns {items, total, page, relaxed}. 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. 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. Returns {items, total, page}.

get_note

Fetch one note in full: complete body text, title, tags, source kind, and source URL. 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. 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. 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. The filter language, property syntax and .base format are documented in 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, 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. Returns {name, definition, yaml}.

create_base

Save a new base. Scope notes:write. 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. 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 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 can filter and sort on. 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. 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. 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. 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. Returns {id, grade, due_at, interval_days, ease_factor, repetitions}. A note not enrolled in review errors with Note is not in review.