All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- createNote uses body-only approach — Title is now set exclusively via
<h1>prefix in the note body instead of setting both thenameproperty and body. This eliminates title duplication.
- Title duplication in createNote — Previously, setting both
nameandbodycaused the title to appear twice in the note. Now onlybody(with<h1>title prefix) is used.
- Proper backslash and tab handling in plaintext content encoding — Backslashes are encoded as
\and tabs are converted to<br>to prevent AppleScript escaping issues.
- Fixed command injection vulnerability in
moveNote()- HTML content from notes was not properly escaped before embedding in AppleScript commands
- Improved sleep implementation - Replaced CPU-spinning busy-wait with efficient system sleep command
- Added sync status caching - Sync detection now caches results for 2 seconds to reduce database queries
- Extracted shared parsing logic - Consolidated duplicated note property parsing into
parseNotePropertiesOutput()helper
- New helper functions for cleaner code:
escapeHtmlForAppleScript()- Safely escape already-HTML content for AppleScriptgenerateFallbackId()- Consistent unique ID generation when AppleScript doesn't return oneparseNotePropertiesOutput()- Shared parsing for AppleScript note property outputclearSyncStatusCache()- Clear cached sync status for testing/forced refresh
- Export type definitions - Added proper TypeScript interfaces for export operations (
NotesExport,ExportedNote, etc.) - Additional retry tests - Coverage for all retryable error patterns (timed out, lost connection, busy)
- ESLint flat config - Migrated from deprecated
.eslintrc.cjsto moderneslint.config.js - Pre-commit hooks - Added husky + lint-staged for automatic linting on commit
- Test coverage thresholds - Enforced minimum coverage (services ≥80%, utils ≥90%)
- Dynamic version - Server version now read from package.json instead of hardcoded
- Collaboration Awareness
list-shared-notestool to find all notes shared with collaborators- Warnings on
update-notewhen modifying shared notes - Warnings on
delete-notewhen removing shared notes listSharedNotes()method in AppleNotesManager
-
iCloud Sync Awareness
get-sync-statustool to check if iCloud sync is active- Sync warnings integrated into
search-notes,list-notes,list-folders - Detection of pending uploads and recent database activity
- Follow-up verification to detect sync interference
-
JXA Research (utilities only, not primary executor)
src/utils/jxa.ts- JavaScript for Automation execution utilities- Research documented in
docs/JXA_RESEARCH.md - Finding: JXA is 7.6x slower than AppleScript, not recommended for primary use
- Markdown Export
get-note-markdowntool to retrieve note content as Markdown- Uses Turndown library for HTML to Markdown conversion
- Database Export
export-notes-jsontool for complete notes backup as JSON
- Batch Operations
batch-delete-notestool to delete multiple notes by IDbatch-move-notestool to move multiple notes to a folder
- Attachment Listing
list-attachmentstool to see attachments in a note
- Verbose Logging
- DEBUG environment variable support for troubleshooting
- Statistics
get-notes-statstool for comprehensive notes statistics
- Validate note existence before destructive operations
- Better error messages for missing notes
- Retry logic for transient failures (Notes.app not responding)
- Improved error message mapping
health-checktool to verify Notes.app connectivity and permissions
folderparameter tosearch-notesfor filtering by folder
- Timeout handling for AppleScript operations (30 second default)
- Password-protected note detection with clear error messages
- Search functionality crash when notes have inaccessible containers (orphaned/corrupted notes)
- Added error handling in AppleScript loop to skip problematic notes instead of failing entirely
- Search now returns all accessible matching notes even if some cannot be processed
-
Folder Operations
list-folders- List all folders in an accountcreate-folder- Create a new folderdelete-folder- Delete a folder
-
Multiple Account Support
list-accounts- List all available accounts- All tools now accept optional
accountparameter
-
Enhanced Search
searchContentoption to search note bodies instead of just titles
-
Note Management
get-note-by-id- Retrieve note by unique IDget-note-details- Get full note metadata (dates, shared status)update-note- Update existing note title and contentdelete-note- Delete notes by titlemove-note- Move notes between folders (copy-then-delete)
-
Developer Experience
- Comprehensive JSDoc documentation
- Unit tests with Vitest (121 tests)
- Integration tests for all MCP tool handlers
- ESLint and Prettier configuration
- TypeScript strict mode
- AppleScript escaping for apostrophes (shell quoting issue)
- Newline handling in note content (now converts to HTML breaks)
- Date parsing in getNoteById (handles commas in AppleScript date format)
- Complete rewrite of all source code with new architecture
- Updated to Node.js 20+ requirement
- Improved error messages throughout
Initial release.
- Create notes with title and content
- Search notes by title
- Retrieve note content by title
- iCloud account support