download_chart
Generate and save chart images to local files using Chart.js configurations for data visualization needs.
Instructions
Download a chart image to a local file
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| config | Yes | Chart configuration object | |
| outputPath | Yes | Path where the chart image should be saved |
Implementation Reference
- src/index.ts:243-273 (handler)Handler for the 'download_chart' tool. Parses config and outputPath from arguments, generates chart config and URL using helpers, downloads image with axios, saves to filesystem with fs.promises.writeFile, returns success message or throws MCP error.case 'download_chart': { try { const { config, outputPath } = request.params.arguments as { config: Record<string, unknown>; outputPath: string; }; const chartConfig = this.generateChartConfig(config); const url = await this.generateChartUrl(chartConfig); const response = await axios.get(url, { responseType: 'arraybuffer' }); const fs = await import('fs'); await fs.promises.writeFile(outputPath, response.data); return { content: [ { type: 'text', text: `Chart saved to ${outputPath}` } ] }; } catch (error: any) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Failed to download chart: ${error?.message || 'Unknown error'}` ); } }
- src/index.ts:197-214 (registration)Registration of the 'download_chart' tool in the ListTools response, including description and input schema definition.{ name: 'download_chart', description: 'Download a chart image to a local file', inputSchema: { type: 'object', properties: { config: { type: 'object', description: 'Chart configuration object' }, outputPath: { type: 'string', description: 'Path where the chart image should be saved' } }, required: ['config', 'outputPath'] } }
- src/index.ts:200-213 (schema)Input schema for the 'download_chart' tool, defining config object and outputPath string as required parameters.inputSchema: { type: 'object', properties: { config: { type: 'object', description: 'Chart configuration object' }, outputPath: { type: 'string', description: 'Path where the chart image should be saved' } }, required: ['config', 'outputPath'] }
- src/index.ts:79-142 (helper)Helper function generateChartConfig that validates chart type, constructs ChartConfig from arguments, handles special cases for certain chart types, called by download_chart handler.private generateChartConfig(args: any): ChartConfig { const { type, labels, datasets, title, options = {} } = args; this.validateChartType(type); const config: ChartConfig = { type, data: { labels: labels || [], datasets: datasets.map((dataset: any) => ({ label: dataset.label || '', data: dataset.data, backgroundColor: dataset.backgroundColor, borderColor: dataset.borderColor, ...dataset.additionalConfig })) }, options: { ...options, ...(title && { title: { display: true, text: title } }) } }; // Special handling for specific chart types switch (type) { case 'radialGauge': case 'speedometer': if (!datasets?.[0]?.data?.[0]) { throw new McpError( ErrorCode.InvalidParams, `${type} requires a single numeric value` ); } config.options = { ...config.options, plugins: { datalabels: { display: true, formatter: (value: number) => value } } }; break; case 'scatter': case 'bubble': datasets.forEach((dataset: any) => { if (!Array.isArray(dataset.data[0])) { throw new McpError( ErrorCode.InvalidParams, `${type} requires data points in [x, y${type === 'bubble' ? ', r' : ''}] format` ); } }); break; } return config; }
- src/index.ts:144-147 (helper)Helper function to generate QuickChart URL from ChartConfig by encoding JSON config as query parameter, used in download_chart.private async generateChartUrl(config: ChartConfig): Promise<string> { const encodedConfig = encodeURIComponent(JSON.stringify(config)); return `${QUICKCHART_BASE_URL}?c=${encodedConfig}`; }