A Zettelkasten knowledge management system as an MCP server
Server has 18 tools with complete schemas and descriptions. Naming follows verb_noun convention (zk_create_note, zk_get_note, etc.). Descriptions are present but generic (avg ~60 chars, below 194-char baseline). Parameters have types and descriptions, but lack enums for constrained inputs (note_type, link_type, direction, format). Error handling exists but is minimal, format_error_response() returns generic messages without recovery guidance. No tool annotations (readOnlyHint, destructiveHint). Output schemas are not formally documented. Missing pagination for list operations (zk_get_all_notes, zk_get_all_tags). Composition is sound, tools are single-responsibility and chainable.
Add a tag to a note.
Create a link between two notes.
Create a new Zettelkasten note.
Delete a note.
Export a note in the specified format.
Find notes with the most connections (incoming + outgoing links).
Find notes with no incoming or outgoing links.
Find notes similar to a given note based on shared tags and links.
Constrained parameters lack enum declarations. note_type, link_type, direction, and format accept free-form strings instead of enums, inviting hallucinated values. LLMs cannot self-correct without explicit enum constraints.
List operations (zk_get_all_notes, zk_get_all_tags, zk_find_orphaned_notes) lack pagination (limit, offset, page_size). Returning unbounded lists risks context window exhaustion and poor LLM reasoning.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Destructive tools (zk_delete_note, zk_remove_link, zk_rebuild_index) should be marked destructiveHint=true to guide agent caution.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 66 | <=2025-11-25 | v2 |
Get all notes in the Zettelkasten.
Get all tags in the Zettelkasten.
Get notes linked to or from a specific note.
Retrieve a note by ID or title.
Rebuild the database index from files.
Remove a link between two notes.
Remove a tag from a note.
Search for notes by tags.
Search for notes by text content.
Update an existing note.
Error handling is generic. format_error_response() returns 'Error: <message>' without recovery guidance. Errors should suggest next steps (e.g., 'Note not found. Try zk_search_text() to find it.').
Output schemas not formally documented. Tool descriptions do not specify return structure (fields, types). LLMs cannot plan downstream calls without knowing what fields are returned.