Skip to content

Reader

Search Vault. Read-only. Idempotent.

Search notes by keyword and meaning; returns notes ranked by score, each with its best-matching sections as snippets.

Use list_documents for a complete listing and read for a path you already know.

Parameters

Name Type Default Description
query string required Words to match or a natural-language question.
limit integer 10 Maximum notes to return (default 10).
mode keyword \| semantic \| hybrid \| null null Omit for the best mode this vault serves. "keyword" suits exact terms, operators and filenames; "semantic" matches meaning only; "hybrid" combines both. "semantic" and "hybrid" need semantic_search_available from stats.
folder string \| null null Only notes under this folder, a value from list_folders; "" for top-level notes only.
filters object \| null null Frontmatter values to match, all of them, such as {"tags": "pacing"}; keys come from indexed_frontmatter_fields in stats, and a list field matches when it holds the value. On an OKF bundle, status (draft, stable or deprecated; stable includes notes with none), stale ("true" or "false") and trust_tier (unverified, machine-confirmed or human-reviewed) filter too.
chunks_per_file integer \| null null Maximum sections per note, at least 1; omit for the server default.
snippet_words integer \| null null Snippet width in words; omit for the server default, 0 for whole sections. read with section set to a result's heading returns that whole section.
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

List of result dicts ranked by file relevance. Each contains:

  • path (str): Relative path of the document.
  • title (str): Document title.
  • folder (str): Parent folder path.
  • score (float): File-level score = max(section.score). Higher is a better match. BM25 (keyword) or cosine (semantic/ hybrid); not comparable across modes.
  • search_type (str): "keyword", "semantic", or "hybrid".
  • frontmatter (dict): Parsed YAML frontmatter of the document.
  • okf (dict, optional): OKF read annotation: present only when the vault is an active OKF bundle. Carries type (when declared), status (defaults to "stable"), stale (bool, stale_after reached), trust_tier ("unverified" / "machine-confirmed" / "human-reviewed"), and sources_count (when the note cites sources).
  • sections (list[dict]): Up to chunks_per_file best-matching sections, each with:

  • heading (str | None): Section heading or null for intro.

  • content (str): Matched snippet (or full chunk if snippet_words=0). Call read(path, section=heading) for the full section text.
  • score (float): Chunk-level score for this section.

On an active OKF bundle, ranking demotes deprecated notes, stale notes less, and the reserved index.md and log.md below real notes.

An empty query returns an empty list in semantic and hybrid mode.

Index freshness rides in the response's _meta.index_stale field: True when the IndexWriter was non-idle, a write completed inside the read window, or wait_for_pending_writes timed out; False otherwise.

Outcomes and errors

  • EmbeddingsNotConfiguredError: If mode is "semantic" or "hybrid" and no embedding provider is configured (a ValueError subclass).
  • InvalidRequestError: If chunks_per_file is below 1.

Find craft notes on a topic, two sections per note:

{"query": "character development techniques", "limit": 5, "filters": {"tags": "craft"}}

To read a hit in full, pass its path and a section heading to read: read(path=hit["path"], section=hit["sections"][0]["heading"]).

read

Read Note. Read-only. Idempotent.

Return a note's text, frontmatter and etag, or an attachment's bytes as base64.

Look paths up with search or list_documents first rather than guessing them.

Parameters

Name Type Default Description
path string required Path in the vault, such as "Journal/note.md" or "assets/diagram.pdf"; case-sensitive.
section string \| null null A heading, such as the heading field of a search result; returns that section and its sub-sections instead of the whole note. Notes only.
revision string \| null null A commit SHA from get_history or from a write result's previous_revision; returns the note as it stood then, without an etag. Pass path as the note is named today. To restore that text, write it with the etag of a read without revision.

Returns

For .md: dict with path, title, folder, content (the full raw file including frontmatter, or the section text when section= is given), frontmatter (dict: empty {} when section= is provided; call read(path) without section= to get the full document's frontmatter), modified_at (Unix timestamp), etag (SHA-256 hex str or null). On an active OKF bundle, whole-document reads also carry an 'okf' dict (type, status, stale, trust_tier, and the note's 'sources' list when present); section reads omit it because they carry no frontmatter to derive it from. For attachments: dict with path, mime_type (str or null), size_bytes (int), content_base64 (str), modified_at (Unix timestamp), etag (SHA-256 hex str or null). The 'etag' value can be passed as 'if_match' to write, edit, delete, or rename to guard against concurrent modifications. With revision=: dict with path, historical_path (the name the note carried at that revision), revision, and content: the whole raw file, or just one section's body when section= is also given. No etag and no modified_at (both describe the note as it is now), and no 'okf' block for the same reason.

