A Model Context Protocol server for creating interactive scatter plots from data
The server defines 4 tools with explicit schemas and descriptions visible in the source code. All tools have non-empty descriptions (range 150-400+ chars) that explain purpose and usage. All parameters have type definitions and descriptions. However, several critical issues limit the score: (1) output schemas are not formally documented, the code returns TextContent or list types without declaring the structure LLMs should expect; (2) error handling provides text responses but lacks structured error classification or recovery guidance; (3) parameters lack enums and range constraints that could prevent hallucinated invalid values; (4) no pagination support despite upload_data accepting CSV/Excel that could contain thousands of rows; (5) tool composition could be tighter, upload_data combines validation, storage, and summarization; (6) missing defensive validation on column names and parameter values.
Create an interactive scatter plot with dual Y-axes. This tool creates a single chart that can display multiple data series on primary and secondary Y-axes. Perfect for comparing different metrics. Args: dataset_name: Name of the uploaded dataset (default: "dataset") x_column: Column name for X-axis (REQUIRED) y_primary_columns: Comma-separated column names for primary Y-axis (REQUIRED) y_secondary_columns: Comma-separated column names for secondary Y-axis (optional) has_date_column: Set to true if your data contains date/time columns date_column: Name of the date column (if has_date_column is true) remove_outliers: Remove statistical outliers from the data outlier_threshold: Z-score threshold for outlier removal (default: 4.0) large_dataset: Enable optimization for datasets with >10,000 points chart_title: Custom title for the chart (optional) Returns: The scatter plot as an image that can be displayed Example: To plot Sales and Revenue against Date: - x_column: "Date" - y_primary_columns: "Sales,Revenue" - has_date_column: true - date_column: "Date"
Get detailed information about a specific column. Useful for understanding your data before plotting. Args: dataset_name: Name of the dataset (default: "dataset") column_name: Name of the column to inspect (REQUIRED) Returns: Statistical summary and information about the column
List all currently uploaded datasets and their columns. Use this to see what data is available for plotting. Returns: List of datasets with their columns
Upload and validate CSV or Excel data for plotting. This is the first step - upload your data before creating plots. IMPORTANT FOR CHATGPT: Do NOT pass file paths! This tool cannot access file systems. Instead, you must: 1. Read the file contents first (using your file reading capabilities) 2. Convert to CSV text format OR base64-encode the binary data 3. Pass the actual data content as a string Accepted data formats: - CSV text directly (preferred for Excel files - read and convert to CSV first) - Base64-encoded CSV file - Base64-encoded Excel file (.xlsx, .xls) Args: data: The actual file contents as CSV text or base64-encoded string (NOT a file path!) name: Name for this dataset (default: "dataset") Returns: Summary of the uploaded data including columns, rows, and preview Example usage: For Excel files: Read the Excel file, convert to CSV text, then call upload_data(csv_text) For CSV files: Read the CSV file contents, then call upload_data(csv_content)
Output schemas are not formally documented. Tools return TextContent, ImageContent, or implicit lists, but the LLM is not told what fields to expect or how to extract data for chaining. E.g., create_scatter_plot returns an image but the agent cannot predict the structure.
No enums for constrained parameters. x_column, y_primary_columns, y_secondary_columns are free-form strings with no validation that columns exist, LLM can hallucinate invalid column names. outlier_threshold is unbounded float with no range constraint (should be > 0, typically 1-5).
Error responses are unstructured text with no recovery guidance. E.g., 'Error: Dataset not found' tells the agent nothing. Should include: (1) error category (retryable vs user-fixable), (2) actionable next step ('try upload_data() first'), (3) available options (list available datasets).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 60 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 57 | - | v1 |
Parameters with interdependencies (has_date_column and date_column; y_secondary_columns depends on x_column and y_primary_columns existing) are not formalized. Schema should enforce these or descriptions should be explicit about constraints.
No pagination support. create_scatter_plot removes_outliers and large_dataset flags hint at large data handling, but upload_data and list_datasets do not declare limits on result size. If a CSV has 50k rows, does list_datasets return all of them? This violates mxe:enforce-result-limits.
Session state is in-memory global dictionary (session_data = {}). On restart, all uploaded datasets are lost. No persistence, no multi-user isolation. Production systems must handle this, document it or implement proper session management.