Skip to main content
Glama

generate_bar_chart

Create horizontal bar charts to visualize numerical comparisons across categories, supporting grouped or stacked data with customizable styles and themes.

Instructions

Generate a horizontal bar chart to show data for numerical comparisons among different categories, such as, comparing categorical data and for horizontal comparisons.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dataYesData for bar chart, such as, [{ category: '分类一', value: 10 }, { category: '分类二', value: 20 }], when grouping or stacking is needed for bar, the data should contain a `group` field, such as, when [{ category: '北京', value: 825, group: '油车' }, { category: '北京', value: 1000, group: '电车' }].
groupNoWhether grouping is enabled. When enabled, bar charts require a 'group' field in the data. When `group` is true, `stack` should be false.
stackNoWhether stacking is enabled. When enabled, bar charts require a 'group' field in the data. When `stack` is true, `group` should be false.
styleNoStyle configuration for the chart with a JSON object, optional.
themeNoSet the theme for the chart, optional, default is 'default'.default
widthNoSet the width of chart, default is 600.
heightNoSet the height of chart, default is 400.
titleNoSet the title of chart.
axisXTitleNoSet the x-axis title of chart.
axisYTitleNoSet the y-axis title of chart.

Implementation Reference

  • Generic MCP tool handler that executes generate_bar_chart: maps to chartType='bar', validates args with Charts.bar.schema, generates chart URL via generateChartUrl, returns content with URL and spec metadata.
    export async function callTool(tool: string, args: object = {}) { logger.info(`Calling tool: ${tool}`); const chartType = CHART_TYPE_MAP[tool as keyof typeof CHART_TYPE_MAP]; if (!chartType) { logger.error(`Unknown tool: ${tool}`); throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${tool}.`); } try { // Validate input using Zod before sending to API. // Select the appropriate schema based on the chart type. const schema = Charts[chartType].schema; if (schema) { // Use safeParse instead of parse and try-catch. const result = z.object(schema).safeParse(args); if (!result.success) { logger.error(`Invalid parameters: ${result.error.message}`); throw new McpError( ErrorCode.InvalidParams, `Invalid parameters: ${result.error.message}`, ); } } const isMapChartTool = [ "generate_district_map", "generate_path_map", "generate_pin_map", ].includes(tool); if (isMapChartTool) { // For map charts, we use the generateMap function, and return the mcp result. const { metadata, ...result } = await generateMap(tool, args); return result; } const url = await generateChartUrl(chartType, args); logger.info(`Generated chart URL: ${url}`); return { content: [ { type: "text", text: url, }, ], _meta: { description: "This is the chart's spec and configuration, which can be renderred to corresponding chart by AntV GPT-Vis chart components.", spec: { type: chartType, ...args }, }, }; // biome-ignore lint/suspicious/noExplicitAny: <explanation> } catch (error: any) { logger.error( `Failed to generate chart: ${error.message || "Unknown error"}.`, ); if (error instanceof McpError) throw error; if (error instanceof ValidateError) throw new McpError(ErrorCode.InvalidParams, error.message); throw new McpError( ErrorCode.InternalError, `Failed to generate chart: ${error?.message || "Unknown error."}`, ); } }
  • Defines the input schema using Zod for generate_bar_chart (data array with category/value/group, options for group/stack/style/theme/size/titles) and the tool descriptor with name, description, inputSchema.
    const schema = { data: z .array(data) .describe( "Data for bar chart, such as, [{ category: '分类一', value: 10 }, { category: '分类二', value: 20 }], when grouping or stacking is needed for bar, the data should contain a `group` field, such as, when [{ category: '北京', value: 825, group: '油车' }, { category: '北京', value: 1000, group: '电车' }].", ) .nonempty({ message: "Bar chart data cannot be empty." }), group: z .boolean() .optional() .default(false) .describe( "Whether grouping is enabled. When enabled, bar charts require a 'group' field in the data. When `group` is true, `stack` should be false.", ), stack: z .boolean() .optional() .default(true) .describe( "Whether stacking is enabled. When enabled, bar charts require a 'group' field in the data. When `stack` is true, `group` should be false.", ), style: z .object({ backgroundColor: BackgroundColorSchema, palette: PaletteSchema, texture: TextureSchema, }) .optional() .describe( "Style configuration for the chart with a JSON object, optional.", ), theme: ThemeSchema, width: WidthSchema, height: HeightSchema, title: TitleSchema, axisXTitle: AxisXTitleSchema, axisYTitle: AxisYTitleSchema, }; // Bar chart tool descriptor const tool = { name: "generate_bar_chart", description: "Generate a horizontal bar chart to show data for numerical comparisons among different categories, such as, comparing categorical data and for horizontal comparisons.", inputSchema: zodToJsonSchema(schema), annotations: { title: "Generate Bar Chart", readOnlyHint: true, }, };
  • src/server.ts:64-77 (registration)
    Dynamically registers all chart tools (including generate_bar_chart from Charts.bar.tool) for ListTools and CallTool requests on the MCP server, delegating execution to callTool.
    function setupToolHandlers(server: Server): void { logger.info("setting up tool handlers..."); server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: getEnabledTools().map((chart) => chart.tool), })); // biome-ignore lint/suspicious/noExplicitAny: <explanation> server.setRequestHandler(CallToolRequestSchema, async (request: any) => { logger.info("calling tool", request.params.name, request.params.arguments); return await callTool(request.params.name, request.params.arguments); }); logger.info("tool handlers set up"); }
  • Helper function called by callTool to generate the actual bar chart: POSTs {type: 'bar', ...args, source} to vis server API and returns the chart URL.
    export async function generateChartUrl( type: string, // biome-ignore lint/suspicious/noExplicitAny: <explanation> options: Record<string, any>, ): Promise<string> { const url = getVisRequestServer(); const response = await axios.post( url, { type, ...options, source: "mcp-server-chart", }, { headers: { "Content-Type": "application/json", }, }, ); const { success, errorMessage, resultObj } = response.data; if (!success) { throw new Error(errorMessage); } return resultObj; }

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/antvis/mcp-server-chart'

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