Skip to main content
Glama
aliasunder

Vault Cortex Obsidian MCP Server

Read Note

vault_read_note
Read-onlyIdempotent

Read a markdown note by vault-relative path. Use outline or heading modes to fetch just the section you need, saving tokens on large files.

Instructions

Read a markdown note by its vault-relative path. By default returns the full raw content including properties; optional modes return just the properties, just the heading outline, or just one section — so large notes don't blow the token budget.

Example: vault_read_note({ path: "Projects/vault-cortex.md" }) Example: vault_read_note({ path: "Projects/vault-cortex.md", properties_only: true }) Example: vault_read_note({ path: "TASKS.md", outline: true }) Example: vault_read_note({ path: "TASKS.md", heading: "Active" }) Example: vault_read_note({ path: "TASKS.md", heading: "Done", heading_level: 2 }) // disambiguate when several "Done" headings exist Example: vault_read_note({ path: "TASKS.md", heading: "Done", start_line: 1, limit: 20 }) // first 20 lines of an oversized section

When to use: You know the exact path and need a specific note's content. For a large note (a long board or doc), use outline: true to see its headings and any text sitting above them, then heading: "..." to read just the one section you need — both far cheaper than pulling the whole file. Use properties_only: true when you only need properties. For an oversized note or section, page it with start_line and limit to read a window at a time. To check a note's or section's line count, request start_line: 1 with limit: 1 — one line plus the total. Prefer vault_search when you don't know the path. Prefer vault_get_memory for About Me/ files (returns content without properties). To edit a section you've read, use vault_patch_note. To explore what links to this note or what it links to, use vault_get_backlinks and vault_get_outgoing_links.

Section boundaries: a section spans from its heading to the next heading of the same or higher level (or EOF). Child headings are included. Modes are mutually exclusive — set at most one of properties_only, outline, or heading. Paged reads normalize line endings to LF; unpaged reads stay byte-identical.

Errors:

  • "note not found" — no note exists at this path; verify it with vault_list_notes

  • "heading not found" — no heading matches the text; error lists available headings

  • "ambiguous heading" — multiple headings match; use heading_level to disambiguate, or read the full note (omit heading) when headings share the same level

  • "outline, heading, and properties_only are mutually exclusive" — only one mode per call

  • "line paging is not available in outline mode" / "... properties_only mode" — start_line/limit only work on text renditions (full read or heading section)

  • "start line past the end" — start_line exceeds the rendition's line count; error states the total

  • 'path must end in ".md"' — the path names a non-markdown file; read files (images, .canvas, data files) with vault_read_file instead

  • "absolute path blocked" — the path starts at the filesystem root; use a vault-relative path

  • "hidden path blocked" — the path targets a hidden (dot-prefixed) file or folder like ".obsidian/"; hidden paths are not accessible, matching Obsidian

Returns: Raw markdown string (default); JSON object of properties (properties_only); JSON outline object with file-level bytes and modified time (outline); raw markdown of the section, heading line included (heading). When start_line or limit is given, the result is preceded by a window-metadata text block ("path — lines 1–20 of 250 (continue with start_line: 21)").

