MCP Note Editing Guide

Purpose

Use this note when editing JSONHTL notes through MCP tools. It records the safe approach after the 2026-07-04 Ask/deployment note edits exposed two easy mistakes: replacing the block before the intended section, and inserting multiple blocks after the same target in reversed or unexpected order.

Read When

• Before editing notes through MCP patch, batch, put, reorder or table_op.

• Before restructuring a note, adding a section, or adding child notes from an agent session.

• When a note edit has gone wrong and you need the known failure modes.

Decision Rule

Prefer the smallest safe edit that preserves links and metadata. For simple text changes, use block-ID patching. For structural rewrites, whole-document put is often safer than many live insert/delete operations. For table blocks, use table_op rather than treating table data as text.

Always Start With a Read

1. Read the target note with include_block_ids: true.

2. Use the returned rev as if_rev on patch, batch or put.

3. Treat block_ids as the source of truth. Every heading, paragraph, codeblock, list, and table is its own block.

4. Map the exact block ID to the exact content you intend to change before writing. Do not infer that a heading's block ID is also the paragraph under it — and do not infer position from memory of an earlier read either; re-verify against the latest read each time. Two edits in the 2026-08-08 session (see Table Editing Robustness) landed in the wrong section this way, despite having just read the document — the block-ID-to-content mapping was misremembered between the read and the write.

Safe Single-Block Changes

Use patch or batch replace_block with block_id for one known block. Include patch_meta in the same batch when changing content: increment version and set updated to today's date. After the write, read the note back and verify the edited section, not just the tool status.

get(key, include_block_ids=true)
batch(key, if_rev=rev, ops=[
  patch_meta(version=N+1, updated=YYYY-MM-DD),
  replace_block(block_id=target_id, block=new_block)
])
get(key)  # verify

Multi-Block Inserts

Do not insert several blocks before or after the same target in one batch unless the tool explicitly guarantees ordering. The safer pattern is either: insert the first block, read back, then insert the next relative to the newly inserted block; or use put with the complete document when adding a whole section. This avoids reversed order such as paragraph-before-heading.

Structural Edits

For moving sections, reordering headings, deleting several blocks, or doing mixed insert/delete batches, prefer reconstructing the complete document and using put with if_rev. This mirrors normal file editing and is easier to inspect. Preserve title, created, tags, links, and other metadata; increment version; set updated; then read back.

If you must use batch for structural edits, split risky operations: do deletes and inserts separately, re-read between them, and avoid index-based operations after any mutation because indexes drift. Block IDs are safer than indexes, but even block-ID batches can be hard to reason about when several operations target nearby blocks.

Creating Child Notes

Create the child note first with a complete put. Then update the parent to link it. This keeps the note tree discoverable and avoids partial parent pages with missing child content. If editing an index or parent page, preserve all existing links.

Verification Checklist

• Read back every changed note.

• Check heading/paragraph order around inserted content.

• Search or visually inspect for stale duplicate text left behind.

• Confirm version and updated metadata changed when content changed.

• Confirm any new note is linked from a parent.

• If a mistake appears, correct it immediately and read back again.

Common Failure Modes

• Replacing the heading-adjacent paragraph by using the wrong block ID.

• Forgetting that headings are blocks, so the paragraph below has a different ID.

• Inserting heading and paragraph after the same block and getting unexpected order.

• Using indexes in a multi-step edit after earlier operations have shifted positions.

• Trusting an ok status without reading the document back.

• Creating a useful child note but not linking it from a parent.

• Replacing a whole block (e.g. a table) with the wrong content because a target block ID was hand-matched from a flat block_ids array from memory rather than checked against a fresh read — the 2026-08-08 incident logged in Table Editing Robustness. Prefer narrow ops (table_op set_cell, insert_row/append_row) over replace_block when the change is really a single cell or row — this class of tool cannot misfire onto the wrong block the way a guessed block_id can.

Related Notes

• Fixing a content swap between two blocks by reissuing a full-document put when a targeted reorder (or a second, carefully block-ID-checked batch) would have fixed it — costs block-ID continuity for no reason. See README/lessons for a worked example.

• Sorting a table on a value that isn't directly sortable (e.g. a drive-time range like "~50-55 min") — discussion of hidden-column vs strip-non-digit vs explicit PCRE-at-sort-time approaches. See Table Editing Robustness. Idea only; not implemented.

See MCP Tools for tool overview, Workflow - Creating and Updating Notes for creation/linking order, and Avoiding Orphaned Notes for preserving discoverability.

Tool Discovery Tip

If expected Notes read/write tools appear to be missing, re-run tool discovery, touch the Notes connector if needed (for example with _keys), and then check discovery again before concluding they are unavailable. On 2026-09-19, the first discovery exposed only _keys/_delete; after re-discovery the public Notes MCP exposed _get, _put, _patch, and _batch in the same chat. Prefer the Notes MCP tools for note reads and edits when available: they are the intended interface and are less likely than shelling out to /home/john/bin/notes or using curl to require an operation approval prompt. Fall back to the local command only when MCP discovery still does not expose the needed operation or the MCP call itself fails.

created 2026-07-04  ·  tags documentation, tools, mcp, notes  ·  updated 2026-09-19  ·  version 7