This server provides two search tools with basic definitions but significant quality gaps. Both tools have functional async implementations with error handling, but the parameter descriptions lack necessary context and detail expected in production-grade tools. Output is returned as plain text rather than structured data. Tool names follow the verb_noun pattern ('get_coles_products', 'get_woolworths_products') which is good, but descriptions are minimal (e.g., 'Search for products at Coles.' lacks context on when to use this tool vs. alternatives, what fields are returned, or pagination behavior). Parameter descriptions exist but are extremely terse, e.g., 'The product search query.' does not explain format constraints, length limits, or examples. No output schema is documented anywhere in the code, forcing LLMs to guess at response structure. Error handling exists but returns raw exception strings rather than actionable recovery guidance.
Parameter descriptions are under 30 characters and lack actionable constraints. 'The product search query' does not specify format, length, example, or whether special characters are supported.
Tool descriptions are 30 - 33 characters, well below the 50 - 200 char baseline. They lack WHEN to use this tool, WHAT it returns, and dependencies (e.g., 'Call this first to discover available store IDs').
No pagination support. If a search returns many products, the entire list is formatted and returned as unstructured text, wasting tokens and risking context window exhaustion.
Recommendations
Expand tool descriptions to 80 - 150 chars. Example for get_coles_products: 'Search the Coles supermarket product catalog by keyword. Returns up to the specified limit of results (default 10), sorted by sales volume. Requires a store_id (defaults to store 0584 in Sydney). Use this to find product availability, pricing, and unit quantities at Coles. If you need to search Woolworths instead, use get_woolworths_products.'
Add parameter descriptions with actionable constraints. For 'query': 'The product name or keyword to search (1 - 200 chars, e.g., "milk" or "greek yogurt"). Special characters like * and ? are not supported.' For 'store_id': 'The Coles store ID (5-digit number, e.g., 0584). Call list_coles_stores() to discover valid IDs for a given location.' For 'limit': 'Maximum number of results to return (1 - 50, default 10). Higher limits return more products but increase token usage.'
Document output schema explicitly. Example: 'Returns a list of products, each with: name (string), price (float, AUD), unit (string, e.g., "1L" or "500g"), store (string, always "Coles").' If returning a string, specify the format: 'Results are formatted as rows separated by "---", with fields Name, Price, Unit, Store per product.'
Implement structured output. Instead of formatting strings, return JSON: [{"name": "...", "price": 2.50, "unit": "1L", "store": "Coles"}]. This enables downstream tools to extract data programmatically and reduces token overhead.
Add pagination support. Accept 'page' and 'page_size' parameters (default page_size=10, page=1). Return a results object: {"products": [...], "page": 1, "page_size": 10, "total": 237, "next_page": 2}. State in the description: 'Results are paginated. Use page and page_size to navigate large result sets.'
Error responses return raw exception strings ('An unexpected error occurred in get_coles_products: {str(e)}') which provide no recovery guidance. LLM cannot determine if the error is retryable, user-fixable, or fatal.
Coles API key is injected via environment variable (good), but the code does not validate that COLES_API_KEY is set before making API calls. A missing key will produce a cryptic API error rather than a clear 'API key not configured' message.
Asymmetric tool signatures: get_coles_products accepts store_id, but get_woolworths_products does not. This asymmetry is not explained in the descriptions, forcing the LLM to reason about architectural differences rather than understanding domain semantics.
Output is a single formatted string ('Name: X\nPrice: Y\n---\n...') rather than structured JSON. This forces LLMs to parse unstructured text, increases token usage, and makes downstream tool chaining difficult.
get_coles_productsget_woolworths_products
Improve error messages with recovery guidance. Example: 'Store ID 0999 not found. Available store IDs in Sydney: 0584, 0585, 0586. Try call list_coles_stores("Sydney") to discover stores near you.' For API errors: 'Coles API returned status 429 (rate limited). Please retry in 60 seconds.' For timeout: 'Search timed out after 10s. Simplify your query (e.g., search for "milk" instead of "dairy products low-fat high-protein") and retry.'
Add a list_coles_stores() tool to help users discover valid store IDs by location. This prevents invalid store_id errors and surfaces store availability before product searches.
Validate that COLES_API_KEY is set at server startup. Return a clear error message if it is missing: 'COLES_API_KEY not configured. Set this environment variable before starting the server.'
Document the difference between Coles and Woolworths in the tool descriptions. Example: 'Coles allows filtering by store ID; Woolworths searches nationally. If you know the store location, use get_coles_products; otherwise, use get_woolworths_products.'
Add tool annotations (readOnlyHint=true, idempotentHint=true) to signal that these tools are safe to call multiple times and do not modify state. This helps agents retry on transient failures without risk.