Skip to main content
Glama

add_widget

Add a data widget (table, chart, KPI) to a report from a plain-language instruction. The request is mapped to the report's connected data; when the data is not connected or the metric is not supported yet, the answer gives the reason. Blended all-channels widgets need two or more paid ad accounts; their blended rates are recomputed from pooled totals, never averaged. Granularity words (daily, weekly, monthly) set a chart's time scale; a period ("last 12 months") is not one. GA4 visits by channel per month is the GA4 table "Channel × Month": one row per channel, one column per calendar month, one metric. The widget goes at the end of the report unless position (start, end, before or after a widget, section_start or section_end, with anchorId from get_report) or the instruction names an existing widget or section. budgetLines builds a Budget vs actual table without AI. The instruction is read by AI; the preview's aiCost states who pays. Free-text blocks use add_text_widget. Requires MCP write actions; without confirm:true it returns a preview.

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "reportId": "<reportId>",
      "instruction": "<instruction>"
    },
    "name": "add_widget"
  }
}

Input Schema

NameRequiredDescriptionDefault
titleNoWith budgetLines only: the table's title.
confirmNoSet true to add it. Omit for a preview of what will be interpreted and added. With confirm:true, also pass the preview's previewToken.
anchorIdNoWith position before, after, section_start or section_end: the id of the widget or section (from get_report). After a section = after everything in it.
channelsNoWith budgetLines: restrict to these channels, e.g. ["Google Ads", "Meta Ads"] (default every connected paid channel).
positionNoWhere the widget goes (default end, or what the instruction states): start, end, before / after a widget, section_start / section_end of a section. All but start and end need anchorId. Wins over a placement in the instruction.
reportIdYesReport id (from list_reports).
budgetLinesNoBudget vs actual table (All channels), no AI: the product lines in order. A campaign goes to the FIRST line it matches; the rest shows as Not assigned. A month with no budget reads '—', never 0. add_widget builds the table (instruction names it); edit_widget with widgetId replaces the table's COMPLETE list.
instructionYesWhat widget to add, in plain language. It may say where ("right after the Top campaigns table", "at the end of the SEO section") when it names an existing widget or section.
previewTokenNoWith confirm:true: the previewToken from this tool's preview (valid 15 minutes, once, for exactly the previewed arguments).
plannedSourceNoWith budgetLines: where the planned budget comes from. settings = the campaigns' own budgets (Google Ads, Meta), read daily, history from the first reading; manual (default) = the amounts given; settings+manual = settings, but a month with an amount given uses it. On edit_widget it can be sent alone.
budgetCurrencyNoWith budgetLines: the ISO currency the budgets are in, e.g. EUR. Optional: without it the table labels the accounts' dominant currency on each render and says so.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
    • removedInput schema / additionalProperties
      Removed value: -false
    • removedInput schema / properties / budgetLines / items / additionalProperties
      Removed value: -false
    • addedInput schema / properties / budgetLines / items / properties / budgets / propertyNames
      Added value: +{
      +  "type": "string"
      +}
  2. Changed1 schema field changed
    • addedInput schema / properties / plannedSource
      Added value: +{
      +  "description": "With budgetLines: where the planned budget comes from. settings = the campaigns' own budgets (Google Ads, Meta), read daily, history from the first reading; manual (default) = the amounts given; settings+manual = settings, but a month with an amount given uses it. On edit_widget it can be sent alone.",
      +  "enum": [
      +    "manual",
      +    "settings",
      +    "settings+manual"
      +  ],
      +  "type": "string"
      +}
  3. Changed4 schema fields changed
    • addedInput schema / properties / budgetCurrency
      Added value: +{
      +  "description": "With budgetLines: the ISO currency the budgets are in, e.g. EUR. Optional: without it the table labels the accounts' dominant currency on each render and says so.",
      +  "maxLength": 3,
      +  "minLength": 3,
      +  "type": "string"
      +}
    • addedInput schema / properties / budgetLines
      Added value: +{
      +  "description": "Budget vs actual table (All channels), no AI: the product lines in order. A campaign goes to the FIRST line it matches; the rest shows as Not assigned. A month with no budget reads '—', never 0. add_widget builds the table (instruction names it); edit_widget with widgetId replaces the table's COMPLETE list.",
      +  "items": {
      +    "additionalProperties": false,
      +    "properties": {
      +      "budgets": {
      +        "additionalProperties": {
      +          "type": [
      +            "number",
      +            "string"
      +          ]
      +        },
      +        "description": "Planned amount per month: {\"2026-10\": 1500}.",
      +        "type": "object"
      +      },
      +      "label": {
      +        "description": "Product line name, e.g. Krankenversicherung.",
      +        "maxLength": 60,
      +        "type": "string"
      +      },
      +      "match": {
      +        "description": "Campaign-name terms, case-insensitive, 'contains any'.",
      +        "items": {
      +          "maxLength": 100,
      +          "type": "string"
      +        },
      +        "maxItems": 20,
      +        "minItems": 1,
      +        "type": "array"
      +      },
      +      "monthly": {
      +        "description": "Default amount for a month without an entry.",
      +        "type": [
      +          "number",
      +          "string"
      +        ]
      +      }
      +    },
      +    "required": [
      +      "label",
      +      "match"
      +    ],
      +    "type": "object"
      +  },
      +  "maxItems": 20,
      +  "type": "array"
      +}
    • addedInput schema / properties / channels
      Added value: +{
      +  "description": "With budgetLines: restrict to these channels, e.g. [\"Google Ads\", \"Meta Ads\"] (default every connected paid channel).",
      +  "items": {
      +    "type": "string"
      +  },
      +  "maxItems": 8,
      +  "type": "array"
      +}
    • addedInput schema / properties / title
      Added value: +{
      +  "description": "With budgetLines only: the table's title.",
      +  "maxLength": 200,
      +  "type": "string"
      +}
  4. First observed

TDQS

A4.5/5.0
Behavior4/5

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

Annotations already declare it is a write (readOnlyHint=false) and non-destructive; the description adds substantial beyond-schema behavior: MCP write actions required, preview without confirm:true, previewToken valid 15 minutes and single-use for exactly the previewed arguments, blended rates recomputed from pooled totals and never averaged, and a reasoned failure when data is unconnected. Slightly short of 5 only because post-write return/lifecycle details are left implicit.

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?

Purpose and preview gating are front-loaded and each sentence carries information, but the block is long and mixes a niche GA4 'Channel × Month' example into the top-level flow, which slightly dilutes scanning. Dense but mostly earned.

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

Completeness4/5

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

For an 11-parameter tool with no output schema, it covers the write gating, the budgetLines non-AI path, placement rules, and failure reasons. It stops short of describing the returned preview structure beyond `aiCost`, so an agent still infers the response shape.

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 already 100%, so the baseline is 3, but the description adds real semantics: position defaults to end and yields to `position`, anchorId comes from get_report, granularity words vs a period are distinguished, and budgetLines assigns a campaign to the FIRST matching line with unassigned rest. These are rules, not restatements.

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?

Opens with a specific verb and resource ('Add a data widget (table, chart, KPI) to a report') and immediately names the distinguishing mechanism (plain-language instruction mapped to connected data). It also carves out siblings explicitly ('Free-text blocks use add_text_widget', 'edit_widget with widgetId replaces the table's COMPLETE list').

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

Usage Guidelines5/5

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

States when to use it (instruction-driven widget creation), when to use an alternative (add_text_widget for free text, budgetLines for a deterministic budget table, edit_widget to replace the budget list), and how the two-step preview/confirm flow gates the actual write. The routing is explicit rather than implied.

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.

Resources