Outcomes and errors

  • ValueError: If no file exists at the given path, the extension is not in the attachment allowlist, the file exceeds MARKDOWN_VAULT_MCP_MAX_ATTACHMENT_SIZE_MB, or the requested section heading is not found. A whole note over the size limit this server returns in one read (MARKDOWN_VAULT_MCP_MAX_NOTE_READ_BYTES) is refused; read it by section. With revision: if the vault is not git-backed, the revision is unusable, the path is an attachment, or git's records do not show the note existing at that revision (a name later reused by a different note is refused rather than answered with the other note's content).
  • DocumentUnreadableError: If the file cannot be read or decoded, its frontmatter does not parse, or git stores it in LFS at that revision.

Read a note:

{"path": "Journal/note.md"}

returns

{
  "path": "Journal/note.md",
  "title": "My Note",
  "folder": "Journal",
  "content": "---\ntitle: My Note\ntags: [journal]\n---\n\nThe note body.\n",
  "frontmatter": {"title": "My Note", "tags": ["journal"]},
  "modified_at": 1791052994.65,
  "etag": "1f196a744076635e77bc55e674dcdd69a29d9d32614c516a51ced986a51aaebe"
}

content is the raw file, frontmatter included. Pass etag as if_match to write, edit, delete or rename to change the note you read.

list_documents

List Documents. Read-only. Idempotent.

List notes, and optionally attachments, with path, title and frontmatter but no body text.

Use search to find notes by what they say.

Parameters

Name Type Default Description
folder string \| null null Only notes in this folder and its sub-folders, such as "Journal"; "" for top-level notes only; omit for the whole vault.
pattern string \| null null Glob matched against paths, such as "Journal/*.md" or "**/*meeting*.md".
include_attachments boolean false Also list non-note files, marked kind="attachment" with their mime_type. Default false.
filters object \| null null Frontmatter values to match, all of them, such as {"tags": "craft"}; any key works, a list field matches when it holds the value, and attachments never match. On an OKF bundle, status (draft, stable or deprecated; stable includes notes with none), stale ("true" or "false") and trust_tier (unverified, machine-confirmed or human-reviewed) filter too.
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

List of info dicts. Every entry has a 'kind' field. Notes: path, title, folder, frontmatter, modified_at, kind="note", and content_chars (int): body length in characters, frontmatter excluded; 0 for a note indexed before the field existed. Attachments (when include_attachments=True): path, folder, mime_type, size_bytes, modified_at, kind="attachment". Body content is not included in either case.

Index freshness rides in the response's _meta.index_stale field: True when the IndexWriter was non-idle, a write completed inside the read window, or wait_for_pending_writes timed out; False otherwise.

Stale notes on an OKF bundle, for a triage pass:

{"folder": "Playbooks", "filters": {"stale": "true"}}

list_folders

List Folders. Read-only. Idempotent.

List every folder that holds notes; "" stands for the top level.

Pass one as the folder argument of search, list_documents and the other folder-scoped tools.

Parameters

Name Type Default Description
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

Sorted list of folder paths, such as ["", "Journal", "Projects"]. Pass any of these as the 'folder' argument to 'search' or 'list_documents'.

Index freshness rides in the response's _meta.index_stale field: True when the IndexWriter was non-idle, a write completed inside the read window, or wait_for_pending_writes timed out; False otherwise.

list_tags

List Tags. Read-only. Idempotent.

List the distinct values one indexed frontmatter field takes across the vault.

Use the values in the filters argument of search.

Parameters

Name Type Default Description
field string "tags" A field from indexed_frontmatter_fields in stats (default "tags").
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

Sorted list of distinct string values, such as ["craft", "pacing", "worldbuilding"]. Use these as values in the 'filters' dict when calling 'search'.

