MCP server for managing todo items with CRUD operations and search
This STDIO-based todo MCP server demonstrates solid foundational tool design with consistent naming (verb_noun pattern) and basic schema coverage. All 5 tools are properly registered with Zod schemas and return structured content. However, descriptions are minimal (single sentence, 10-35 chars), parameter descriptions lack depth, and error handling is absent. The server does not validate inputs, provide recovery guidance, or distinguish between retryable and fatal errors. Output schemas are present but sparse. No pagination, no idempotency markers, and no tool annotations. STDIO transport limits to 50 cap for protocol readiness.
Create a new todo item
Delete by ID
Return all todos
Substring search on title
Toggle (or set) the done flag
Descriptions are critically short (10-35 characters) and lack context. 'Return all todos', 'Delete by ID' do not explain WHEN to use these tools vs alternatives, what they return, or consequences. Baseline A+ tools average 194 chars with LLM-optimized guidance.
Parameters lack descriptions. 'title', 'due', 'id', 'done', 'q' have no guidance in schema. LLMs cannot infer that 'due' is an ISO 8601 date string, that 'done' toggles or sets state, or what 'q' format should be. Baseline A+ tools have 100% parameter annotation coverage.
No error handling or recovery guidance. delete_todo silently succeeds without confirming the item existed. toggleTodo() throws 'Not found' but this error is never caught or translated into actionable guidance for the LLM (e.g., 'Try search_todos() first'). Baseline pattern requires error responses to tell LLM what to do next.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 49 | 2025-06-18+ | v2 |
| 2026-03-09 | F | 44 | - | v1 |
delete_todo offers no confirmation or dry-run step. Agents can permanently delete todos without reversal. Baseline pattern pattern:confirmation-request recommends dry-run or confirmation for irreversible operations.
No input validation at tool level. add_todo accepts any 'due' string without format validation; search_todos accepts any query; toggle_todo accepts any id without existence pre-check (checked inside, but error not handled). LLM receives raw errors with no self-correction path.
list_todos and search_todos return unbounded arrays. No pagination (limit, offset, cursor) despite baseline pattern paginated-result. Large todo lists blow context window.
No idempotency markers or tool annotations (readOnlyHint, destructiveHint). Agents cannot determine which tools are safe to retry. add_todo is non-idempotent (repeated calls create duplicate todos) but this is not signaled.
Output schemas are minimal. list_todos returns raw Todo objects; add_todo returns spread operator results. No documentation of what fields are guaranteed, what are optional, or what follows. Baseline A+ tools document return types fully.