Multi-language MCP server implementation for todo management with TypeScript, Go, and .NET implementations. Demonstrates Model Context Protocol compliance with HTTP and STDIO transports.
Server implements 4 CRUD tools (create_todo, read_todos, update_todo, delete_todo) with consistent naming patterns and basic schemas. All tools have action-verb names starting with create/read/update/delete, which is good. However, descriptions are generic (10-80 chars), parameter descriptions are minimal, and output schemas are not documented. The TypeScript/Go/C# implementations show tool registration, but schema documentation is incomplete. Per-tool scoring reveals: naming is solid (75-85), descriptions are weak (40-50, generic and brief), and schemas lack output documentation and rich parameter constraints. No error guidance, no pagination support for list operations, no destructive operation warnings in descriptions despite delete_todo being marked DESTRUCTIVE. Composition is acceptable, each tool does one thing, but the interface doesn't match the 'chat data model' well (e.g., IDs are required, no lookup-friendly alternatives). This is a typical fair/poor community server in the C-D range.
Creates a new todo with a description and creation date.
Deletes a todo by id.
Reads all todos, or a single todo if an id is provided.
Updates the specified todo fields by id.
Output schemas are not documented. Tools return strings (create_todo, update_todo, delete_todo) or lists (read_todos) but there is no schema specification for what fields are in the response, which breaks downstream tool chaining and forces LLMs to parse unstructured text.
Tool descriptions are generic and do not guide LLM selection or explain when to use each tool. 'Reads all todos, or a single todo if an id is provided' (58 chars) does not explain the difference between read_todos (fetch all vs. one by ID) and other potential discovery tools. Descriptions should be 50-200 chars and answer: What? When? What does it return?
Destructive tool (delete_todo) has no warning or confirmation step in the description. LLMs should know delete_todo is irreversible and non-retryable. Description should say: 'Permanently deletes a todo by id. This cannot be undone.' Additionally, no error guidance when deletion fails (e.g., todo not found).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 59 | - | v1 |
read_todos accepts optional 'id' parameter but returns a list regardless. Output schema is not documented, LLM doesn't know whether it gets a single Todo object or a list of one item. This ambiguity breaks downstream parsing and tool composition.
No pagination support on read_todos. If a user has 10,000 todos, returning all of them at once will exhaust the context window. Tool should support limit and offset/cursor parameters, and return a total count or next_cursor.
Parameter descriptions are minimal or missing context. 'Id of the todo to read (optional)' doesn't explain what format the id is in, what happens if it doesn't exist, or whether to pass a number or string.
No error recovery guidance. If an update_todo fails because the ID doesn't exist, the tool returns 'Todo with Id X not found.' but doesn't suggest 'Call read_todos() to fetch valid IDs.' LLMs need actionable error messages to self-correct.
create_todo response is a plain string: 'Todo created: {description} (Id: {id})'. Should return a structured object with fields {id, description, createdDate} so downstream tools can reference the new todo ID without parsing the string.