Index freshness rides in the response's _meta.index_stale field: True when the IndexWriter was non-idle, a write completed inside the read window, or wait_for_pending_writes timed out; False otherwise.

Outcomes and errors

  • InvalidRequestError: If field is not an indexed frontmatter field; the message names the fields that are indexed.

stats

Vault Stats. Read-only. Idempotent.

Report the vault's size, link health and capabilities: the search modes it serves and the frontmatter fields search can filter on.

Parameters

Name Type Default Description
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

Dict with the following fields:

  • document_count (int): Total number of indexed documents.
  • chunk_count (int): Total number of indexed text chunks.
  • folder_count (int): Total number of folders containing documents.
  • semantic_search_available (bool): True if mode="semantic" or mode="hybrid" can be used in 'search'.
  • indexed_frontmatter_fields (list[str]): Field names usable as 'filters' in 'search' and as 'field' in 'list_tags'.
  • attachment_extensions (list[str]): Allowed non-.md extensions, or ["*"] when any extension is allowed.
  • link_count (int): Total number of indexed links. 0 may mean no links exist or link tracking not yet built (call 'reindex').
  • broken_link_count (int): Links pointing to missing documents. Call 'get_broken_links' if non-zero.
  • orphan_count (int): Notes with no inbound or outbound links. Call 'get_orphan_notes' if non-zero.
  • okf (dict, optional): Present only when the vault is an active OKF (Open Knowledge Format) bundle. Carries mode, declared_version, a per-type histogram plus untyped_count, status and trust-tier breakdowns, and stale_count. Those cover the note population 'okf_validate' audits; the reserved index.md / log.md files are counted apart as reserved_count.

Index freshness rides in the response's _meta.index_stale field: True when the IndexWriter was non-idle, a write completed inside the read window, or wait_for_pending_writes timed out; False otherwise.

{"document_count": 42, "chunk_count": 156, "folder_count": 5, "semantic_search_available": true,
 "indexed_frontmatter_fields": ["tags", "cluster"], "attachment_extensions": ["pdf", "png", "jpg"],
 "link_count": 310, "broken_link_count": 3, "orphan_count": 7}

get_similar

Similar Notes. Read-only. Idempotent.

Find the notes closest in meaning to a given note; returns them ranked by similarity with their closest sections, the note itself excluded.

Needs semantic_search_available from stats. A note whose embeddings are not built yet has no similar notes.

Parameters

Name Type Default Description
path string required Path of the note to compare against, such as "notes/topic.md"; case-sensitive.
limit integer 10 Maximum notes to return (default 10).
chunks_per_file integer \| null null Maximum sections per note, at least 1; omit for the server default.
folder string \| null null Only notes in this folder or below, such as "3-Resources"; "" for top-level notes only.
filters object \| null null Frontmatter values to match, all of them, such as {"type": "resource"}; any key works and a list field matches when it holds the value. On an OKF bundle, status (stable includes notes with none), stale ("true" or "false") and trust_tier filter too.
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

List of result dicts ranked by file similarity. Each contains:

  • path (str): Relative path of the similar document.
  • title (str): Document title.
  • folder (str): Parent folder path.
  • score (float): File-level cosine similarity (max of section scores), 0.0-1.0; higher = more similar.
  • search_type (str): Always "semantic".
  • frontmatter (dict): Parsed YAML frontmatter.
  • sections (list[dict]): Up to chunks_per_file best-matching sections, each with:

  • heading (str | None): Section heading or null for intro.

  • content (str): Matched chunk text.
  • score (float): Chunk-level score for this section.

Index freshness is reported out-of-band in the response's _meta.index_stale field: True when the IndexWriter had pending or in-flight work at any of three observation points (wait_for_pending_writes timing out, a write completing inside the read window, or non-idle at response time), False otherwise.

Outcomes and errors

  • DocumentNotFoundError: If no document exists at the given path.
  • EmbeddingsNotConfiguredError: If the vault has no embeddings.
  • InvalidRequestError: If chunks_per_file is below 1.
  • ToolError: If the index is busy or still building; retry shortly.
  • IndexUnavailableError: If the index build failed or the index is broken; get_index_status reports the error.
{"path": "3-Resources/okf.md", "folder": "3-Resources", "filters": {"type": "resource"}, "chunks_per_file": 1}

