Skip to main content
Glama
Vault Cortex Obsidian MCP Server

Vault Cortex Obsidian MCP Server

Patch Note

vault_patch_note
Destructive

Edit part of an existing Markdown note by appending, prepending, replacing, or inserting content by heading without overwriting the full body.

Instructions

Surgical edits to a markdown note — append, prepend, replace, or insert content by heading. Properties are kept as written, and body line breaks are saved as LF. A repeated call can write the content again, so after a timeout or lost response, re-read the note before retrying.

Example: vault_patch_note({ path: "Projects/plan.md", operation: "append", heading: "Open questions", content: "- Which region hosts the backup?" }) Example: vault_patch_note({ path: "Notes/Plan.md", operation: "replace", heading: "Status", content: "On track for launch.\n" }) Example: vault_patch_note({ path: "Notes/Plan.md", operation: "insert_before", heading: "Phase 2", content: "## Phase 1\nDone.\n" }) Example: vault_patch_note({ path: "Notes/Plan.md", operation: "prepend", content: "> [!info] Draft\n> Not reviewed yet.\n" }) — adds a leading callout

When to use: Modifying part of an existing note without overwriting the entire body. Prefer vault_write_note for a new note or a full rewrite (overwrite: true); vault_replace_in_note for an in-place text change (a typo, a rename); vault_insert_at_anchor for inserting next to a specific line; vault_replace_span for replacing a run of lines; vault_delete_span for removing lines; vault_update_properties for properties; vault_create_task for adding a task; vault_update_task for a task's status or lane.

Operations:

  • append: add content at end of section (or end of file if no heading), below any empty lines that end it. So when a blank line follows a table, an appended row starts a new table; to extend the original table, use vault_insert_at_anchor after its last row

  • prepend: add content after heading line (or at the top of the body, below the properties block, if no heading). To start a new section above the note's current first heading, use insert_before on that heading: a no-heading prepend whose content starts with a heading nests any content above the first heading inside the new section.

  • replace: replace section body (requires heading); to empty it, use vault_delete_span on its lines

  • insert_before: insert content above the heading line (requires heading)

Behavior:

  • Heading-targeted operations keep the matched heading. Every operation inserts content as whole lines and adds no empty lines of its own: content ending in a newline ("Done.\n") leaves an empty line after it, and content without one ("Done.") puts the next line directly below.

  • A section spans from its heading to the next heading with the same or a smaller level number (or EOF), so it includes its child headings. Empty headings ("##" with no text) act as boundaries but cannot be targeted; edit their content via vault_replace_in_note instead.

  • To edit a leading callout, read it via vault_read_note(outline: true), then vault_replace_in_note the old block for the new one; a no-heading prepend would stack a second callout above it.

Errors:

  • "note not found" — path does not exist; check vault_list_notes for valid paths

  • "path must end in …" — add the .md extension

  • "heading not found" — the message lists the available headings

  • "ambiguous heading" — multiple headings match; use heading_level to disambiguate; if they share a level, rename one or use vault_replace_in_note to target by text content

  • "operation … requires a heading target" — pass heading, or use append or prepend to edit the file body

  • "heading cannot be empty" — heading is whitespace only; pass the heading's text

  • "content begins with the heading … which would duplicate it" — content's first line repeats the target heading; omit it

  • "section … has N child headings …" — the target section contains child headings that replace would destroy; pass include_children: true to confirm, or target the child heading directly

  • "absolute path blocked" / "path traversal blocked" / "hidden path blocked" — pass a vault-relative path with no dot-prefixed part

  • "concurrent write in progress" — a write to this note is in flight; re-read it and retry

  • "content contains a control character" — remove the character the message names

  • "ENAMETOOLONG: …" or another filesystem error — the message says what to do

  • "the note would open with a properties block …" — a note without properties would start with --- lines around text that can't be properties; the error says how to avoid it

Obsidian syntax: Content is Obsidian Flavored Markdown (no escaping applied). Watch for: #word = tag, [[ = wikilink, %% = comment block. Table rows: send only the data row ("| cell1 | cell2 |"), not the header or separator — duplicating them splits the table.

Returns: Confirmation message — "Applied to → ", where target is the matched heading (e.g. "## Active") or "file body" for a no-heading append/prepend. A no-heading prepend that nested existing content under an inserted heading adds a sentence naming the content's size and any call that would have avoided it.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "path": "<path>",
      "operation": "<operation>",
      "content": "<content>"
    },
    "name": "vault_patch_note"
  }
}

Input Schema

