Rust MCP framework for building AI agents with tool support, resource handling, and prompt management
This MCP server exposes 10 tools with basic functionality but significant quality gaps. All tools have descriptions (20-72 chars average), which is better than missing descriptions, but they are terse and lack the LLM-optimized guidance needed for reliable tool selection. Most critically, NO parameter descriptions are visible in the code, the schema shows parameter names and types but no explanatory text for what each parameter controls or why the LLM should set it. Input schemas are present for all tools and properly typed (JSON Schema format), but lack the depth needed for robust agent reasoning. Error handling is minimal: tools return generic error messages without recovery guidance. The tool composition is reasonable (each tool does one thing), but naming could be more precise (e.g., 'calculator' with operation enum is vague compared to 'add_numbers'). No tool annotations (readOnlyHint, destructiveHint, idempotentHint) are present.
Add two numbers
Math operations: add, subtract, multiply, divide, power, sqrt
Echo back a message
Get weather for cities worldwide
Look up HTTP status codes
Validate and parse JSON strings
Multiply two numbers
Search for text pattern occurrences
NO parameter descriptions visible in source code. Every parameter (e.g., 'message', 'operation', 'location', 'code', 'a', 'b') lacks explanatory text. LLMs cannot determine what a 'message' parameter should contain, why 'operation' enum values matter, or the valid range for numeric 'a' and 'b'. This violates the critical pattern that every parameter needs a description explaining what it controls.
Tool descriptions are terse (20-72 chars) and lack LLM-optimized guidance. They state WHAT the tool does but not WHEN to use it or WHY instead of a similar tool. For example, 'Echo back a message' (21 chars) tells an LLM nothing about when to invoke it; 'Add two numbers' (15 chars, below the 20-char floor for description quality) provides minimal context. Best practice is 50-200 chars with explicit intent guidance.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 55 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 45 | 2024-11-05+ | v1 |
Get the length of a string
Reverse a text string
Weak naming conventions. Tools 'add' and 'multiply' are generic verbs without object context, they conflict with the verb_noun pattern (verb_object). Tools like 'calculator' hide the actual operation behind an enum, forcing the LLM to introspect the schema rather than inferring intent from the name. Recommended: 'add_numbers', 'multiply_numbers', or keep 'calculator' but rename it 'perform_math_operation' for clarity.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All tools are marked as READ_ONLY in the rubric submission, which is appropriate, but the source code does not show explicit annotation attributes in the Tool struct. This is a missing optional but valuable attribute for the current MCP spec (2026-07-28). Tools should declare their safety profile so agents can reason about side effects.
No input validation or constraints documented. The 'calculator' tool accepts 'operation' as an enum (good), but the numeric parameters 'a' and 'b' have no documented min/max. 'search_text' accepts arbitrary strings with no length limits. LLMs can pass huge payloads or invalid operations, leading to poor errors. Constraints must be stated in parameter descriptions and enforced server-side.
Error handling is non-actionable. The code returns generic error messages like 'Error::InvalidRequest("Division by zero")' and 'Error::ToolNotFound'. These tell the LLM THAT an error occurred but not WHAT TO DO NEXT. Best practice is 'Division by zero: try with b != 0' or 'Tool not found. Available tools: [list]'. Errors must guide recovery.
Output schemas are not documented in the source. Tools return 'ResultContent::Text { text: ... }' but there is no visible schema declaring what fields a caller should expect, whether the response is structured or free-form, or how to extract data for chaining. LLMs cannot plan downstream tool calls without knowing the response structure.
Redundant tools without clear differentiation. Both 'calculator' (with 'add' operation) and 'add' tool exist. Similarly, 'calculator' with 'multiply' and separate 'multiply' tool. LLMs waste reasoning cycles deciding which to use. Consolidate to one canonical set or clearly document when to prefer one over the other.