get_toc

Table of Contents. Read-only. Idempotent.

Return the heading outline of a note, or of every note under a folder.

For a note: a list of {heading, level}, the title first as level 1. For a folder: {path, notes, truncated}, each note with its path, title and headings.

Parameters

Name Type Default Description
path string required A note path ending in .md, such as "a/b.md", or a folder, such as "a/b".
max_level integer \| null null Deepest heading level to keep, such as 2 for H1 and H2; omit for all. The title always stays.
max_notes integer 200 Folders only: notes to include, first by path (default 200); truncated is true when more exist.
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

Note mode: list of {heading (str), level (int)}. Folder mode: {path (str), notes (list[{path, title, headings, content_chars}]), truncated (bool)}. Empty/nonexistent folder → empty 'notes'. Each note's content_chars (int) is its body length in characters, frontmatter excluded; 0 for a note indexed before the field existed.

Index freshness is reported out-of-band in '_meta.index_stale'.

Outcomes and errors

  • ValueError: Note path with no document; invalid folder path.
  • ToolError: If the index is busy or still building; retry shortly.
  • IndexUnavailableError: If the index build failed or the index is broken; get_index_status reports the error.
{"path": "1-Projects/export", "max_level": 2, "max_notes": 50}

returns

{"path": "1-Projects/export", "notes": [{"path": "1-Projects/export/plan.md", "title": "Plan", "headings": [{"heading": "Plan", "level": 1}, {"heading": "Scope", "level": 2}], "content_chars": 4120}], "truncated": false}

get_recent

Recent Notes. Read-only. Idempotent.

List the most recently modified notes, newest first.

Use it to pick up recent activity without a search query.

Parameters

Name Type Default Description
limit integer 20 Maximum notes to return (default 20).
folder string \| null null Only notes in this folder and its sub-folders, such as "Journal"; "" for top-level notes only; omit for the whole vault.
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

One dict per note, each with: path, title, folder, frontmatter, modified_at (Unix timestamp), kind ("note"), and content_chars (int): body length in characters, frontmatter excluded; 0 for a note indexed before the field existed.

Index freshness rides in the response's _meta.index_stale field: True when the IndexWriter was non-idle, a write completed inside the read window, or wait_for_pending_writes timed out; False otherwise.

get_context

Note Context. Read-only. Idempotent.

Return a note's metadata, backlinks, outlinks, similar notes, folder neighbours, indexed tags and applicable conventions in one call.

Use it instead of get_backlinks, get_outlinks and get_similar when you need more than one of them.

Parameters

Name Type Default Description
path string required Path of the note, such as "notes/topic.md"; case-sensitive.
similar_limit integer 5 Maximum similar notes (default 5); 0 skips them, which suits a vault where stats shows semantic_search_available false.
link_limit integer 10 Maximum backlinks, and separately outlinks (default 10).
wait_for_pending_writes boolean false Wait for recent index writes. On timeout, answer from the current index with _meta.index_stale=true. Default false.

Returns

Dict with the note context. Fields:

  • path (str): Relative path of the document.
  • title (str): Document title.
  • folder (str): Parent folder path.
  • frontmatter (dict): Parsed YAML frontmatter.
  • modified_at (float): Unix timestamp of last modification.
  • backlinks (list): Documents linking to this note. List of dicts, each with:

  • source_path (str): Path of the document containing the link.

  • source_title (str): Title of the source document.
  • link_text (str): The clickable text of the link.
  • link_type (str): One of "markdown", "wikilink", or "reference".
  • fragment (str | None): Heading anchor (such as "#section"), or null.
  • raw_target (str): Literal link target as written in the source.

  • outlinks (list): Links from this note. List of dicts, each with:

  • target_path (str): Path of the linked document.

  • link_text (str): The clickable text of the link.
  • link_type (str): One of "markdown", "wikilink", or "reference".
  • fragment (str | None): Heading anchor (such as "#section"), or null.
  • raw_target (str): Literal link target as written in the source.
  • exists (bool): True if the target document is indexed.

  • similar (list): Semantically similar notes, field-collapsed by file (chunks_per_file=1 for compact dossiers). List of dicts, each with:

  • path (str): Relative path of the similar document.

  • title (str): Document title.
  • folder (str): Parent folder path.
  • score (float): File-level cosine similarity 0.0-1.0 = score of the best matching section.
  • search_type (str): Always "semantic".
  • frontmatter (dict): Parsed YAML frontmatter.
  • sections (list): Single best-matching section, each with heading (str|null), content (str), score (float). Call get_similar(path, chunks_per_file=N) for more sections.

  • folder_notes (list[str]): Paths of other notes in the same folder (up to 20). Plain strings, not dicts.

  • tags (dict[str, list[str]]): Indexed frontmatter field → distinct values for this note.
  • conventions (list, optional): the user's authoring conventions for the note's folder (root-first list of {folder, path, content}). Present only when convention files apply. Honor them when writing to or proposing links involving this note; some folders are self-contained by design.
  • okf (dict, optional): OKF read annotation for this note (type, status, stale, trust_tier, sources_count). Present only when the vault is an active OKF bundle.