Outline shape: { bytes, modified, leading_callout?, leading_content?, headings } — bytes is the whole file's on-disk size; modified is its filesystem modification time; headings is [{ level, text, bytes }], where each heading's bytes is the exact UTF-8 byte length of the text that heading mode returns for that section. leading_callout ({ type, title, body }) is the note's top-of-file callout; leading_content is the rest of the body text above the first heading, with the callout's own lines excluded so the two never repeat the same text. Either key is omitted when the note has none. Empty headings ("##" with no text) appear with text: "" — they act as section boundaries but cannot be targeted by the heading parameter; read the parent section (which includes child headings) or the full note, and edit via vault_replace_in_note.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
pathYesVault-relative path to the note, including the ".md" extension (e.g. "About Me/Principles.md")
limitNoMaximum lines returned (default: all remaining). A paged read's metadata line states the window, the total line count, and the next start_line.
headingNoReturn only this section (heading line + body, through the next same-or-higher heading). Case-sensitive exact match.
outlineNoIf true, returns { bytes, modified, leading_callout?, leading_content?, headings } as JSON instead of body content — a cheap structure fetch for large notes. headings: [{ level, text, bytes }]; leading_callout: { type, title, body } when the note has a top-of-file callout; leading_content: the rest of the body text above the first heading (callout lines excluded) when the note has any.
start_lineNoFirst line to return, 1-based (default 1). Pages the delivered rendition (full body or a heading section). Not valid for outline or properties_only (JSON modes).
heading_levelNoHeading level (1-6) for disambiguation when multiple headings share the same text; only applies with heading
properties_onlyNoIf true, returns parsed properties as JSON instead of full note content

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.53.0
    • changedInput schema / properties / outline / description
      Previous value: -"If true, returns { leading_callout?, leading_content?, headings } as JSON instead of body content — a cheap structure fetch for large notes. headings: [{ level, text, bytes }]; leading_callout: { type, title, body } when the note has a top-of-file callout; leading_content: the rest of the body text above the first heading (callout lines excluded) when the note has any."New value: +"If true, returns { bytes, modified, leading_callout?, leading_content?, headings } as JSON instead of body content — a cheap structure fetch for large notes. headings: [{ level, text, bytes }]; leading_callout: { type, title, body } when the note has a top-of-file callout; leading_content: the rest of the body text above the first heading (callout lines excluded) when the note has any."
  2. Changed2 schema fields changedv0.36.0
    • addedInput schema / properties / limit
      Added value: +{
      +  "description": "Maximum lines returned (default: all remaining). A paged read's metadata line states the window, the total line count, and the next start_line.",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / start_line
      Added value: +{
      +  "description": "First line to return, 1-based (default 1). Pages the delivered rendition (full body or a heading section). Not valid for outline or properties_only (JSON modes).",
      +  "maximum": 9007199254740991,
      +  "minimum": 1,
      +  "type": "integer"
      +}
  3. Addedv0.32.1
  4. Removedv0.32.0
  5. Changed1 schema field changedv0.23.10
    • changedInput schema / properties / path / description
      Previous value: -"Vault-relative path to the note (e.g. \"About Me/Principles.md\")"New value: +"Vault-relative path to the note, including the \".md\" extension (e.g. \"About Me/Principles.md\")"
  6. Changed3 schema fields changedv0.19.2
    • addedInput schema / properties / heading
      Added value: +{
      +  "description": "Return only this section (heading line + body, through the next same-or-higher heading). Case-sensitive exact match.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • addedInput schema / properties / heading_level
      Added value: +{
      +  "description": "Heading level (1-6) for disambiguation when multiple headings share the same text; only applies with heading",
      +  "maximum": 6,
      +  "minimum": 1,
      +  "type": "integer"
      +}
    • addedInput schema / properties / outline
      Added value: +{
      +  "description": "If true, returns { leading_callout?, headings } as JSON instead of body content — a cheap structure fetch for large notes. headings: [{ level, text, bytes }]; leading_callout: { type, title, body } when the note has a top-of-file callout.",
      +  "type": "boolean"
      +}
  7. Added

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, and the description adds substantial behavior beyond that: modes are mutually exclusive, paged reads normalize line endings to LF while unpaged reads stay byte-identical, outline shape has specific size semantics, hidden/absolute paths are blocked, and empty headings cannot be targeted. There is no contradiction with the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but well structured: examples first, then usage guidance, behavior, errors, and return shapes. It is slightly redundant with the input schema in the outline-shape section, but nearly every sentence carries operational value for a 7-parameter tool with multiple modes.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema present, the description fully defines return values for every mode, including the outline JSON shape, paging metadata, and all meaningful error conditions with recovery hints. Nothing an agent needs to call this tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, and the description still adds real value: concrete examples for properties_only, outline, heading, heading_level, and start_line/limit. It clarifies cross-parameter constraints such as mutual exclusivity, heading_level only applying with heading, and paging being invalid for JSON modes, plus the window-metadata block returned when paging.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read a markdown note by its vault-relative path,' and immediately enumerates the available read modes. It distinguishes itself from siblings by naming alternatives like vault_search, vault_get_memory, and vault_patch_note, so an agent knows exactly what this tool is and is not.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is an explicit 'When to use' paragraph: use this tool when you know the exact path, prefer vault_search when you don't, prefer vault_get_memory for About Me files, and use vault_patch_note to edit. It also gives mode-selection heuristics for large notes, properties-only needs, paging, and checking line counts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.