Skip to main content
Glama
MR901

mcp-plots

render_chart

Create charts from tabular data for visualization, with options for line, bar, pie, scatter plots and more. Supports data analysis suggestions and multiple output formats including PNG, SVG, and Mermaid diagrams.

Instructions

Render a chart from tabular data and return MCP-compatible content. Special modes: - chart_type="help": Returns available chart types, themes, and field suggestions - chart_type="suggest": Analyzes your data and suggests field mappings (requires data) Parameters: - chart_type: chart type ("line", "bar", "pie", etc.) or "help"/"suggest" - data: list of objects (rows) - optional for help mode - field_map: keys like x_field, y_field, category_field, value_field, group_field, size_field - config_overrides: subset of ChartConfig as dict (width, height, title, theme, dpi, etc.) - options: generator-specific options (e.g., smooth, stack) - output_format: MCP_IMAGE (PNG), MCP_TEXT (SVG), or MERMAID

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
chart_typeYes
config_overridesNo
dataNo
field_mapNo
optionsNo
output_formatNo

Implementation Reference

  • MCP @tool decorator registration and handler function for render_chart. This is the entry point called by MCP when the tool is invoked, which delegates to the implementation.
    def render_chart( chart_type: str, data: List[Dict[str, Any]] = None, field_map: Dict[str, str] = None, config_overrides: Dict[str, Any] = None, options: Dict[str, Any] = None, output_format: str = None ) -> Dict[str, Any]: """ Render a chart from tabular data and return MCP-compatible content. Special modes: - chart_type="help": Returns available chart types, themes, and field suggestions - chart_type="suggest": Analyzes your data and suggests field mappings (requires data) Parameters: - chart_type: chart type ("line", "bar", "pie", etc.) or "help"/"suggest" - data: list of objects (rows) - optional for help mode - field_map: keys like x_field, y_field, category_field, value_field, group_field, size_field - config_overrides: subset of ChartConfig as dict (width, height, title, theme, dpi, etc.) - options: generator-specific options (e.g., smooth, stack) - output_format: MCP_IMAGE (PNG), MCP_TEXT (SVG), or MERMAID """ return _render_chart_impl( chart_type=chart_type, data=data, field_map=field_map, config_overrides=config_overrides, options=options, output_format=output_format )
  • Registration call site where register_tools is invoked to register the render_chart tool (and others) with the MCP server during server startup.
    # Import and register visualization tools from src.capabilities.tools import register_tools register_tools(self.mcp_server, config=capabilities_config) # Extract registered tool list for summary display # Note: Uses internal API that may change in future FastMCP versions try: self.mcp_registered_tools = self.mcp_server._tool_manager.list_tools() except Exception: # Best-effort: fall back to empty list if internal API differs self.mcp_registered_tools = [] logger.info("MCP tools registration complete.")
  • Dataclass ChartRequest defines the structured input schema for the render_chart tool, including from_tool_params factory method to convert tool parameters and validation logic.
    @dataclass class ChartRequest: """ Complete chart generation request with validation. Encapsulates all information needed to generate a chart, including data, configuration, and output preferences. """ chart_type: str data: List[Dict[str, Any]] field_mapping: FieldMapping = field(default_factory=FieldMapping) config_overrides: Dict[str, Any] = field(default_factory=dict) options: Dict[str, Any] = field(default_factory=dict) output_format: Optional[str] = None mode: ChartRequestMode = ChartRequestMode.RENDER def __post_init__(self): """Validate request after initialization""" # Only validate for render mode, not for help/suggest if self.mode == ChartRequestMode.RENDER: self.validate() @classmethod def from_tool_params( cls, chart_type: str, data: Optional[List[Dict[str, Any]]] = None, field_map: Optional[Dict[str, str]] = None, config_overrides: Optional[Dict[str, Any]] = None, options: Optional[Dict[str, Any]] = None, output_format: Optional[str] = None ) -> 'ChartRequest': """Create request from MCP tool parameters""" # Determine mode based on chart_type if chart_type == "help": mode = ChartRequestMode.HELP elif chart_type == "suggest": mode = ChartRequestMode.SUGGEST else: mode = ChartRequestMode.RENDER return cls( chart_type=chart_type, data=data or [], field_mapping=FieldMapping.from_dict(field_map or {}), config_overrides=config_overrides or {}, options=options or {}, output_format=output_format, mode=mode ) def validate(self) -> None: """Validate request for chart generation""" if self.mode == ChartRequestMode.RENDER: if not self.data: raise ValueError(ChartConstants.ErrorMessages.EMPTY_DATA) if not isinstance(self.data, list): raise ValueError(ChartConstants.ErrorMessages.INVALID_DATA_TYPE) if len(self.data) > ChartConstants.ConfigDefaults.MAX_DATA_POINTS: raise ValueError(f"Data exceeds maximum allowed points: {ChartConstants.ConfigDefaults.MAX_DATA_POINTS}") elif self.mode == ChartRequestMode.SUGGEST: if not self.data: raise ValueError("Data is required for field suggestions") def get_field_kwargs(self) -> Dict[str, Any]: """Get field mappings as kwargs for ChartGenerator""" return self.field_mapping.get_non_none_fields() def is_special_mode(self) -> bool: """Check if this is a special mode request (help/suggest)""" return self.mode in (ChartRequestMode.HELP, ChartRequestMode.SUGGEST)
  • Internal implementation of render_chart that creates ChartRequest and delegates to ChartRenderingService.
    def _render_chart_impl( chart_type: str, data: List[Dict[str, Any]] = None, field_map: Dict[str, str] = None, config_overrides: Dict[str, Any] = None, options: Dict[str, Any] = None, output_format: str = None ) -> Dict[str, Any]: """ Render a chart from tabular data and return MCP-compatible content. Special modes: - chart_type="help": Returns available chart types, themes, and field suggestions - chart_type="suggest": Analyzes your data and suggests field mappings (requires data) Parameters: - chart_type: chart type ("line", "bar", "pie", etc.) or "help"/"suggest" - data: list of objects (rows) - optional for help mode - field_map: keys like x_field, y_field, category_field, value_field, group_field, size_field - config_overrides: subset of ChartConfig as dict (width, height, title, theme, dpi, etc.) - options: generator-specific options (e.g., smooth, stack) - output_format: MCP_IMAGE (PNG), MCP_TEXT (SVG), or MERMAID """ try: # Create chart request from parameters request = ChartRequest.from_tool_params( chart_type=chart_type, data=data, field_map=field_map, config_overrides=config_overrides, options=options, output_format=output_format ) # Use chart service chart_service = _get_chart_service() response = chart_service.render_chart(request) # Convert to MCP format return response.to_mcp_format() except Exception as e: logger.error(f"render_chart failed: {e}") return {"status": "error", "error": str(e)}
  • Core service method implementing the chart rendering logic: handles modes, validation, config building, generation via factory, and response normalization.
    def render_chart(self, request: ChartRequest) -> ChartResponse: """ Render chart with full error handling and configuration management. Args: request: Complete chart rendering request Returns: ChartResponse: Standardized response with content or error """ try: # Handle special modes if request.mode == ChartRequestMode.HELP: return self._generate_help_response() if request.mode == ChartRequestMode.SUGGEST: return self._generate_field_suggestions(request.data) # Validate request for regular chart rendering request.validate() # Get user preferences user_prefs = self._config_service.get_user_preferences() # Build chart configuration config = self._build_chart_config(request, user_prefs) # Build chart data chart_data = self._build_chart_data(request) # Generate chart using factory result = self._chart_factory.generate_chart( request.chart_type, chart_data=chart_data, config=config, **request.options ) # Normalize response content = self._normalize_chart_result(result) return ChartResponse.success_response( content=content, metadata={ "chart_type": request.chart_type, "data_points": len(request.data), "output_format": config.output_format.value, "generation_time": datetime.now().isoformat() } ) except Exception as e: # Use centralized error handling error_response = ErrorHandler.handle_chart_error(e, getattr(request, 'chart_type', None)) # Log the error with appropriate level if isinstance(e, ChartGenerationError): self._logger.warning(f"Chart generation error: {e}") else: self._logger.error(f"Unexpected chart rendering error: {e}") return ChartResponse.error_response( error=error_response["error"], metadata={ "chart_type": getattr(request, 'chart_type', 'unknown'), "error_code": error_response.get("error_code", "UNKNOWN_ERROR"), "error_type": type(e).__name__ } )

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MR901/mcp-plots'

If you have feedback or need assistance with the MCP directory API, please join our Discord server