NameRequiredDescriptionDefault
pathYesVault-relative path to the note, including the ".md" extension (e.g. "TASKS.md", "Projects/plan.md"). Use the exact letter case.
contentYesMarkdown content to insert, or the section's new body for replace.
headingNoTarget heading text (case-sensitive exact match). Omit for a file-level append or prepend.
operationYesThe edit to apply.
heading_levelNoHeading level (1-6) for disambiguation when multiple headings share the same text
include_childrenNoWhen true, allows replace to overwrite a section that contains child headings.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changedv0.55.1
    • changedInput schema / properties / operation / description
      Previous value: -"append | prepend | replace | insert_before."New value: +"The edit to apply."
  2. Changed2 schema fields changedv0.54.16
    • addedInput schema / additionalProperties
      Added value: +false
    • changedInput schema / properties / content / description
      Previous value: -"Markdown content to insert."New value: +"Markdown content to insert, or the section's new body for replace."
  3. Changed2 schema fields changedv0.54.13
    • changedInput schema / properties / content / description
      Previous value: -"Markdown content to insert. Must not begin with the target heading text (it would duplicate the heading, which is kept automatically)."New value: +"Markdown content to insert."
    • changedInput schema / properties / include_children / description
      Previous value: -"When true, allows replace to overwrite a section that contains child headings. Without this, replace errors if children exist — preventing silent data loss."New value: +"When true, allows replace to overwrite a section that contains child headings."
  4. Changed3 schema fields changedv0.54.9
    • changedInput schema / properties / content / description
      Previous value: -"Markdown content to insert, written verbatim with no separator added — end it with a newline to leave a blank line after the inserted block. Must not begin with the target heading text (it would duplicate the heading, which is kept automatically)."New value: +"Markdown content to insert. Must not begin with the target heading text (it would duplicate the heading, which is kept automatically)."
    • changedInput schema / properties / heading / description
      Previous value: -"Target heading text (case-sensitive exact match). Required for replace and insert_before. Optional for append/prepend (omit for file-level operation)."New value: +"Target heading text (case-sensitive exact match). Omit for a file-level append or prepend."
    • changedInput schema / properties / operation / description
      Previous value: -"append | prepend | replace | insert_before. replace and insert_before require a heading; append and prepend work with or without one."New value: +"append | prepend | replace | insert_before."
  5. Changed1 schema field changedv0.54.7
    • changedInput schema / properties / path / description
      Previous value: -"Vault-relative path to the note, including the \".md\" extension (e.g. \"TASKS.md\", \"Projects/plan.md\")"New value: +"Vault-relative path to the note, including the \".md\" extension (e.g. \"TASKS.md\", \"Projects/plan.md\"). Use the exact letter case."
  6. Changed1 schema field changedv0.41.2
    • changedInput schema / properties / content / description
      Previous value: -"Markdown content to insert. Must not begin with the target heading text (it would duplicate the heading, which is kept automatically)."New value: +"Markdown content to insert, written verbatim with no separator added — end it with a newline to leave a blank line after the inserted block. Must not begin with the target heading text (it would duplicate the heading, which is kept automatically)."
  7. Changed1 schema field changedv0.37.1
    • addedInput schema / properties / include_children
      Added value: +{
      +  "description": "When true, allows replace to overwrite a section that contains child headings. Without this, replace errors if children exist — preventing silent data loss.",
      +  "type": "boolean"
      +}
  8. Changed1 schema field changedv0.23.10
    • changedInput schema / properties / path / description
      Previous value: -"Vault-relative path to the note (e.g. \"TASKS.md\", \"Projects/plan.md\")"New value: +"Vault-relative path to the note, including the \".md\" extension (e.g. \"TASKS.md\", \"Projects/plan.md\")"
  9. Changed3 schema fields changedv0.23.5
    • changedInput schema / properties / content / description
      Previous value: -"Content to insert or replace with"New value: +"Markdown content to insert. Must not begin with the target heading text (it would duplicate the heading, which is kept automatically)."
    • changedInput schema / properties / operation / description
      Previous value: -"Patch operation to apply"New value: +"append | prepend | replace | insert_before. replace and insert_before require a heading; append and prepend work with or without one."
    • changedInput schema / properties / path / description
      Previous value: -"Vault-relative path to the note"New value: +"Vault-relative path to the note (e.g. \"TASKS.md\", \"Projects/plan.md\")"
  10. Changed1 schema field changedv0.22.1
    • addedInput schema / properties / content / minLength
      Added value: +1
  11. Changed1 schema field changedv0.19.2
    • addedInput schema / properties / heading / minLength
      Added value: +1
  12. Added

TDQS

A4.9/5.0
Behavior5/5

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

Annotations declare destructive=true, idempotent=false, readOnly=false; the description corroborates idempotency risk explicitly ('a repeated call can write the content again... re-read the note before retrying') and adds non-obvious behavior: line-break/newline preservation, LF normalization, section extent rules (child headings included, '##' as boundary), the nesting trap on no-heading prepend, and the destructive replace-with-children guard. It also catalogues 13 error strings with remedies, which is behavior an agent cannot get from 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?

Well structured with front-loaded purpose, then When-to-use, Operations, Behavior, Errors, and Returns sections; every header aids scanning. It is long, and the four worked examples plus a few error entries (filesystem errors, control characters) are lower-value than the rest, but nothing is outright filler and the density is justified by the tool's destructiveness.

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?

For a 6-parameter destructive mutation with no output schema, the description covers return format ('Applied <operation> to <path> → <target>'), failure modes with recovery paths, and the Obsidian-syntax hazards (tag, wikilink, comment delimiters, table row duplication). An agent has everything needed to call it correctly and to recover from a timeout.

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 already 100%, so the baseline is a 3; the description earns more by adding meaning the schema cannot express — which operations require `heading`, when to pass `include_children` (replace would destroy child headings), when `heading_level` is needed (ambiguous match), and what `content` should contain per operation (data row only for tables, no duplicated heading).

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?

Opens with a specific verb+resource ('Surgical edits to a markdown note') and immediately enumerates the four operations (append, prepend, replace, insert_before). It goes further by naming the exact sibling tools for adjacent jobs (vault_write_note, vault_replace_in_note, vault_insert_at_anchor, vault_replace_span, vault_delete_span), so an agent can distinguish this tool from its 30+ siblings without opening a schema.

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?

'When to use' states the positive condition (modifying part of an existing note without overwriting the body) and then routes to an explicit alternative for every neighboring case: full rewrite, typo fix, line-anchored insert, span replace/delete, properties, tasks. Exclusions are concrete rather than implied, which is exactly what a crowded vault toolset needs.

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