NotePlan MCP exhibits mediocre definition quality typical of early-stage community servers. Tool naming follows verb-noun conventions adequately (get_, create_, update_, search_), but descriptions are generic and severely lacking in actionable detail. Parameter schemas are present with Zod validation but descriptions are minimal (8-40 chars, well below the 72-char baseline). No output schemas are documented. Error handling is minimal, most tools throw generic errors without recovery guidance. The server conflates STDIO and HTTP transports in the codebase (src/index.js vs src/index.ts), creating ambiguity about the actual interface. Composition is reasonable, tools are single-responsibility, but descriptions fail to convey prerequisites, return structures, or decision-making guidance for LLMs.
Create a daily note with optional date and content
Create a new note
Get note by ID
Get all notes
Get notes by folder
Search notes by query
Update an existing note
Descriptions are generic and lack LLM-optimization. Most are 20-35 chars (well below the 72-char baseline for params and 194-char baseline for tools). 'Create a new note', 'Get note by ID', and 'Update an existing note' do not explain WHEN to use each tool, what state changes occur, or how to chain them.
Output schemas are not documented. Tools return JSON.stringify() of internal objects, but the LLM has no schema definition for what fields are included, their types, or relationships. Without documented output schemas, LLMs cannot reliably extract data for downstream tool calls or understand pagination/continuation.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 54 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 41 | - | v1 |
Error handling is minimal and non-actionable. Errors like 'Note not found with id: {id}' do not suggest recovery steps (e.g., 'Call search_notes() to find the correct ID'). No error categorization (retryable vs. fatal). Agents cannot determine whether to retry, ask the user, or proceed with an alternative.
Parameter descriptions are incomplete and missing format constraints. 'The folder name to search in' does not clarify expected format (string, path, or display name?). Date parameters lack validation hints.
No pagination or result limits documented. get_notes() and search_notes() may return unbounded lists, if a user has 1000+ notes, responses could exhaust context windows. No limit parameter, no cursor/offset, no total_count field documented. Baseline requires pagination hints and limits of 20-50 items.
State-modifying tools (create_note, create_daily_note, update_note) do not document irreversibility or require confirmation. Descriptions do not warn that these calls have side effects. No idempotence guarantee, retrying create_note with the same title and content may create duplicate notes.
Optional parameters in create_note and update_note lack guidance on defaults. If content is omitted, is the note empty or does it inherit a default? If folder is omitted in create_note, where is the note created? Ambiguous defaults force LLMs to guess or make unnecessary lookup calls.
Parameter naming lacks type suffixes. 'id' and 'folder' do not clarify whether they are system IDs, slugs, or display names. 'folder' is especially ambiguous, does it accept 'My Folder', '/projects/my-folder', or 'folder-123'?
Transport ambiguity: source includes both STDIO (src/index.ts with StdioServerTransport) and HTTP/Express (src/index.js). Package.json lists two entry points ('start' runs STDIO; 'start-http' runs Express). Unclear which transport is the canonical MCP interface. This creates maintenance burden and potential compatibility issues.
No tool annotations present. Tools do not declare readOnlyHint, destructiveHint, or idempotentHint. get_notes, get_note_by_id, search_notes, and get_notes_by_folder should be marked readOnlyHint=true; create_note, create_daily_note, and update_note should be marked destructiveHint=true and/or idempotentHint=false to signal to clients how to handle retries and undo.