Index freshness is reported out-of-band in the response's _meta.index_stale field: True when the IndexWriter had pending or in-flight work at any of three observation points (wait_for_pending_writes timing out, a write completing inside the read window, or non-idle at response time), False otherwise.

Outcomes and errors

  • ValueError: If no document exists at the given path.
  • ToolError: If the index is busy or still building; retry shortly.
  • IndexUnavailableError: If the index build failed or the index is broken; get_index_status reports the error.
{"path": "3-Resources/okf.md", "similar_limit": 0, "link_limit": 5}

With similar_limit at 0 the similarity lookup is skipped, as for a vault without embeddings.

get_conventions

Folder Conventions. Read-only. Idempotent.

Return the vault owner's authoring conventions for a note or folder, vault root first and the most specific last.

Parameters

Name Type Default Description
path string "" A note or folder path, such as "3-Resources/topic.md" or "3-Resources"; a note takes its folder's conventions. "" (the default) returns the root conventions and lists every folder that has its own.

Returns

Dict with:

  • path (str): The path that was queried.
  • conventions (list): Applicable convention entries, root-first. Each has folder (str, "" for vault root), path (str, the convention file's own path), and content (str, its markdown body).
  • convention_folders (list[str], discovery mode only): all folders carrying a convention file ("" = vault root), included only when path is ""; it requires a vault-wide folder walk, so a call with a path skips it.

Convention files are left out of search and listings but can be read and edited like any note. This tool reads them from disk, so it answers while the index is still building.

Outcomes and errors

  • ValueError: If the path escapes the vault root.
{"path": "3-Resources/topic.md"}

returns the conventions that apply, root first:

{"path": "3-Resources/topic.md", "conventions": [{"folder": "", "path": "_conventions.md", "content": "…"}, {"folder": "3-Resources", "path": "3-Resources/_conventions.md", "content": "Keep notes self-contained; do not link out to project notes."}]}

okf_validate

Validate OKF Bundle. Read-only. Idempotent. Tags: okf.

Audit how far the vault conforms to the Open Knowledge Format, with example paths per rule; works on a vault not yet declared as a bundle.

Parameters

None.

Returns

Report dict. The audit reads the vault from disk, so it works before the index is built, and it skips the vault's excluded paths. Every rule except root_index_missing is a finding with count (int) and up to 20 examples (list[str] of paths).

  • mode (str), declared_version (str | None), active (bool): the detection state.
  • total_notes (int), conformant_notes (int): the progress ratio; the reserved index.md and log.md are not counted as notes.

Conformance rules, which the format requires:

  • missing_type: notes without a non-empty type; the reserved index.md and log.md are exempt.
  • unparseable_frontmatter: notes whose frontmatter does not parse.
  • misplaced_okf_version: okf_version declared anywhere but the root index.md.
  • index_frontmatter: index.md files carrying frontmatter, any on a folder index and anything but okf_version on the root, server-generated indexes included.

Advisory rules, tolerated but worth fixing:

  • unknown_status: a status outside draft, stable and deprecated.
  • log_heading_shape: log.md files whose ## headings are not YYYY-MM-DD dates.
  • root_index_missing (bool): true when the root index.md is absent.

Informational rules, not deviations:

  • wikilink_files: notes containing wikilinks, which matter only when exporting.
  • missing_recommended: notes without the recommended title or description.