Insert at Anchor
vault_insert_at_anchorInsert whole lines into an Obsidian note before or after a line matched by a short anchor substring, enabling precise table-row, list-item, or landmark-relative edits.
Instructions
Insert content as whole lines into a note's body, before or after a specific line identified by a short anchor substring. Properties are kept as written, and body line breaks are saved as LF. A failed save leaves the note unchanged. A repeated call inserts the content again, or fails as ambiguous when the content holds the anchor, so after a timeout or lost response, re-read the note before retrying.
Example: vault_insert_at_anchor({ path: "Tracker.md", anchor: "| 2024-03-02 | Acme", position: "after", content: "| 2024-03-03 | Beta Corp | New entry |" }) — inserts a new table row after the matched row. Example: vault_insert_at_anchor({ path: "Notes/Plan.md", anchor: "## Phase 2", position: "before", content: "> [!note] Phase 1 must close before this starts.\n" }) — inserts a callout and a blank line above the Phase 2 heading.
When to use: Adding content at a precise location identified by a nearby line's text, without needing to know the heading structure. Good for inserting rows into tables, adding items into lists at a specific position, or placing content relative to a known landmark line. Prefer vault_patch_note for heading-targeted inserts (append/prepend to a section). Prefer vault_replace_span when replacing a block rather than inserting next to it.
Parameters:
An anchor matches a body line (any line below the properties block).
content is inserted verbatim — blank lines inside it are kept, and a trailing newline adds a blank line after the inserted block.
Errors:
"note not found" — verify path with vault_list_notes
"path must end in …" — add the .md extension
"anchor not found" — no body line holds the fragment; verify with vault_read_note
"ambiguous anchor …" — the anchor matches multiple lines; use a longer fragment or set first_match: true
"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.
Returns: Confirmation message "Inserted line(s) <before|after> anchor in " — N counts the lines in content as sent (its line breaks plus one).
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>",
"anchor": "<anchor>",
"position": "<position>",
"content": "<content>"
},
"name": "vault_insert_at_anchor"
}
}Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Vault-relative path to the note, including the ".md" extension (e.g. "Notes/Plan.md", "Tracker.md"). Use the exact letter case. | |
| anchor | Yes | Short, unique substring of the body line to insert next to (case-sensitive). | |
| content | Yes | Content to insert (one or more lines). | |
| position | Yes | "before" inserts above the anchor line, "after" below it. | |
| first_match | No | If the anchor matches more than one line, use the first match instead of erroring (default: false — ambiguity is an error). |