Static source inference · medium confidence · evidence: Streamable HTTP
Current-spec patterns detected
Summary
This server has critical gaps in tool definitions. While 5 tools are registered via @McpTool annotation, almost ALL parameter descriptions are null/missing. Tool descriptions are either absent or trivial. The codebase shows tool names, but descriptions and parameter documentation are nearly nonexistent. Following the conservative calibration, this is an F-tier server in its current state.
ALL parameters have null/missing descriptions. Examples: 'orderId' in get_order_status, 'subscriberId' in changePlan, 'from'/'to' in getUsageHistory all have description:null.
Tool descriptions are missing or trivial. The annotation @McpTool on methods like listPlans() has no description parameter. Without a tool-level description, LLMs cannot determine WHEN or WHY to select the tool.
Parameter naming lacks type suffixes. Parameters like 'subscriberId', 'planId', 'orderId' are opaque system IDs. No description means the LLM cannot choose the right identifier type.
Recommendations
ADD DESCRIPTION to every @McpTool annotation. Example: @McpTool(name = "get_order_status", description = "Retrieve the current status of a customer order. Returns status (PENDING, PROCESSING, COMPLETED, FAILED, CANCELLED), message, and timestamp. Use this to check if an order is ready or failed.") Descriptions should be 50 - 200 characters, explain WHAT and WHEN, and avoid example values.
ADD DESCRIPTIONS to all method parameters using a custom annotation or JavaDoc. Example: public OrderStatusResponse getOrderStatus(@ToolParameter(description = "The unique order ID (e.g. ord-1001, ord-1002). Obtain from order confirmation email or create_order response.") String orderId).
RENAME 'getCurrentPlanOrThrow' to 'get_current_plan'. Drop the implementation detail (Throw). Document error case: 'Returns the active plan for a subscriber. Throws an error if subscriber has no active plan, use this to validate subscription status before calling changePlan.'
ADD OUTPUT SCHEMA documentation to each tool. Example for get_order_status: 'Returns: {orderId: string, status: PENDING|PROCESSING|COMPLETED|FAILED|CANCELLED, message: string, updatedAt: ISO 8601 timestamp}.' This helps LLMs understand what fields are available for downstream calls.
ADD ENUM constraints for known-set parameters. changePlan: planId should have enum ["starter-5g", "family-40g", "unlimited-plus"]. getUsageHistory: 'from' and 'to' should document accepted format (ISO 8601 date YYYY-MM-DD).
ADD PAGINATION support to listPlans(). Signature: listPlans(int limit = 20, int offset = 0) → returns {plans: [...], total: int, next_offset: ?int}.
Tool 'getCurrentPlanOrThrow' has a name that leaks implementation detail (Throw). Also, 'throw' implies error on missing plan, document whether this is an error or a normal case.
Date parameters 'from' and 'to' in getUsageHistory lack format documentation. The schema shows format:date, but no description explains the format (ISO 8601?), timezone handling, or required range.
No output schema documentation visible. While response models exist (OrderStatusResponse, ChangePlanResponse, etc.), the tool definitions do not explicitly document what fields the LLM should expect. LLMs need to know what fields to expect so they can plan downstream tool calls.'
changePlan is a WRITE tool but has NO error guidance. Agents need to know which calls are safe to retry and which have irreversible consequences.' No mention of idempotency, rollback, or failure recovery.
No enum constraints on parameters. Examples: 'planId' in changePlan could enumerate available plans (starter-5g, family-40g, unlimited-plus). 'from' and 'to' could have timezone enum. Free-form strings invite hallucinated values.'
listPlans() accepts zero parameters but should document pagination. The tool returns a List<Plan>, but there is no mention of result count, limit, or pagination.
No error recovery guidance. The OrderService throws ResponseStatusException(NOT_FOUND, 'Order not found'), but there is no tool description that tells the LLM what to do next. Try search_users() with a partial name."'
get_order_status
ADD ERROR RECOVERY GUIDANCE. Example for get_order_status: 'If order not found, confirm the order ID with the user or call search_orders(phone_number) to find matching orders.' Example for changePlan: 'This operation is idempotent, retrying with the same subscriberId + planId is safe. On failure, check error message. If subscriber does not exist, call get_current_plan(subscriberId) to validate.'
ADD IDEMPOTENCY HINT to changePlan. Since this is a WRITE tool, declare: @McpTool(description = "...", idempotentHint = true) so agents know they can safely retry if the network fails mid-call.
ADD COMPOSITION DETAILS. Document which tools call each other. E.g., 'To change a plan, first call get_current_plan(subscriberId) to confirm active plan, then call changePlan(subscriberId, planId). The response includes the new plan details and effective_at timestamp.'
DOCUMENT SUBSCRIBER LOOKUP. If subscriberId is a system ID, clarify: 'Subscriber ID is a 10-digit system identifier. If you have a phone number, call search_subscribers(phone_number) first.' This prevents LLMs from hallucinating IDs.