Skip to content

feat: add update_note and append_to_note MCP tools#927

Open
nguyenngothuong wants to merge 38 commits into
refactoringhq:mainfrom
nguyenngothuong:feat/mcp-update-append
Open

feat: add update_note and append_to_note MCP tools#927
nguyenngothuong wants to merge 38 commits into
refactoringhq:mainfrom
nguyenngothuong:feat/mcp-update-append

Conversation

@nguyenngothuong

Copy link
Copy Markdown

Closes #895. The Tolaria MCP server previously only let agents create new notes (create_note with O_EXCL). This PR adds write-back to existing notes so agents can maintain living documents (Agent notes, evolving Project notes, frontmatter status / schedule / related_to updates) instead of fragmenting them into supplementary notes.

What was implemented

Two new writable, non-destructive MCP tools operating on existing notes, layered exactly like create_note (vault.js primitive → tool-service method → stdio + WebSocket registration):

  • update_note — replace full content (frontmatter + body). Atomic temp-file + rename so a crashed write never truncates a note. Optional expectedMtime (the mtimeMs from get_note) fails fast on concurrent edits, leaving the on-disk note untouched.
  • append_to_note — append markdown verbatim to the body. No conflict guard because append cannot lose data on its own. Lower-risk path for logs/journals.

Both reuse the existing realpath traversal guard, resolve via the same writableVaultPath / writableNotePath helpers, emit vault_changed so the UI refreshes, and use the existing writable annotation profile (readOnlyHint: false, destructiveHint: false, openWorldHint: false) — i.e. MCP clients treat them like create_note (non-destructive local write, no extra approval).

Design follows the spec in #895 exactly. The optional expectedMtime conflict guard is opt-in (issue suggestion), so the common single-editor agent flow stays a single update_note call without a mandatory read.

QA

Verified via MCP stdio integration tests:

  • update_note / append_to_note are listed with correct annotations and required ['path', 'content'] schema.
  • Round-trip update_note then read-back matches the new content.
  • append_to_note appends verbatim (no auto-newline — agents control formatting).
  • update_note rejects path-traversal outside the vault; fails on expectedMtime mismatch without touching the note.
  • append_to_note rejects path-traversal; throws ENOENT for missing notes.

No native UI QA needed — no UI change (these are MCP-only tools).

Tests / coverage

cd mcp-server && node --test test.js tool-service.test.js53 pass / 0 fail (8 new cases across vault primitives, service layer, and stdio MCP integration). pnpm lint clean. Pre-push gate: 25/25 Playwright smoke pass.

CodeScene

PAT / project not set in this environment, so the gate skipped. Boy Scout rule applied manually — vault.js helpers (writeExistingUtf8File, appendUtf8File, assertNoteMatchesExpectedMtime) are focused single-purpose functions, and the atomic write cleans up its temp file on a failed rename so it never leaks.

Codacy

No Critical / High findings introduced — all writes go through the existing resolveVaultNotePath traversal guard (no new path handling); expectedMtime is opt-in and never silently overwrites.

Localization

No UI copy changes.

PostHog

No event needed — MCP tool calls are agent-driven, not user-driven UI actions; instrumenting them would create noise.

Refactoring

Extracted resolveWritableNote and noteContent helpers in tool-service.js to keep the two new methods parallel with createNote without duplication.

ADRs

ADR-0142 records the design and the alternatives considered (mandatory expectedMtime, frontmatter-patch tool, in-place write, append-only shipping).

Docs

mcp-server/index.js tool banner updated to list the new tools. Bundle regenerated (pnpm bundle-mcp) — bundle is gitignored, rebuilt at release time.

Demo vault dirt

git status --short -- demo-vault demo-vault-v2 clean.

Closes refactoringhq#895. The Tolaria MCP server previously only let agents create new
notes (create_note with O_EXCL). This adds write-back to existing notes so
agents can maintain living documents (Agent notes, evolving Project notes,
frontmatter status/schedule updates) instead of fragmenting them into
supplementary notes.

- update_note: replace full content (frontmatter + body). Atomic temp +
  rename. Optional expectedMtime fails fast on concurrent edits.
- append_to_note: append markdown verbatim to the body.

Both reuse the realpath traversal guard, emit vault_changed, and use the
existing writable annotation profile. See ADR-0142 for full design.
github-actions Bot added 28 commits June 21, 2026 13:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP: Add update_note and/or append_to_note tools

1 participant