Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
The CSV Editor server provides 29 tools with consistent naming (verb_noun pattern) and complete input schemas. However, descriptions lack LLM-optimization depth, parameter descriptions are often generic, and output schemas are undocumented. Most tools follow naming conventions well (get_, load_, export_, etc.) but descriptions are typically 30-80 characters, below the baseline of 194 chars for A+ tools. No tools have documented return types or output schemas, which breaks the composition pattern where downstream tools need to know what data is available. Error handling is absent from tool definitions. The server demonstrates reasonable structure but significant gaps in making tools LLM-friendly for multi-step planning.
No output/return schemas documented for any tool. LLMs cannot plan multi-step workflows when they don't know what fields downstream tools will receive. For example, load_csv succeeds but LLM doesn't know if response includes row_count, column_names, session_id structure, or error details.
Document output/return schemas for all 29 tools. Include example response structures showing field names, types, and what IDs/references are returned. This enables LLMs to chain tools and plan multi-step workflows.
Expand descriptions to 150-250 characters. Add WHEN to use (vs similar tools), WHAT it returns, and any side effects. Example: 'Filter rows by one or more conditions. Returns filtered dataframe with unchanged columns. Use before sort_data to narrow scope or after loading for validation. Returns session_id and updated row_count.'
Convert generic 'object' parameters into explicit nested schemas. For filter_rows.conditions, specify: [{column: string, operator: enum(==,!=,>,<,>=,<=,in,contains), value: string|number}]. For group_by_aggregate.aggregations, specify: {[column_name]: enum(sum,mean,count,min,max,std)}.
Add enum constraints for all multi-choice parameters: format in export_csv, method in get_correlation_matrix, strategy in fill_missing_values, method in detect_outliers. Remove these from descriptions once enums are defined.
Expose risk classification as tool annotations. Mark remove_columns, remove_duplicates, and export_csv with destructiveHint=true. Mark read-only tools (get_*, list_*, check_*, detect_*, profile_*, validate_*) with readOnlyHint=true. This guides agent behavior without extra tool calls.
Add confirmation/dry-run support to destructive tools. For remove_columns and remove_duplicates, add optional 'dry_run: boolean' parameter. Description should state: 'Set dry_run=true to preview rows that would be removed without making changes.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Descriptions are 50-65 characters average, well below the 194-char baseline for A+ tools. Descriptions like 'Filter rows based on conditions', 'Sort data by columns', 'Get statistics for numeric columns' lack context about WHEN to use each tool vs alternatives, prerequisites, or what data structures are returned. LLMs cannot reliably distinguish similar tools.
Parameters like 'conditions' (filter_rows), 'aggregations' (group_by_aggregate), and 'schema' (validate_schema) are typed as generic objects without nested schema documentation. LLMs cannot know what keys, types, or structure these objects require, forcing them to guess or hallucinate.
No error handling guidance in tool definitions. Tools like remove_columns and remove_duplicates are DESTRUCTIVE (irreversible) but lack descriptions about confirmation, dry-run support, or recovery steps. Agents have no way to know if they should ask the user before executing.
No distinction in LLM-facing tool metadata between read-only and destructive operations. Risk classifications (READ_ONLY, WRITE, DESTRUCTIVE, REVERSIBLE) exist in the evaluation metadata but are not exposed as tool annotations. LLMs cannot infer operation safety from tool definitions alone.
Session-based architecture requires LLMs to manage session IDs across multiple calls. Many tools require session_id as a string parameter, but no tool explicitly returns the session structure needed for subsequent calls. Breaks the tool-chain pattern, load_csv must return a session_id that filter_rows accepts, but response schema is undocumented.
Enum constraints missing for multi-choice parameters. 'delimiter' defaults to ',' but accepts any string; 'format' in export_csv lists options (csv, json, excel, parquet, html, markdown, tsv) in description but not as enum constraint. LLMs will hallucinate invalid formats.
Pagination missing from list_sessions and tools that return multiple results (e.g., get_value_counts defaults to top_n=10, but no offset/limit or cursor mechanism documented). Large result sets could blow context window; no guidance on how to iterate through results.
list_sessionsget_value_countsgroup_by_aggregate
Document session_id flow explicitly. In load_csv description: 'Returns session_id. Pass this session_id to all subsequent tools (filter_rows, sort_data, export_csv, etc.) to operate on the same data.' In each subsequent tool, add: 'Required. Identifies which loaded CSV to operate on. Obtain from load_csv or list_sessions.'
Add pagination to list_sessions. Add parameters: offset (default 0), limit (default 20, max 100). Return total_sessions count. Repeat for get_value_counts and group_by_aggregate.
For parameters accepting complex patterns (e.g., regex in update_column.pattern), add format guidance. Example: 'Regex pattern (Python re syntax). Test with simple patterns first; see https://regex101.com for testing.'
Clarify parameter relationships. In add_column, 'value' and 'formula' are mutually exclusive, state: 'Provide either value (static default) or formula (computed per row), not both. If both provided, formula takes precedence.' Repeat for export_csv (file_path optional if format is print-only).
Add defaults that match common use cases. close_session could default to a confirmation prompt rather than silently closing. fill_missing_values defaulting to 'drop' may surprise users expecting mean imputation, make default explicit in description.