The Notes server has clear, consistent tool naming and basic schema definitions, but suffers from several critical gaps. All 6 tools follow the verb_noun pattern (notes-get-*, notes-create-note) and have descriptions (baseline 194 chars), placing them in the fair range. However, parameter descriptions are minimal (typically 10-30 chars, well below the 72-char baseline), and critical output schemas are entirely undocumented. The server returns JSON strings via text content blocks with no declared schema, forcing LLMs to parse unstructured output. Input validation and error handling are absent, invalid folder IDs or title mismatches will produce OSA script failures with no recovery guidance. The tools operate on macOS Notes.app exclusively via OSA, introducing a major security concern: user input (folderId, title, name, body) is interpolated directly into shell commands without proper escaping in several paths, creating a command injection vulnerability.
Create a new note in a specific folder and get back the note with its identifier
Retrieve all folders with names and identifiers
Retrieve a note by its identifier
Retrieve a note by its exact title match
Retrieve all notes from a specific folder
Get the total number of notes
Output schemas completely undocumented. All tools return JSON strings wrapped in text content blocks with zero schema declaration. LLMs cannot predict response structure and must parse unstructured output, violating the structured-output and response-shaper patterns.
Command injection vulnerability in OSA script interpolation. User inputs (folderId, title, name, body) are inserted directly into shell commands without proper escaping. In notes.ts lines 18-21 and 46-48, the title and folderId parameters are interpolated unescaped into JavaScript strings that are then passed to osascript. A title like "'; const x = 1; '" or a folderId containing backticks could break out of the string and execute arbitrary code.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 51 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 54 | - | v1 |
Parameter descriptions far below baseline (10-30 chars vs 72-char baseline). Examples: 'ID of the folder to get notes from' (34 chars), 'Identifier of the note to retrieve' (33 chars). Descriptions lack guidance on expected format, constraints, or when to use this tool vs similar alternatives.
No error handling or recovery guidance. If a folder ID is invalid, the OSA script fails silently or throws an uncaught exception. LLMs receive raw stderr output with no actionable next steps, no suggestion to call notes-get-folders first, no list of valid folder IDs.
No input validation. Invalid or missing required parameters are passed directly to OSA, producing cryptic errors. No enum constraints, format declarations, or length limits documented for string parameters.
tools-get-notes and notes-get-note-by-id return similar structures but serve different purposes (list vs single). Naming clarity is adequate ('get-notes' vs 'get-note-by-id'), but the distinction from 'get-note-by-title' is ambiguous, LLMs may conflate title lookup with ID lookup.
Tool composition gap: notes-get-notes returns notes without plaintext, while notes-get-note-by-id returns plaintext. An LLM listing notes cannot immediately read their content and must make a second call. Consider including a 'preview' or 'excerpt' field in list responses.