feat: add update_note and append_to_note MCP tools#927
Open
nguyenngothuong wants to merge 38 commits into
Open
feat: add update_note and append_to_note MCP tools#927nguyenngothuong wants to merge 38 commits into
nguyenngothuong wants to merge 38 commits into
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #895. The Tolaria MCP server previously only let agents create new notes (
create_notewithO_EXCL). This PR adds write-back to existing notes so agents can maintain living documents (Agent notes, evolving Project notes, frontmatterstatus/schedule/related_toupdates) 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 +renameso a crashed write never truncates a note. OptionalexpectedMtime(themtimeMsfromget_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
realpathtraversal guard, resolve via the samewritableVaultPath/writableNotePathhelpers, emitvault_changedso the UI refreshes, and use the existing writable annotation profile (readOnlyHint: false,destructiveHint: false,openWorldHint: false) — i.e. MCP clients treat them likecreate_note(non-destructive local write, no extra approval).Design follows the spec in #895 exactly. The optional
expectedMtimeconflict guard is opt-in (issue suggestion), so the common single-editor agent flow stays a singleupdate_notecall without a mandatory read.QA
Verified via MCP stdio integration tests:
update_note/append_to_noteare listed with correct annotations and required['path', 'content']schema.update_notethen read-back matches the new content.append_to_noteappends verbatim (no auto-newline — agents control formatting).update_noterejects path-traversal outside the vault; fails onexpectedMtimemismatch without touching the note.append_to_noterejects path-traversal; throwsENOENTfor 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.js→ 53 pass / 0 fail (8 new cases across vault primitives, service layer, and stdio MCP integration).pnpm lintclean. 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.jshelpers (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
resolveVaultNotePathtraversal guard (no new path handling);expectedMtimeis 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
resolveWritableNoteandnoteContenthelpers intool-service.jsto keep the two new methods parallel withcreateNotewithout 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.jstool 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-v2clean.