A simple REST API for managing TODO items with status tracking, built with Express and TypeScript. Provides CRUD operations, status filtering, and sample todo generation capabilities.
This HTTP REST API MCP server exposes 10 tools for todo management with basic structure but significant quality gaps. Tool naming follows verb-first conventions (list_todos, get_todo, create_todo, etc.), which is solid. However, parameter descriptions are minimal (many are generic like 'optional query parameter' or 'required path parameter' without explaining WHAT the parameter controls or WHY). Output schemas are not documented, there is no explicit schema definition for response structures. Error handling exists at the HTTP level but responses don't guide LLM recovery ('invalid status' errors are clear, but many 404s lack enrichment). Tool descriptions average ~80 chars and lack WHEN/WHY guidance. No tool annotations (readOnlyHint, destructiveHint, idempotentHint) are present. The codebase shows validation logic but it's buried in Express route handlers, not exposed via schema constraints.
Create a new todo. Only title is required, description and deadline are optional.
Delete a todo
Filter todos by status
Generate sample todos from predefined templates
API information - Get details about the TODO App API including version, description, features, and available endpoints
Get information about todo generator capabilities and statistics
API documentation - Get comprehensive list of all endpoints with descriptions, parameters, and examples
Get a specific todo by ID
Output schemas are not documented. Tools return JSON responses (e.g., list_todos returns {success, data, total}, create_todo returns {success, data, message}) but no schema is exposed to the LLM. LLMs cannot plan downstream chaining without knowing what fields to expect.
Parameter descriptions are generic and lack action context. Examples: 'optional query parameter (pending|in-progress|completed)' for status in list_todos tells LLM what values exist but not WHEN to use this filter or what it DOES. Compare to: 'Filter results to show only todos with this status (pending = not started, in-progress = actively being worked on, completed = done). Omit to see all todos.'
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 41 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 26 | - | v1 |
List all todos with optional status filter
Update a todo. All fields are optional - only provide the fields you want to update.
Destructive operations (delete_todo) lack confirmation workflow. The description says 'Delete a todo' but does not warn that this is irreversible or suggest a dry-run pattern. An agent could accidentally delete user data without safeguards.
Tool annotations are missing. delete_todo, update_todo, and create_todo should declare destructiveHint=true and write hints. list_todos, get_todo, filter_todos_by_status, get_generation_info, get_help, get_about should declare readOnlyHint=true. This enables agents to infer safety and idempotency without reading descriptions.
Error responses do not guide LLM recovery. 404 errors return {success: false, message: 'Todo not found'} but do not suggest alternatives like 'Try calling list_todos() to see available IDs' or offer available IDs. Per pattern:recovery-guide, errors should tell the agent what to do next.
Overlapping tool purpose: list_todos with optional status filter and filter_todos_by_status do nearly the same thing. list_todos?status=pending vs filter_todos_by_status with status=pending. LLMs will waste reasoning cycles deciding between them. Recommend consolidating or making the distinction clearer (e.g., filter_todos is more efficient for single-status queries).
Parameter type information is present in schema (e.g., status is enum, count is number) but NOT in descriptions. Descriptions say 'optional - number of todos to generate' but do NOT state the range (1-15) or default (1). LLMs read descriptions, not schemas, constraints must appear in text.
get_help and get_about tools are informational only and do not follow the principle of 'every tool does one thing.' They return human-readable API docs which are useful for initial discovery but add noise to the tool surface. Consider making API docs available via documentation links or a single '/api/discovery' resource instead.