Skip to main content
Glama

Show chart

fastero_show_chart
Read-only

Show a chart of a read-only query to the person, inside the conversation. Nothing is saved: the chart has a Save button that puts it on the dashboard you name, or fastero_save_chart with the same arguments saves it. dashboard names where Save puts it: the one being worked on, or a short new name if there is none. For a chart chartType can’t say, vegaLite instead of chartType and assignments: the answer then also holds the picture and a report of likely mistakes, so look at them and correct the chart before going on.

Input Schema

NameRequiredDescriptionDefault
sqlYesOne read-only statement returning one row per point: aggregate in SQL (GROUP BY), and ORDER BY the x axis.
titleYesThe chart’s title, as people will see it.
formatNoHow numbers read: currency adds $, percent adds %, compact abbreviates (1.2K). Defaults to number.
legendNoauto shows a legend for two series or more.
prefixNoWritten before each number: a currency other than dollars, say "€".
suffixNoWritten after each number: a unit, say " MWh" or " s".
regroupNoHow the numbers combine when the dashboard's period switch groups dates by a longer period: sum for totals and counts (the default), average for rates, prices, averages and percentiles (the default for percent), last for levels such as active users or a balance.
decimalsNoDigits after the decimal point, 0 to 6. Unset, money shows 2 and other numbers the digits they have.
vegaLiteNoA Vega-Lite v6 description, only for a chart chartType can't say: several panels, several kinds of mark on one chart, bands, shaded periods, labelled lines, a log or reversed axis, a colour per row, floating bars, side-by-side boxplots. A plain bar, line or pie stays chartType: it is shorter, follows the dashboard's Day/Week/Month switch, and a person can edit it by hand, which nobody can do to this. Rebuild an existing chart this way only when asked for something its type can't do; its old version stays in its history. The rows are the query's, so give no data. Give no config, background, padding, autosize or top-level title: the app decides the look, and the widget's name is the title (title.subtitle stays). About 800 wide in all, in numbers: width 720, height 320. Leave text colours to the theme. Not available: params, selections, url, href, the image and geoshape marks, and nested data. A fixed level line takes y: { datum: 80 }, and x: null under a shared x, or it draws one line per x. Formulas may call only simple functions (format, round, toDate, year and the like). Anything else, and any number people will quote, belongs in the query, so it reads the same in every view. sort: null keeps the query's order. To read well: say the finding in the name or subtitle, with its number, or, on a chart that refreshes, in a text mark worked out from the rows, since typed words go stale; a mid grey plus one accent colour, mid-tones that read on a light and a dark card, more only where they mean something; a target or limit on the chart as a labelled mark; values on the marks or an axis, not both; label only the points the finding rests on; bars start at zero. On a chart that refreshes, keep words and legends off the plot, where a later bar can land on them: a legend with orient "top", a text mark with y: -6 and baseline "bottom". Example: { "width": 720, "height": 320, "encoding": { "x": { "field": "month", "type": "temporal" } }, "layer": [ { "mark": { "type": "bar", "color": "#94a3b8" }, "encoding": { "y": { "field": "orders", "type": "quantitative" } } }, { "mark": { "type": "line", "color": "#3b82f6" }, "encoding": { "y": { "field": "avg_3m", "type": "quantitative" } } }, { "mark": { "type": "rule", "strokeDash": [4, 4] }, "encoding": { "x": null, "y": { "datum": 500 } } } ] }
chartTypeNoline or time_series for a measure over time; bar to compare categories (horizontal_bar for long labels, stacked_bar for the parts of each); pie or treemap for shares of one whole (a pie shows the 7 largest slices and groups the rest as Other); waterfall for steps that add up to a total; combo for two measures on different scales; scatter to relate two measures, bubble for three; heatmap for one measure across two categories. number for a number card: over a series (assignments { date, value }, one row per period) it shows the latest value, its change against the previous period and a trend line.
dashboardNoWhere Save puts the chart; its button names it. { id, name } for an existing dashboard (fastero_list_dashboards); { name } alone for a new one, which Save creates.
projectIdYesThe project the chart is saved into if the person keeps it: a project’s id, from fastero_list_projects.
sortOrderNoThe order a bar, horizontal_bar, pie or waterfall chart draws its categories in: by value, smallest first (asc) or largest first (desc), or as the query returns them (none, the default). A horizontal_bar reads desc from the top.
dataLabelsNoValues written on the chart. auto writes them on 12 points or fewer, and a pie's shares always.
assignmentsNoWhich result columns a chart plots, by chart type: bar, horizontal_bar, stacked_bar {category, value_slot_1, value_slot_2...}; line {xAxis, yAxis, optional value_slot_2, value_slot_3...} (a line each); time_series {date, yAxis1, optional yAxis2}; pie {category, value}; scatter {xAxis, yAxis}; waterfall {category, value}; combo {category, bar_value, line_value}; heatmap {xAxis, yAxis, value}; treemap {name, value}; bubble {xAxis, yAxis, size, optional category}; map {latitude, longitude, optional size, category, label}. Values are column names from the query result. Write the query to return one row per point (aggregate in SQL).
connectionIdYesA data connection’s id, from fastero_list_connections; fastero_create_file_connection makes one of an uploaded CSV or Excel file.
lowerIsBetterNoFor a number card: a fall is good news (costs, cancellations, churn), so a fall shows green.
referenceLinesNoLines and bands drawn across a bar, horizontal_bar, stacked_bar, line, time_series, combo or scatter chart: { type: "average" } a dashed line at the average of the points drawn; { type: "value", value } a line at a fixed value, such as a target; { type: "band", from, to } a shaded range. Each may have a label and a color (#rrggbb, #rgb or rgb(r, g, b)). The list replaces the chart's; [] removes them.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / vegaLite / description
      Previous value: -"A Vega-Lite v6 description, only for a chart chartType can't say: several panels, several kinds of mark on one chart, bands, shaded periods, labelled lines, a log or reversed axis, a colour per row, floating bars, side-by-side boxplots. A plain bar, line or pie stays chartType: it is shorter, follows the dashboard's Day/Week/Month switch, and a person can edit it by hand, which nobody can do to this. Rebuild an existing chart this way only when asked for something its type can't do; its old version stays in its history.\nThe rows are the query's, so give no data. Give no config, background, padding, autosize or top-level title: the app decides the look, and the widget's name is the title (title.subtitle stays). About 800 wide in all, in numbers: width 720, height 320. Leave text colours to the theme. Not available: params, selections, url, href, the image and geoshape marks, and nested data. A fixed level line takes y: { datum: 80 }, and x: null under a shared x, or it draws one line per x. Formulas may call only simple functions (format, round, toDate, year and the like). Anything else, and any number people will quote, belongs in the query, so it reads the same in every view. sort: null keeps the query's order.\nTo read well: say the finding in the name or subtitle, with its number, or, on a chart that refreshes, in a text mark worked out from the rows, since typed words go stale; a mid grey plus one accent colour, mid-tones that read on a light and a dark card, more only where they mean something; a target or limit on the chart as a labelled mark; values on the marks or an axis, not both; label only the points the finding rests on; bars start at zero.\nExample: { \"width\": 720, \"height\": 320, \"encoding\": { \"x\": { \"field\": \"month\", \"type\": \"temporal\" } }, \"layer\": [ { \"mark\": { \"type\": \"bar\", \"color\": \"#94a3b8\" }, \"encoding\": { \"y\": { \"field\": \"orders\", \"type\": \"quantitative\" } } }, { \"mark\": { \"type\": \"line\", \"color\": \"#3b82f6\" }, \"encoding\": { \"y\": { \"field\": \"avg_3m\", \"type\": \"quantitative\" } } }, { \"mark\": { \"type\": \"rule\", \"strokeDash\": [4, 4] }, \"encoding\": { \"x\": null, \"y\": { \"datum\": 500 } } } ] }"New value: +"A Vega-Lite v6 description, only for a chart chartType can't say: several panels, several kinds of mark on one chart, bands, shaded periods, labelled lines, a log or reversed axis, a colour per row, floating bars, side-by-side boxplots. A plain bar, line or pie stays chartType: it is shorter, follows the dashboard's Day/Week/Month switch, and a person can edit it by hand, which nobody can do to this. Rebuild an existing chart this way only when asked for something its type can't do; its old version stays in its history.\nThe rows are the query's, so give no data. Give no config, background, padding, autosize or top-level title: the app decides the look, and the widget's name is the title (title.subtitle stays). About 800 wide in all, in numbers: width 720, height 320. Leave text colours to the theme. Not available: params, selections, url, href, the image and geoshape marks, and nested data. A fixed level line takes y: { datum: 80 }, and x: null under a shared x, or it draws one line per x. Formulas may call only simple functions (format, round, toDate, year and the like). Anything else, and any number people will quote, belongs in the query, so it reads the same in every view. sort: null keeps the query's order.\nTo read well: say the finding in the name or subtitle, with its number, or, on a chart that refreshes, in a text mark worked out from the rows, since typed words go stale; a mid grey plus one accent colour, mid-tones that read on a light and a dark card, more only where they mean something; a target or limit on the chart as a labelled mark; values on the marks or an axis, not both; label only the points the finding rests on; bars start at zero. On a chart that refreshes, keep words and legends off the plot, where a later bar can land on them: a legend with orient \"top\", a text mark with y: -6 and baseline \"bottom\".\nExample: { \"width\": 720, \"height\": 320, \"encoding\": { \"x\": { \"field\": \"month\", \"type\": \"temporal\" } }, \"layer\": [ { \"mark\": { \"type\": \"bar\", \"color\": \"#94a3b8\" }, \"encoding\": { \"y\": { \"field\": \"orders\", \"type\": \"quantitative\" } } }, { \"mark\": { \"type\": \"line\", \"color\": \"#3b82f6\" }, \"encoding\": { \"y\": { \"field\": \"avg_3m\", \"type\": \"quantitative\" } } }, { \"mark\": { \"type\": \"rule\", \"strokeDash\": [4, 4] }, \"encoding\": { \"x\": null, \"y\": { \"datum\": 500 } } } ] }"
  2. Changed2 schema fields changed
    • addedInput schema / properties / vegaLite
      Added value: +{
      +  "description": "A Vega-Lite v6 description, only for a chart chartType can't say: several panels, several kinds of mark on one chart, bands, shaded periods, labelled lines, a log or reversed axis, a colour per row, floating bars, side-by-side boxplots. A plain bar, line or pie stays chartType: it is shorter, follows the dashboard's Day/Week/Month switch, and a person can edit it by hand, which nobody can do to this. Rebuild an existing chart this way only when asked for something its type can't do; its old version stays in its history.\nThe rows are the query's, so give no data. Give no config, background, padding, autosize or top-level title: the app decides the look, and the widget's name is the title (title.subtitle stays). About 800 wide in all, in numbers: width 720, height 320. Leave text colours to the theme. Not available: params, selections, url, href, the image and geoshape marks, and nested data. A fixed level line takes y: { datum: 80 }, and x: null under a shared x, or it draws one line per x. Formulas may call only simple functions (format, round, toDate, year and the like). Anything else, and any number people will quote, belongs in the query, so it reads the same in every view. sort: null keeps the query's order.\nTo read well: say the finding in the name or subtitle, with its number, or, on a chart that refreshes, in a text mark worked out from the rows, since typed words go stale; a mid grey plus one accent colour, mid-tones that read on a light and a dark card, more only where they mean something; a target or limit on the chart as a labelled mark; values on the marks or an axis, not both; label only the points the finding rests on; bars start at zero.\nExample: { \"width\": 720, \"height\": 320, \"encoding\": { \"x\": { \"field\": \"month\", \"type\": \"temporal\" } }, \"layer\": [ { \"mark\": { \"type\": \"bar\", \"color\": \"#94a3b8\" }, \"encoding\": { \"y\": { \"field\": \"orders\", \"type\": \"quantitative\" } } }, { \"mark\": { \"type\": \"line\", \"color\": \"#3b82f6\" }, \"encoding\": { \"y\": { \"field\": \"avg_3m\", \"type\": \"quantitative\" } } }, { \"mark\": { \"type\": \"rule\", \"strokeDash\": [4, 4] }, \"encoding\": { \"x\": null, \"y\": { \"datum\": 500 } } } ] }",
      +  "type": "object"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "projectId",
      -  "connectionId",
      -  "sql",
      -  "title",
      -  "chartType",
      -  "assignments"
      -]New value: +[
      +  "projectId",
      +  "connectionId",
      +  "sql",
      +  "title"
      +]
  3. Changed3 schema fields changed
    • changedInput schema / properties / assignments / description
      Previous value: -"Which result columns a chart plots, by chart type: bar, horizontal_bar, stacked_bar {category, value_slot_1, value_slot_2...}; line {xAxis, yAxis}; time_series {date, yAxis1, optional yAxis2}; pie {category, value}; scatter {xAxis, yAxis}; waterfall {category, value}; combo {category, bar_value, line_value}; heatmap {xAxis, yAxis, value}; treemap {name, value}; bubble {xAxis, yAxis, size, optional category}; map {latitude, longitude, optional size, category, label}. Values are column names from the query result. Write the query to return one row per point (aggregate in SQL)."New value: +"Which result columns a chart plots, by chart type: bar, horizontal_bar, stacked_bar {category, value_slot_1, value_slot_2...}; line {xAxis, yAxis, optional value_slot_2, value_slot_3...} (a line each); time_series {date, yAxis1, optional yAxis2}; pie {category, value}; scatter {xAxis, yAxis}; waterfall {category, value}; combo {category, bar_value, line_value}; heatmap {xAxis, yAxis, value}; treemap {name, value}; bubble {xAxis, yAxis, size, optional category}; map {latitude, longitude, optional size, category, label}. Values are column names from the query result. Write the query to return one row per point (aggregate in SQL)."
    • addedInput schema / properties / referenceLines
      Added value: +{
      +  "description": "Lines and bands drawn across a bar, horizontal_bar, stacked_bar, line, time_series, combo or scatter chart: { type: \"average\" } a dashed line at the average of the points drawn; { type: \"value\", value } a line at a fixed value, such as a target; { type: \"band\", from, to } a shaded range. Each may have a label and a color (#rrggbb, #rgb or rgb(r, g, b)). The list replaces the chart's; [] removes them.",
      +  "items": {
      +    "properties": {
      +      "color": {
      +        "type": "string"
      +      },
      +      "from": {
      +        "type": "number"
      +      },
      +      "label": {
      +        "maxLength": 40,
      +        "type": "string"
      +      },
      +      "to": {
      +        "type": "number"
      +      },
      +      "type": {
      +        "enum": [
      +          "average",
      +          "value",
      +          "band"
      +        ],
      +        "type": "string"
      +      },
      +      "value": {
      +        "type": "number"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 5,
      +  "type": "array"
      +}
    • addedInput schema / properties / sortOrder
      Added value: +{
      +  "description": "The order a bar, horizontal_bar, pie or waterfall chart draws its categories in: by value, smallest first (asc) or largest first (desc), or as the query returns them (none, the default). A horizontal_bar reads desc from the top.",
      +  "enum": [
      +    "none",
      +    "asc",
      +    "desc"
      +  ],
      +  "type": "string"
      +}
  4. Changed1 schema field changed
    • changedInput schema / properties / connectionId / description
      Previous value: -"A data connection’s id, from fastero_list_connections."New value: +"A data connection’s id, from fastero_list_connections; fastero_create_file_connection makes one of an uploaded CSV or Excel file."
  5. Changed5 schema fields changed
    • addedInput schema / properties / connectionId / description
      Added value: +"A data connection’s id, from fastero_list_connections."
    • addedInput schema / properties / dashboard / properties / id / description
      Added value: +"A dashboard’s id, from fastero_list_dashboards."
    • addedInput schema / properties / dashboard / properties / name / description
      Added value: +"The dashboard’s name."
    • changedInput schema / properties / projectId / description
      Previous value: -"The project the chart is saved into if the person keeps it."New value: +"The project the chart is saved into if the person keeps it: a project’s id, from fastero_list_projects."
    • addedInput schema / properties / title / description
      Added value: +"The chart’s title, as people will see it."
  6. First observed

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false; the description reinforces this with 'Nothing is saved' and explains the practical consequence – a Save button and a SAVE-time dashboard target. It also discloses that the vegaLite path returns the rendered picture plus a report of likely mistakes, which is meaningful behavior beyond the annotations. No contradiction with the read-only hint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with purpose and the save alternative before the vegaLite caveat. Some phrasing is dense and slightly awkward ('For a chart chartType can’t say'), but nothing is padding given an 18-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description only explains what comes back on the vegaLite branch; for the ordinary chartType path it never says what the answer contains (confirmation, rendered chart, validation errors). For a tool with nested objects and 18 parameters, the behavioral picture is adequate but leaves the return value of the common path to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: dashboard defaults to the dashboard being worked on or a short new name, and vegaLite replaces chartType and assignments and changes what comes back. It stays focused on the parameters an agent most often gets wrong rather than restating the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: show a chart of a read-only query to the person, inside the conversation. It explicitly separates itself from fastero_save_chart by saying nothing is saved and naming save_chart as the persisting alternative, so the agent can pick between them without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The show-versus-save choice is implied clearly (Save button or fastero_save_chart with the same arguments), and the vegaLite branch states when to use it over chartType ('only for a chart chartType can't say'). It stops short of an explicit when-not rule for the inline preview itself, but the routing context is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.