MCP server for managing shopping orders with CRUD operations
Shopping MCP has basic tool structure with explicit schema definitions, but exhibits significant gaps in parameter documentation, output schema clarity, and error handling guidance. All 5 tools have names starting with action verbs (CreateOrder, UpdateOrder, GetAllOrders, GetOrder, DeleteOrder) and are properly registered via [McpServerTool] attributes. However, parameter descriptions are entirely absent, input schemas exist but lack the descriptive context required for LLM-guided tool selection. Output types are inferred from method signatures (OrderDto, List<OrderDto>, void) but are not formally documented for the agent. The tool descriptions are minimal (5-12 words each), well below the 50-200 character optimum for LLM-driven planning. No enum constraints, validation rules, or error recovery guidance are visible. The server lacks permission gates on destructive operations (DeleteOrder) and provides no pagination support for GetAllOrders despite returning a list. Composition is clean, each tool has one responsibility, but chaining is not optimized: GetAllOrders returns OrderDto list without explanation of when to use it vs GetOrder(id).
Creates a new order and returns the created order.
Deletes an order by ID.
Gets all orders.
Gets an order by ID.
Updates an existing order.
Parameter descriptions completely absent. Input schemas exist (Name, Price for CreateOrder/UpdateOrder; id for GetOrder/DeleteOrder) but carry no descriptive text explaining what each parameter controls, its format, constraints, or valid ranges. LLMs cannot infer 'Price' means a decimal currency value vs a count vs a priority.
Tool descriptions are under 20 characters and provide minimal context. 'Creates a new order and returns the created order' (54 chars) barely explains what to pass or when to use it vs other tools. No guidance on prerequisites, side effects (writes state), or relationship to UpdateOrder.
No output schema documentation visible. OrderDto return type is inferred from C# method signature (Task<OrderDto>, Task<List<OrderDto>>) but not explicitly documented for the MCP client. LLMs do not know what fields OrderDto contains (Id, Name, Price) unless the client introspects runtime reflection, unportable and brittle.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 44 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 0 | - | v1 |
No error handling or recovery guidance. If CreateOrder is called with invalid Price (negative, non-numeric, or out of range), no error message guides the LLM to retry with valid input. DeleteOrder succeeds silently even if the order ID does not exist. No distinction between retryable and fatal errors.
Destructive operation (DeleteOrder) lacks permission checks, confirmation step, or dry-run capability. An LLM can invoke DeleteOrder(id=1) directly without user confirmation or access control, risking accidental deletion. No tool annotations (destructiveHint) declare this as irreversible.
GetAllOrders returns entire list without pagination. OrderService.Orders is a static in-memory list; GetAll() returns all items as List<OrderDto>. If the list grows to hundreds, response bloat wastes tokens and risks context window exhaustion. No limit, offset, or cursor parameters visible.
GetOrder response is nullable (Task<OrderDto?> in OrderService.cs) but tool definition does not document what happens if ID is not found. No error message or fallback guidance for the LLM if the order does not exist.
No input validation rules documented. Price parameter in CreateOrder/UpdateOrder accepts decimal but no description specifies: minimum (0?), maximum, currency precision (cents?), negative allowed?. LLMs will pass arbitrary values without guidance.