A Python MCP server with CSV reading and aggregation tools, plus a hello world example
Three tools with generally good structure but uneven quality. read_csv and aggregate_csv have complete schemas and reasonable descriptions; health_check is a utility with minimal purpose. Descriptions are present but fall short of LLM-optimization standards (most are 100-200 chars, acceptable but not rich). Parameter descriptions exist for all required params but lack constraint/format detail. Output schemas are documented in code but not explicitly in tool metadata. Error handling is present and actionable (file checks, validation messages) but could be more prescriptive about recovery steps. No tool annotations (readOnlyHint, idempotentHint) are declared despite all three being read-only operations.
Aggregates data in a CSV file to return total, mean, median, etc. for a column. Use when calculating total, avg, mean, median, etc. for a column in a CSV file. Example: 'sum sales by region', 'give the total sales by region', 'give total count of unit sold in sample.csv'
health check endpoint
Reads a CSV file and returns the contents with detailed analysis Use when analyzing CSV files or reading csv files Example: 'read_csv sample.csv' 'what is in sample.csv?'
health_check is not a legitimate tool, it's a utility endpoint. The name 'health_check' does not start with an action verb that reflects a user-facing intent. 'ping' parameter has empty description. This tool serves no purpose in an agent's task planning.
Tool descriptions lack specificity about when to use them. read_csv says 'Use when analyzing CSV files or reading csv files' (circular). No guidance on how read_csv differs from aggregate_csv or when to prefer one. LLMs will struggle to disambiguate.
Parameter descriptions lack constraint detail. 'file_path': 'Path to the CSV file, ask the user if not clear' is vague, no mention of supported formats, max file size, absolute vs relative paths, or what happens if the file is not a CSV. 'agg_function': 'Aggregation function to apply: sum, mean, median, min, max, std, count' should be an enum constraint, not a free-text description.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 51 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 40 | - | v1 |
No tool annotations declared. All three tools are read-only (marked 'Risk: READ_ONLY') but do not include readOnlyHint in schema. This metadata helps agents understand safety and retry behavior.
Output schema is documented in code comments and inline examples but not explicitly exposed in tool metadata. LLMs cannot see the structure of the returned JSON (success, file_info, preview, statistics, schema, metadata) without reading the source. Should be documented in description or via explicit response schema field.
aggregate_csv accepts a 'group_by' parameter that takes comma-separated column names but does not document this format in the parameter description. An LLM might pass a single string or an array, causing confusion.