Skip to main content
Glama

Costory: Your Finops MCP

update_dashboard

Destructive

Update an existing dashboard's name, description, shared dashboardContext, widgets, and/or tags. Use when the user asks to change an existing dashboard's name, filters, or widgets. The get_skill guide "dashboards" explains inheritance rules. Look up the dashboard id via search. Pass name and/or description to rename without recreating (empty description clears). Pass dashboardContext as a partial patch to edit the global filter (conditionsCel), period, groupBy, metricId, currency, or scopeId without recreating the dashboard — omit fields you want to keep; empty conditionsCel clears the filter. Pass operations to add/replace/remove widgets. Pass tags to replace the full tag list (existing IDs from list_tags and/or { name, color? } for new tags; color defaults to #6366F1; missing tags are created). Omit keeps stored tags; [] clears. At least one of dashboardContext, operations, tags, name, or description is required. Sharing is not an update_dashboard field — use get_object_permissions / set_object_permissions. Response includes inheritedContext so new chart widgets can omit fields matching the dashboard. Cost series may omit metricId, currency, and groupBy. Usage requires metricId and has no currency; omit groupBy to inherit. Budget groupBy is explicit (the budget VD bqName) and does not inherit dashboardContext.groupBy. Both inherit period and conditionsCel. Hide formula inputs with visible: false. Text widgets: { type: "text", title, textContent }. Do not repeat from/to or datePreset when they match the dashboard context. Set extendDashboardConditions: false on the widget to ignore the dashboard filter, or on one cost/usage series to opt out just that series. Optional grid fields on add: x/y/w/h (from get). Returns a URL — you MUST include it in your response. EXAMPLES: see skill dashboards Workflow B (widgets) and Workflow D (context / global filter). • "Tag the AWS dashboard as infrastructure" (after list_tags returned tag id "tag_abc") → { dashboardId: "clx9aws", tags: ["tag_abc"] }

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": {
      "dashboardId": "<dashboardId>",
      "context": "<context>"
    },
    "name": "update_dashboard"
  }
}

Input Schema

NameRequiredDescriptionDefault
nameNoDashboard title. Omit to keep.
slugNoOrganization slug. Omit to auto-detect from your account (fails if you belong to multiple orgs).
tagsNoComplete tag list to set on the dashboard (replaces current tags). Pass existing tag IDs from `list_tags`, and/or new tag objects `{ name, color? }` (created in the org if missing; color defaults to #6366F1). Pass [] to clear all tags. Use `get` to read current tags before removing one. Optional; omit to leave tags unchanged.
contextYesA few words on why you are calling this tool, for the server developer's analytics. Describe people and things by role, such as "a customer". Do not quote the user or include names, emails, or other personal details.
llm_modelNoThe model identifier you are running as, for example "claude-opus-4-8" or "gpt-5.2". Pass "unknown" if you are not certain. Recorded for the server developer's analytics.
operationsNoList of operations to apply atomically. Each op is "add" (append a new widget), "replace" (overwrite an existing widget in place), or "remove" (delete a widget). For add/replace, widgets inherit dashboard context by default; only pass per-widget overrides. Optional when `dashboardContext` or `tags` is provided. Example: [{"op":"add","widget":{"title":"Monthly cost","queries":[{"type":"cost","name":"a","chartType":"BAR"}],"aggBy":"Month"}}].
dashboardIdYesID of the DashboardV2 to mutate. Get it from `search` (V2 surface).
descriptionNoDashboard description. Omit to keep; empty string clears.
conversation_idNoThe conversation_id this server returned earlier in this conversation, unchanged, including after later user messages. Omit it if you have none. Recorded for the server developer's analytics.
dashboardContextNoPartial patch for dashboard-level shared context (global filter, period, groupBy, metricId, currency, scopeId). Omitted fields keep their current values. Set `conditionsCel` to update/clear the global filter (empty string clears it). When changing period mode, null the unused side (`datePreset` vs `startDate`/`endDate`). Can be used alone or together with `operations` or `tags`.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed4 schema fields changed
    • changedInput schema / properties / context / description
      Previous value: -"Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""New value: +"A few words on why you are calling this tool, for the server developer's analytics. Describe people and things by role, such as \"a customer\". Do not quote the user or include names, emails, or other personal details."
    • changedInput schema / properties / dashboardContext / properties / datePreset / description
      Previous value: -"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate when a preset matches the requested range."New value: +"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Use this when a preset matches the requested range; otherwise use startDate/endDate."
    • changedInput schema / properties / operations / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "add",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "discriminator": {
      -          "propertyName": "type"
      -        },
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      -            "properties": {
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "textContent": {
      -                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      -                "type": "string"
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "text",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "textContent",
      -              "title"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "aggBy": {
      -                "default": "Month",
      -                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -                "enum": [
      -                  "Hour",
      -                  "Day",
      -                  "Week",
      -                  "Month",
      -                  "Period"
      -                ],
      -                "type": "string"
      -              },
      -              "compare": {
      -                "additionalProperties": false,
      -                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -                "properties": {
      -                  "chartType": {
      -                    "default": "WATERFALL",
      -                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -                    "enum": [
      -                      "WATERFALL",
      -                      "TABLE",
      -                      "KPI_BREAKDOWN"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "enabled": {
      -                    "default": true,
      -                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -                    "type": "boolean"
      -                  },
      -                  "from": {
      -                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "to": {
      -                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "datePreset": {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "TRAILING_90_DAYS",
      -                      "TRAILING_30_DAYS",
      -                      "TRAILING_45_DAYS",
      -                      "TRAILING_7_DAYS",
      -                      "TRAILING_3_DAYS",
      -                      "TRAILING_1_DAYS",
      -                      "TRAILING_14_WEEKS",
      -                      "MTD",
      -                      "QTD",
      -                      "YTD",
      -                      "CURRENT_MONTH",
      -                      "CURRENT_QUARTER",
      -                      "CURRENT_YEAR",
      -                      "LAST_WEEK",
      -                      "LAST_MONTH",
      -                      "LAST_6_MONTHS",
      -                      "LAST_12_MONTHS",
      -                      "LAST_4_YEARS",
      -                      "LAST_3_MONTHS",
      -                      "LAST_INVOICE_MONTH"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      -              },
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "displayOptions": {
      -                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision, pivot {rows, columns}. get_skill dashboards.",
      -                "properties": {
      -                  "hideEmptyRows": {
      -                    "description": "Hide rows with abs displayed sum < 0.01",
      -                    "type": "boolean"
      -                  },
      -                  "pivot": {
      -                    "additionalProperties": false,
      -                    "description": "TABLE-only. Place groupBy, query, time on rows/columns. Outer first. get_skill dashboards.",
      -                    "properties": {
      -                      "columns": {
      -                        "description": "Non-empty. Outer first. Same axes as rows.",
      -                        "items": {
      -                          "enum": [
      -                            "groupBy",
      -                            "query",
      -                            "time"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "minItems": 1,
      -                        "type": "array"
      -                      },
      -                      "rows": {
      -                        "description": "Non-empty. Outer first. Each of groupBy, query, time at most once across rows+columns.",
      -                        "items": {
      -                          "enum": [
      -                            "groupBy",
      -                            "query",
      -                            "time"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "minItems": 1,
      -                        "type": "array"
      -                      }
      -                    },
      -                    "required": [
      -                      "rows",
      -                      "columns"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "precision": {
      -                    "description": "Fraction digits 0–6",
      -                    "maximum": 6,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "showTotal": {
      -                    "description": "Show Total column",
      -                    "type": "boolean"
      -                  },
      -                  "sort": {
      -                    "properties": {
      -                      "by": {
      -                        "description": "total | cost | groupBy | query letter (a)",
      -                        "minLength": 1,
      -                        "type": "string"
      -                      },
      -                      "direction": {
      -                        "default": "DESC",
      -                        "description": "ASC | DESC (default DESC)",
      -                        "enum": [
      -                          "ASC",
      -                          "DESC"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "by"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "topN": {
      -                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      -                    "maximum": 100,
      -                    "minimum": 1,
      -                    "type": "integer"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "extendDashboardConditions": {
      -                "default": true,
      -                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` into cost and usage series `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      -                "type": "boolean"
      -              },
      -              "from": {
      -                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "limit": {
      -                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      -                "maximum": 1000,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "queries": {
      -                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost may omit metricId, currency, and groupBy to inherit dashboardContext. Usage requires metricId (a usage id, not a cost column) and has no currency; omit groupBy to inherit. Budget groupBy is explicit (the budget virtual dimension bqName from get); it does not inherit dashboardContext.groupBy — omit for the total. Cost and usage inherit conditionsCel unless extendDashboardConditions is false. `visible: false` hides a series. Call get_skill skillId: \"dashboards\" for examples.",
      -                "items": {
      -                  "additionalProperties": {},
      -                  "propertyNames": {
      -                    "type": "string"
      -                  },
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "scopeId": {
      -                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      -                "type": [
      -                  "string",
      -                  "null"
      -                ]
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "to": {
      -                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "chart",
      -                "default": "chart",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "queries",
      -              "title"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "additionalProperties": {},
      -        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to overwrite (keeps its position).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "remove",
      -        "type": "string"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to delete.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "add",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "discriminator": {
      +          "propertyName": "type"
      +        },
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      +            "properties": {
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "textContent": {
      +                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      +                "type": "string"
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "text",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "textContent",
      +              "title"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "aggBy": {
      +                "default": "Month",
      +                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +                "enum": [
      +                  "Hour",
      +                  "Day",
      +                  "Week",
      +                  "Month",
      +                  "Period"
      +                ],
      +                "type": "string"
      +              },
      +              "compare": {
      +                "additionalProperties": false,
      +                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +                "properties": {
      +                  "chartType": {
      +                    "default": "WATERFALL",
      +                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +                    "enum": [
      +                      "WATERFALL",
      +                      "TABLE",
      +                      "KPI_BREAKDOWN"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "enabled": {
      +                    "default": true,
      +                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +                    "type": "boolean"
      +                  },
      +                  "from": {
      +                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "to": {
      +                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "datePreset": {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "TRAILING_90_DAYS",
      +                      "TRAILING_30_DAYS",
      +                      "TRAILING_45_DAYS",
      +                      "TRAILING_7_DAYS",
      +                      "TRAILING_3_DAYS",
      +                      "TRAILING_1_DAYS",
      +                      "TRAILING_14_WEEKS",
      +                      "MTD",
      +                      "QTD",
      +                      "YTD",
      +                      "CURRENT_MONTH",
      +                      "CURRENT_QUARTER",
      +                      "CURRENT_YEAR",
      +                      "LAST_WEEK",
      +                      "LAST_MONTH",
      +                      "LAST_6_MONTHS",
      +                      "LAST_12_MONTHS",
      +                      "LAST_4_YEARS",
      +                      "LAST_3_MONTHS",
      +                      "LAST_INVOICE_MONTH"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      +              },
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "displayOptions": {
      +                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision, pivot {rows, columns}. get_skill dashboards.",
      +                "properties": {
      +                  "hideEmptyRows": {
      +                    "description": "Hide rows with abs displayed sum < 0.01",
      +                    "type": "boolean"
      +                  },
      +                  "pivot": {
      +                    "additionalProperties": false,
      +                    "description": "TABLE-only. Place groupBy, query, time on rows/columns. Outer first. get_skill dashboards.",
      +                    "properties": {
      +                      "columns": {
      +                        "description": "Non-empty. Outer first. Same axes as rows.",
      +                        "items": {
      +                          "enum": [
      +                            "groupBy",
      +                            "query",
      +                            "time"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      },
      +                      "rows": {
      +                        "description": "Non-empty. Outer first. Each of groupBy, query, time at most once across rows+columns.",
      +                        "items": {
      +                          "enum": [
      +                            "groupBy",
      +                            "query",
      +                            "time"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      }
      +                    },
      +                    "required": [
      +                      "rows",
      +                      "columns"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "precision": {
      +                    "description": "Fraction digits 0–6",
      +                    "maximum": 6,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "showTotal": {
      +                    "description": "Show Total column",
      +                    "type": "boolean"
      +                  },
      +                  "sort": {
      +                    "properties": {
      +                      "by": {
      +                        "description": "total | cost | groupBy | query letter (a)",
      +                        "minLength": 1,
      +                        "type": "string"
      +                      },
      +                      "direction": {
      +                        "default": "DESC",
      +                        "description": "ASC | DESC (default DESC)",
      +                        "enum": [
      +                          "ASC",
      +                          "DESC"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "by"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "topN": {
      +                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      +                    "maximum": 100,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "extendDashboardConditions": {
      +                "default": true,
      +                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` into cost and usage series `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      +                "type": "boolean"
      +              },
      +              "from": {
      +                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "limit": {
      +                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      +                "maximum": 1000,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "queries": {
      +                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (use short ids like a/b/c); put human labels in `alias`. Cost may omit metricId, currency, and groupBy to inherit dashboardContext. Usage requires metricId (a usage id, not a cost column) and has no currency; omit groupBy to inherit. Budget groupBy is explicit (the budget virtual dimension bqName from get); it does not inherit dashboardContext.groupBy — omit for the total. Cost and usage inherit conditionsCel unless extendDashboardConditions is false. `visible: false` hides a series. Call get_skill skillId: \"dashboards\" for examples.",
      +                "items": {
      +                  "additionalProperties": {},
      +                  "propertyNames": {
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "scopeId": {
      +                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "to": {
      +                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "chart",
      +                "default": "chart",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "queries",
      +              "title"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "additionalProperties": {},
      +        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to overwrite (keeps its position).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "remove",
      +        "type": "string"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to delete.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / required
      Previous value: -[
      -  "dashboardId",
      -  "context",
      -  "llm_model"
      -]New value: +[
      +  "dashboardId",
      +  "context"
      +]
  2. Changed6 schema fields changed
    • changedInput schema / properties / context / description
      Previous value: -"Deprecated alias for `dashboardContext`; supported temporarily for backward compatibility. Do not send both fields."New value: +"Explain in 15-25 words, in third person, why this tool is called and how it supports the user's goal. For analytics only. You MUST describe only the abstract purpose of the tool call. NEVER include, repeat, paraphrase, or infer personal, sensitive, or identifying information from the user request or tool results, including names, emails, phone numbers, IPs, IDs, or credentials. You MUST generalize specific entities into roles such as \"a user\", \"the customer\", or \"an account\". Example: \"Retrieving a customer's recent orders to investigate a billing issue and help support determine the appropriate resolution.\""
    • removedInput schema / properties / context / properties
      Removed value: -{
      -  "conditionsCel": {
      -    "description": "Dashboard-wide CEL filter. AND-merged into every cost and usage widget that does not set `extendDashboardConditions: false` (default is inherit). Omit or empty string for no dashboard-level filter.",
      -    "type": "string"
      -  },
      -  "currency": {
      -    "anyOf": [
      -      {
      -        "enum": [
      -          "USD",
      -          "EUR",
      -          "GBP",
      -          "CNY",
      -          "KRW"
      -        ],
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ]
      -  },
      -  "datePreset": {
      -    "anyOf": [
      -      {
      -        "enum": [
      -          "TRAILING_90_DAYS",
      -          "TRAILING_30_DAYS",
      -          "TRAILING_45_DAYS",
      -          "TRAILING_7_DAYS",
      -          "TRAILING_3_DAYS",
      -          "TRAILING_1_DAYS",
      -          "TRAILING_14_WEEKS",
      -          "MTD",
      -          "QTD",
      -          "YTD",
      -          "CURRENT_MONTH",
      -          "CURRENT_QUARTER",
      -          "CURRENT_YEAR",
      -          "LAST_WEEK",
      -          "LAST_MONTH",
      -          "LAST_6_MONTHS",
      -          "LAST_12_MONTHS",
      -          "LAST_4_YEARS",
      -          "LAST_3_MONTHS",
      -          "LAST_INVOICE_MONTH"
      -        ],
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate when a preset matches the requested range."
      -  },
      -  "endDate": {
      -    "anyOf": [
      -      {
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ]
      -  },
      -  "groupBy": {
      -    "description": "Default group-by axis inherited by widget cost queries that omit `groupBy`. When multiple widgets share the same split, put it here instead of repeating it on each widget.",
      -    "type": [
      -      "string",
      -      "null"
      -    ]
      -  },
      -  "metricId": {
      -    "description": "Default metric inherited by widget cost queries that omit `metricId`.",
      -    "type": [
      -      "string",
      -      "null"
      -    ]
      -  },
      -  "scopeId": {
      -    "type": [
      -      "string",
      -      "null"
      -    ]
      -  },
      -  "startDate": {
      -    "anyOf": [
      -      {
      -        "format": "date",
      -        "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Used only when `datePreset` is null; ISO date (YYYY-MM-DD)."
      -  }
      -}
    • changedInput schema / properties / context / type
      Previous value: -"object"New value: +"string"
    • addedInput schema / properties / conversation_id
      Added value: +{
      +  "description": "The conversation_id this server returned earlier in this conversation, unchanged, including after later user messages. Omit it if you have none. Recorded for the server developer's analytics.",
      +  "type": "string"
      +}
    • addedInput schema / properties / llm_model
      Added value: +{
      +  "description": "The model identifier you are running as, for example \"claude-opus-4-8\" or \"gpt-5.2\". Pass \"unknown\" if you are not certain. Recorded for the server developer's analytics.",
      +  "type": "string"
      +}
    • changedInput schema / required
      Previous value: -[
      -  "dashboardId"
      -]New value: +[
      +  "dashboardId",
      +  "context",
      +  "llm_model"
      +]
  3. Changed13 schema fields changed
    • removedInput schema / properties / context / properties / groupBy / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / context / properties / groupBy / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / context / properties / metricId / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / context / properties / metricId / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / context / properties / scopeId / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / context / properties / scopeId / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / dashboardContext / properties / groupBy / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / dashboardContext / properties / groupBy / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / dashboardContext / properties / metricId / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / dashboardContext / properties / metricId / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / properties / dashboardContext / properties / scopeId / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / properties / dashboardContext / properties / scopeId / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • changedInput schema / properties / operations / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "add",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "discriminator": {
      -          "propertyName": "type"
      -        },
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      -            "properties": {
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "textContent": {
      -                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      -                "type": "string"
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "text",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "textContent",
      -              "title"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "aggBy": {
      -                "default": "Month",
      -                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -                "enum": [
      -                  "Hour",
      -                  "Day",
      -                  "Week",
      -                  "Month",
      -                  "Period"
      -                ],
      -                "type": "string"
      -              },
      -              "compare": {
      -                "additionalProperties": false,
      -                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -                "properties": {
      -                  "chartType": {
      -                    "default": "WATERFALL",
      -                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -                    "enum": [
      -                      "WATERFALL",
      -                      "TABLE",
      -                      "KPI_BREAKDOWN"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "enabled": {
      -                    "default": true,
      -                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -                    "type": "boolean"
      -                  },
      -                  "from": {
      -                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "to": {
      -                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "datePreset": {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "TRAILING_90_DAYS",
      -                      "TRAILING_30_DAYS",
      -                      "TRAILING_45_DAYS",
      -                      "TRAILING_7_DAYS",
      -                      "TRAILING_3_DAYS",
      -                      "TRAILING_1_DAYS",
      -                      "TRAILING_14_WEEKS",
      -                      "MTD",
      -                      "QTD",
      -                      "YTD",
      -                      "CURRENT_MONTH",
      -                      "CURRENT_QUARTER",
      -                      "CURRENT_YEAR",
      -                      "LAST_WEEK",
      -                      "LAST_MONTH",
      -                      "LAST_6_MONTHS",
      -                      "LAST_12_MONTHS",
      -                      "LAST_4_YEARS",
      -                      "LAST_3_MONTHS",
      -                      "LAST_INVOICE_MONTH"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      -              },
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "displayOptions": {
      -                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision, pivot {rows, columns}. get_skill dashboards.",
      -                "properties": {
      -                  "hideEmptyRows": {
      -                    "description": "Hide rows with abs displayed sum < 0.01",
      -                    "type": "boolean"
      -                  },
      -                  "pivot": {
      -                    "additionalProperties": false,
      -                    "description": "TABLE-only. Place groupBy, query, time on rows/columns. Outer first. get_skill dashboards.",
      -                    "properties": {
      -                      "columns": {
      -                        "description": "Non-empty. Outer first. Same axes as rows.",
      -                        "items": {
      -                          "enum": [
      -                            "groupBy",
      -                            "query",
      -                            "time"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "minItems": 1,
      -                        "type": "array"
      -                      },
      -                      "rows": {
      -                        "description": "Non-empty. Outer first. Each of groupBy, query, time at most once across rows+columns.",
      -                        "items": {
      -                          "enum": [
      -                            "groupBy",
      -                            "query",
      -                            "time"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "minItems": 1,
      -                        "type": "array"
      -                      }
      -                    },
      -                    "required": [
      -                      "rows",
      -                      "columns"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "precision": {
      -                    "description": "Fraction digits 0–6",
      -                    "maximum": 6,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "showTotal": {
      -                    "description": "Show Total column",
      -                    "type": "boolean"
      -                  },
      -                  "sort": {
      -                    "properties": {
      -                      "by": {
      -                        "description": "total | cost | groupBy | query letter (a)",
      -                        "minLength": 1,
      -                        "type": "string"
      -                      },
      -                      "direction": {
      -                        "default": "DESC",
      -                        "description": "ASC | DESC (default DESC)",
      -                        "enum": [
      -                          "ASC",
      -                          "DESC"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "by"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "topN": {
      -                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      -                    "maximum": 100,
      -                    "minimum": 1,
      -                    "type": "integer"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "extendDashboardConditions": {
      -                "default": true,
      -                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` into cost and usage series `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      -                "type": "boolean"
      -              },
      -              "from": {
      -                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "limit": {
      -                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      -                "maximum": 1000,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "queries": {
      -                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost may omit metricId, currency, and groupBy to inherit dashboardContext. Usage requires metricId (a usage id, not a cost column) and has no currency; omit groupBy to inherit. Budget groupBy is explicit (the budget virtual dimension bqName from get); it does not inherit dashboardContext.groupBy — omit for the total. Cost and usage inherit conditionsCel unless extendDashboardConditions is false. `visible: false` hides a series. Call get_skill skillId: \"dashboards\" for examples.",
      -                "items": {
      -                  "additionalProperties": {},
      -                  "propertyNames": {
      -                    "type": "string"
      -                  },
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "scopeId": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "to": {
      -                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "chart",
      -                "default": "chart",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "title"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "additionalProperties": {},
      -        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to overwrite (keeps its position).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "remove",
      -        "type": "string"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to delete.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "add",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "discriminator": {
      +          "propertyName": "type"
      +        },
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      +            "properties": {
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "textContent": {
      +                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      +                "type": "string"
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "text",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "textContent",
      +              "title"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "aggBy": {
      +                "default": "Month",
      +                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +                "enum": [
      +                  "Hour",
      +                  "Day",
      +                  "Week",
      +                  "Month",
      +                  "Period"
      +                ],
      +                "type": "string"
      +              },
      +              "compare": {
      +                "additionalProperties": false,
      +                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +                "properties": {
      +                  "chartType": {
      +                    "default": "WATERFALL",
      +                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +                    "enum": [
      +                      "WATERFALL",
      +                      "TABLE",
      +                      "KPI_BREAKDOWN"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "enabled": {
      +                    "default": true,
      +                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +                    "type": "boolean"
      +                  },
      +                  "from": {
      +                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "to": {
      +                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "datePreset": {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "TRAILING_90_DAYS",
      +                      "TRAILING_30_DAYS",
      +                      "TRAILING_45_DAYS",
      +                      "TRAILING_7_DAYS",
      +                      "TRAILING_3_DAYS",
      +                      "TRAILING_1_DAYS",
      +                      "TRAILING_14_WEEKS",
      +                      "MTD",
      +                      "QTD",
      +                      "YTD",
      +                      "CURRENT_MONTH",
      +                      "CURRENT_QUARTER",
      +                      "CURRENT_YEAR",
      +                      "LAST_WEEK",
      +                      "LAST_MONTH",
      +                      "LAST_6_MONTHS",
      +                      "LAST_12_MONTHS",
      +                      "LAST_4_YEARS",
      +                      "LAST_3_MONTHS",
      +                      "LAST_INVOICE_MONTH"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      +              },
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "displayOptions": {
      +                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision, pivot {rows, columns}. get_skill dashboards.",
      +                "properties": {
      +                  "hideEmptyRows": {
      +                    "description": "Hide rows with abs displayed sum < 0.01",
      +                    "type": "boolean"
      +                  },
      +                  "pivot": {
      +                    "additionalProperties": false,
      +                    "description": "TABLE-only. Place groupBy, query, time on rows/columns. Outer first. get_skill dashboards.",
      +                    "properties": {
      +                      "columns": {
      +                        "description": "Non-empty. Outer first. Same axes as rows.",
      +                        "items": {
      +                          "enum": [
      +                            "groupBy",
      +                            "query",
      +                            "time"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      },
      +                      "rows": {
      +                        "description": "Non-empty. Outer first. Each of groupBy, query, time at most once across rows+columns.",
      +                        "items": {
      +                          "enum": [
      +                            "groupBy",
      +                            "query",
      +                            "time"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      }
      +                    },
      +                    "required": [
      +                      "rows",
      +                      "columns"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "precision": {
      +                    "description": "Fraction digits 0–6",
      +                    "maximum": 6,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "showTotal": {
      +                    "description": "Show Total column",
      +                    "type": "boolean"
      +                  },
      +                  "sort": {
      +                    "properties": {
      +                      "by": {
      +                        "description": "total | cost | groupBy | query letter (a)",
      +                        "minLength": 1,
      +                        "type": "string"
      +                      },
      +                      "direction": {
      +                        "default": "DESC",
      +                        "description": "ASC | DESC (default DESC)",
      +                        "enum": [
      +                          "ASC",
      +                          "DESC"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "by"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "topN": {
      +                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      +                    "maximum": 100,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "extendDashboardConditions": {
      +                "default": true,
      +                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` into cost and usage series `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      +                "type": "boolean"
      +              },
      +              "from": {
      +                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "limit": {
      +                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      +                "maximum": 1000,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "queries": {
      +                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost may omit metricId, currency, and groupBy to inherit dashboardContext. Usage requires metricId (a usage id, not a cost column) and has no currency; omit groupBy to inherit. Budget groupBy is explicit (the budget virtual dimension bqName from get); it does not inherit dashboardContext.groupBy — omit for the total. Cost and usage inherit conditionsCel unless extendDashboardConditions is false. `visible: false` hides a series. Call get_skill skillId: \"dashboards\" for examples.",
      +                "items": {
      +                  "additionalProperties": {},
      +                  "propertyNames": {
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "scopeId": {
      +                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +                "type": [
      +                  "string",
      +                  "null"
      +                ]
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "to": {
      +                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "chart",
      +                "default": "chart",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "queries",
      +              "title"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "additionalProperties": {},
      +        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to overwrite (keeps its position).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "remove",
      +        "type": "string"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to delete.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId"
      +    ],
      +    "type": "object"
      +  }
      +]
  4. Changed1 schema field changed
    • changedInput schema / properties / operations / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "add",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "discriminator": {
      -          "propertyName": "type"
      -        },
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      -            "properties": {
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "textContent": {
      -                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      -                "type": "string"
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "text",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "textContent",
      -              "title"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "aggBy": {
      -                "default": "Month",
      -                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -                "enum": [
      -                  "Hour",
      -                  "Day",
      -                  "Week",
      -                  "Month",
      -                  "Period"
      -                ],
      -                "type": "string"
      -              },
      -              "compare": {
      -                "additionalProperties": false,
      -                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -                "properties": {
      -                  "chartType": {
      -                    "default": "WATERFALL",
      -                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -                    "enum": [
      -                      "WATERFALL",
      -                      "TABLE",
      -                      "KPI_BREAKDOWN"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "enabled": {
      -                    "default": true,
      -                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -                    "type": "boolean"
      -                  },
      -                  "from": {
      -                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "to": {
      -                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "datePreset": {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "TRAILING_90_DAYS",
      -                      "TRAILING_30_DAYS",
      -                      "TRAILING_45_DAYS",
      -                      "TRAILING_7_DAYS",
      -                      "TRAILING_3_DAYS",
      -                      "TRAILING_1_DAYS",
      -                      "TRAILING_14_WEEKS",
      -                      "MTD",
      -                      "QTD",
      -                      "YTD",
      -                      "CURRENT_MONTH",
      -                      "CURRENT_QUARTER",
      -                      "CURRENT_YEAR",
      -                      "LAST_WEEK",
      -                      "LAST_MONTH",
      -                      "LAST_6_MONTHS",
      -                      "LAST_12_MONTHS",
      -                      "LAST_4_YEARS",
      -                      "LAST_3_MONTHS",
      -                      "LAST_INVOICE_MONTH"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      -              },
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "displayOptions": {
      -                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision, pivot {rows, columns}. get_skill dashboards.",
      -                "properties": {
      -                  "hideEmptyRows": {
      -                    "description": "Hide rows with abs displayed sum < 0.01",
      -                    "type": "boolean"
      -                  },
      -                  "pivot": {
      -                    "additionalProperties": false,
      -                    "description": "TABLE-only. Place groupBy, query, time on rows/columns. Outer first. get_skill dashboards.",
      -                    "properties": {
      -                      "columns": {
      -                        "description": "Non-empty. Outer first. Same axes as rows.",
      -                        "items": {
      -                          "enum": [
      -                            "groupBy",
      -                            "query",
      -                            "time"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "minItems": 1,
      -                        "type": "array"
      -                      },
      -                      "rows": {
      -                        "description": "Non-empty. Outer first. Each of groupBy, query, time at most once across rows+columns.",
      -                        "items": {
      -                          "enum": [
      -                            "groupBy",
      -                            "query",
      -                            "time"
      -                          ],
      -                          "type": "string"
      -                        },
      -                        "minItems": 1,
      -                        "type": "array"
      -                      }
      -                    },
      -                    "required": [
      -                      "rows",
      -                      "columns"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "precision": {
      -                    "description": "Fraction digits 0–6",
      -                    "maximum": 6,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "showTotal": {
      -                    "description": "Show Total column",
      -                    "type": "boolean"
      -                  },
      -                  "sort": {
      -                    "properties": {
      -                      "by": {
      -                        "description": "total | cost | groupBy | query letter (a)",
      -                        "minLength": 1,
      -                        "type": "string"
      -                      },
      -                      "direction": {
      -                        "default": "DESC",
      -                        "description": "ASC | DESC (default DESC)",
      -                        "enum": [
      -                          "ASC",
      -                          "DESC"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "by"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "topN": {
      -                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      -                    "maximum": 100,
      -                    "minimum": 1,
      -                    "type": "integer"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "extendDashboardConditions": {
      -                "default": true,
      -                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` into cost and usage series `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      -                "type": "boolean"
      -              },
      -              "from": {
      -                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "limit": {
      -                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      -                "maximum": 1000,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "queries": {
      -                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost may omit metricId, currency, and groupBy to inherit dashboardContext. Usage requires metricId (a usage id, not a cost column) and has no currency; omit groupBy to inherit. Cost and usage inherit conditionsCel unless extendDashboardConditions is false. `visible: false` hides a series. Call get_skill skillId: \"dashboards\" for examples.",
      -                "items": {
      -                  "additionalProperties": {},
      -                  "propertyNames": {
      -                    "type": "string"
      -                  },
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "scopeId": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "to": {
      -                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "chart",
      -                "default": "chart",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "title"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "additionalProperties": {},
      -        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to overwrite (keeps its position).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "remove",
      -        "type": "string"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to delete.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "add",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "discriminator": {
      +          "propertyName": "type"
      +        },
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      +            "properties": {
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "textContent": {
      +                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      +                "type": "string"
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "text",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "textContent",
      +              "title"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "aggBy": {
      +                "default": "Month",
      +                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +                "enum": [
      +                  "Hour",
      +                  "Day",
      +                  "Week",
      +                  "Month",
      +                  "Period"
      +                ],
      +                "type": "string"
      +              },
      +              "compare": {
      +                "additionalProperties": false,
      +                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +                "properties": {
      +                  "chartType": {
      +                    "default": "WATERFALL",
      +                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +                    "enum": [
      +                      "WATERFALL",
      +                      "TABLE",
      +                      "KPI_BREAKDOWN"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "enabled": {
      +                    "default": true,
      +                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +                    "type": "boolean"
      +                  },
      +                  "from": {
      +                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "to": {
      +                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "datePreset": {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "TRAILING_90_DAYS",
      +                      "TRAILING_30_DAYS",
      +                      "TRAILING_45_DAYS",
      +                      "TRAILING_7_DAYS",
      +                      "TRAILING_3_DAYS",
      +                      "TRAILING_1_DAYS",
      +                      "TRAILING_14_WEEKS",
      +                      "MTD",
      +                      "QTD",
      +                      "YTD",
      +                      "CURRENT_MONTH",
      +                      "CURRENT_QUARTER",
      +                      "CURRENT_YEAR",
      +                      "LAST_WEEK",
      +                      "LAST_MONTH",
      +                      "LAST_6_MONTHS",
      +                      "LAST_12_MONTHS",
      +                      "LAST_4_YEARS",
      +                      "LAST_3_MONTHS",
      +                      "LAST_INVOICE_MONTH"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      +              },
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "displayOptions": {
      +                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision, pivot {rows, columns}. get_skill dashboards.",
      +                "properties": {
      +                  "hideEmptyRows": {
      +                    "description": "Hide rows with abs displayed sum < 0.01",
      +                    "type": "boolean"
      +                  },
      +                  "pivot": {
      +                    "additionalProperties": false,
      +                    "description": "TABLE-only. Place groupBy, query, time on rows/columns. Outer first. get_skill dashboards.",
      +                    "properties": {
      +                      "columns": {
      +                        "description": "Non-empty. Outer first. Same axes as rows.",
      +                        "items": {
      +                          "enum": [
      +                            "groupBy",
      +                            "query",
      +                            "time"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      },
      +                      "rows": {
      +                        "description": "Non-empty. Outer first. Each of groupBy, query, time at most once across rows+columns.",
      +                        "items": {
      +                          "enum": [
      +                            "groupBy",
      +                            "query",
      +                            "time"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      }
      +                    },
      +                    "required": [
      +                      "rows",
      +                      "columns"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "precision": {
      +                    "description": "Fraction digits 0–6",
      +                    "maximum": 6,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "showTotal": {
      +                    "description": "Show Total column",
      +                    "type": "boolean"
      +                  },
      +                  "sort": {
      +                    "properties": {
      +                      "by": {
      +                        "description": "total | cost | groupBy | query letter (a)",
      +                        "minLength": 1,
      +                        "type": "string"
      +                      },
      +                      "direction": {
      +                        "default": "DESC",
      +                        "description": "ASC | DESC (default DESC)",
      +                        "enum": [
      +                          "ASC",
      +                          "DESC"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "by"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "topN": {
      +                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      +                    "maximum": 100,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "extendDashboardConditions": {
      +                "default": true,
      +                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` into cost and usage series `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      +                "type": "boolean"
      +              },
      +              "from": {
      +                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "limit": {
      +                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      +                "maximum": 1000,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "queries": {
      +                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost may omit metricId, currency, and groupBy to inherit dashboardContext. Usage requires metricId (a usage id, not a cost column) and has no currency; omit groupBy to inherit. Budget groupBy is explicit (the budget virtual dimension bqName from get); it does not inherit dashboardContext.groupBy — omit for the total. Cost and usage inherit conditionsCel unless extendDashboardConditions is false. `visible: false` hides a series. Call get_skill skillId: \"dashboards\" for examples.",
      +                "items": {
      +                  "additionalProperties": {},
      +                  "propertyNames": {
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "scopeId": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "to": {
      +                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "chart",
      +                "default": "chart",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "title"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "additionalProperties": {},
      +        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to overwrite (keeps its position).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "remove",
      +        "type": "string"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to delete.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId"
      +    ],
      +    "type": "object"
      +  }
      +]
  5. Changed5 schema fields changed
    • changedInput schema / properties / context / properties / conditionsCel / description
      Previous value: -"Dashboard-wide CEL filter. AND-merged into every cost widget that does not set `extendDashboardConditions: false` (default is inherit). Omit or empty string for no dashboard-level filter."New value: +"Dashboard-wide CEL filter. AND-merged into every cost and usage widget that does not set `extendDashboardConditions: false` (default is inherit). Omit or empty string for no dashboard-level filter."
    • changedInput schema / properties / dashboardContext / properties / conditionsCel / description
      Previous value: -"Dashboard-wide CEL filter. AND-merged into every cost widget that does not set `extendDashboardConditions: false` (default is inherit). Omit or empty string for no dashboard-level filter."New value: +"Dashboard-wide CEL filter. AND-merged into every cost and usage widget that does not set `extendDashboardConditions: false` (default is inherit). Omit or empty string for no dashboard-level filter."
    • addedInput schema / properties / description
      Added value: +{
      +  "description": "Dashboard description. Omit to keep; empty string clears.",
      +  "type": "string"
      +}
    • addedInput schema / properties / name
      Added value: +{
      +  "description": "Dashboard title. Omit to keep.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • changedInput schema / properties / operations / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "add",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "discriminator": {
      -          "propertyName": "type"
      -        },
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      -            "properties": {
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "textContent": {
      -                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      -                "type": "string"
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "text",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "textContent",
      -              "title"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "aggBy": {
      -                "default": "Month",
      -                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -                "enum": [
      -                  "Hour",
      -                  "Day",
      -                  "Week",
      -                  "Month",
      -                  "Period"
      -                ],
      -                "type": "string"
      -              },
      -              "compare": {
      -                "additionalProperties": false,
      -                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -                "properties": {
      -                  "chartType": {
      -                    "default": "WATERFALL",
      -                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -                    "enum": [
      -                      "WATERFALL",
      -                      "TABLE",
      -                      "KPI_BREAKDOWN"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "enabled": {
      -                    "default": true,
      -                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -                    "type": "boolean"
      -                  },
      -                  "from": {
      -                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "to": {
      -                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "datePreset": {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "TRAILING_90_DAYS",
      -                      "TRAILING_30_DAYS",
      -                      "TRAILING_45_DAYS",
      -                      "TRAILING_7_DAYS",
      -                      "TRAILING_3_DAYS",
      -                      "TRAILING_1_DAYS",
      -                      "TRAILING_14_WEEKS",
      -                      "MTD",
      -                      "QTD",
      -                      "YTD",
      -                      "CURRENT_MONTH",
      -                      "CURRENT_QUARTER",
      -                      "CURRENT_YEAR",
      -                      "LAST_WEEK",
      -                      "LAST_MONTH",
      -                      "LAST_6_MONTHS",
      -                      "LAST_12_MONTHS",
      -                      "LAST_4_YEARS",
      -                      "LAST_3_MONTHS",
      -                      "LAST_INVOICE_MONTH"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      -              },
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "displayOptions": {
      -                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision. get_skill dashboards.",
      -                "properties": {
      -                  "hideEmptyRows": {
      -                    "description": "Hide rows with abs displayed sum < 0.01",
      -                    "type": "boolean"
      -                  },
      -                  "precision": {
      -                    "description": "Fraction digits 0–6",
      -                    "maximum": 6,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "showTotal": {
      -                    "description": "Show Total column",
      -                    "type": "boolean"
      -                  },
      -                  "sort": {
      -                    "properties": {
      -                      "by": {
      -                        "description": "total | cost | groupBy | query letter (a)",
      -                        "minLength": 1,
      -                        "type": "string"
      -                      },
      -                      "direction": {
      -                        "default": "DESC",
      -                        "description": "ASC | DESC (default DESC)",
      -                        "enum": [
      -                          "ASC",
      -                          "DESC"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "by"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "topN": {
      -                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      -                    "maximum": 100,
      -                    "minimum": 1,
      -                    "type": "integer"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "extendDashboardConditions": {
      -                "default": true,
      -                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      -                "type": "boolean"
      -              },
      -              "from": {
      -                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "limit": {
      -                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE widget, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      -                "maximum": 1000,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "queries": {
      -                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      -                "items": {
      -                  "additionalProperties": {},
      -                  "propertyNames": {
      -                    "type": "string"
      -                  },
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "scopeId": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "to": {
      -                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "chart",
      -                "default": "chart",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "title"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "additionalProperties": {},
      -        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to overwrite (keeps its position).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "remove",
      -        "type": "string"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to delete.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "add",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "discriminator": {
      +          "propertyName": "type"
      +        },
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      +            "properties": {
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "textContent": {
      +                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      +                "type": "string"
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "text",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "textContent",
      +              "title"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "aggBy": {
      +                "default": "Month",
      +                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +                "enum": [
      +                  "Hour",
      +                  "Day",
      +                  "Week",
      +                  "Month",
      +                  "Period"
      +                ],
      +                "type": "string"
      +              },
      +              "compare": {
      +                "additionalProperties": false,
      +                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +                "properties": {
      +                  "chartType": {
      +                    "default": "WATERFALL",
      +                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +                    "enum": [
      +                      "WATERFALL",
      +                      "TABLE",
      +                      "KPI_BREAKDOWN"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "enabled": {
      +                    "default": true,
      +                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +                    "type": "boolean"
      +                  },
      +                  "from": {
      +                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "to": {
      +                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "datePreset": {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "TRAILING_90_DAYS",
      +                      "TRAILING_30_DAYS",
      +                      "TRAILING_45_DAYS",
      +                      "TRAILING_7_DAYS",
      +                      "TRAILING_3_DAYS",
      +                      "TRAILING_1_DAYS",
      +                      "TRAILING_14_WEEKS",
      +                      "MTD",
      +                      "QTD",
      +                      "YTD",
      +                      "CURRENT_MONTH",
      +                      "CURRENT_QUARTER",
      +                      "CURRENT_YEAR",
      +                      "LAST_WEEK",
      +                      "LAST_MONTH",
      +                      "LAST_6_MONTHS",
      +                      "LAST_12_MONTHS",
      +                      "LAST_4_YEARS",
      +                      "LAST_3_MONTHS",
      +                      "LAST_INVOICE_MONTH"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      +              },
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "displayOptions": {
      +                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision, pivot {rows, columns}. get_skill dashboards.",
      +                "properties": {
      +                  "hideEmptyRows": {
      +                    "description": "Hide rows with abs displayed sum < 0.01",
      +                    "type": "boolean"
      +                  },
      +                  "pivot": {
      +                    "additionalProperties": false,
      +                    "description": "TABLE-only. Place groupBy, query, time on rows/columns. Outer first. get_skill dashboards.",
      +                    "properties": {
      +                      "columns": {
      +                        "description": "Non-empty. Outer first. Same axes as rows.",
      +                        "items": {
      +                          "enum": [
      +                            "groupBy",
      +                            "query",
      +                            "time"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      },
      +                      "rows": {
      +                        "description": "Non-empty. Outer first. Each of groupBy, query, time at most once across rows+columns.",
      +                        "items": {
      +                          "enum": [
      +                            "groupBy",
      +                            "query",
      +                            "time"
      +                          ],
      +                          "type": "string"
      +                        },
      +                        "minItems": 1,
      +                        "type": "array"
      +                      }
      +                    },
      +                    "required": [
      +                      "rows",
      +                      "columns"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "precision": {
      +                    "description": "Fraction digits 0–6",
      +                    "maximum": 6,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "showTotal": {
      +                    "description": "Show Total column",
      +                    "type": "boolean"
      +                  },
      +                  "sort": {
      +                    "properties": {
      +                      "by": {
      +                        "description": "total | cost | groupBy | query letter (a)",
      +                        "minLength": 1,
      +                        "type": "string"
      +                      },
      +                      "direction": {
      +                        "default": "DESC",
      +                        "description": "ASC | DESC (default DESC)",
      +                        "enum": [
      +                          "ASC",
      +                          "DESC"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "by"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "topN": {
      +                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      +                    "maximum": 100,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "extendDashboardConditions": {
      +                "default": true,
      +                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` into cost and usage series `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      +                "type": "boolean"
      +              },
      +              "from": {
      +                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "limit": {
      +                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      +                "maximum": 1000,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "queries": {
      +                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. Cost may omit metricId, currency, and groupBy to inherit dashboardContext. Usage requires metricId (a usage id, not a cost column) and has no currency; omit groupBy to inherit. Cost and usage inherit conditionsCel unless extendDashboardConditions is false. `visible: false` hides a series. Call get_skill skillId: \"dashboards\" for examples.",
      +                "items": {
      +                  "additionalProperties": {},
      +                  "propertyNames": {
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "scopeId": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "to": {
      +                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "chart",
      +                "default": "chart",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "title"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "additionalProperties": {},
      +        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to overwrite (keeps its position).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "remove",
      +        "type": "string"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to delete.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId"
      +    ],
      +    "type": "object"
      +  }
      +]
  6. Changed2 schema fields changed
    • changedInput schema / properties / context / properties / datePreset / description
      Previous value: -"Default date preset inherited when a widget omits date fields. Prefer this over startDate/endDate whenever an available preset matches the requested range."New value: +"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate when a preset matches the requested range."
    • changedInput schema / properties / dashboardContext / properties / datePreset / description
      Previous value: -"Default date preset inherited when a widget omits date fields. Prefer this over startDate/endDate whenever an available preset matches the requested range."New value: +"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate when a preset matches the requested range."
  7. Changed2 schema fields changed
    • changedInput schema / properties / context / properties / currency / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "USD",
      -      "EUR",
      -      "GBP",
      -      "CNY"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "USD",
      +      "EUR",
      +      "GBP",
      +      "CNY",
      +      "KRW"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / dashboardContext / properties / currency / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "USD",
      -      "EUR",
      -      "GBP",
      -      "CNY"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "USD",
      +      "EUR",
      +      "GBP",
      +      "CNY",
      +      "KRW"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  8. Changed3 schema fields changed
    • changedInput schema / properties / context / properties / datePreset / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "TRAILING_90_DAYS",
      -      "TRAILING_30_DAYS",
      -      "TRAILING_45_DAYS",
      -      "TRAILING_7_DAYS",
      -      "TRAILING_3_DAYS",
      -      "TRAILING_14_WEEKS",
      -      "MTD",
      -      "QTD",
      -      "YTD",
      -      "CURRENT_MONTH",
      -      "CURRENT_QUARTER",
      -      "CURRENT_YEAR",
      -      "LAST_WEEK",
      -      "LAST_MONTH",
      -      "LAST_6_MONTHS",
      -      "LAST_12_MONTHS",
      -      "LAST_4_YEARS",
      -      "LAST_3_MONTHS",
      -      "LAST_INVOICE_MONTH"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "TRAILING_90_DAYS",
      +      "TRAILING_30_DAYS",
      +      "TRAILING_45_DAYS",
      +      "TRAILING_7_DAYS",
      +      "TRAILING_3_DAYS",
      +      "TRAILING_1_DAYS",
      +      "TRAILING_14_WEEKS",
      +      "MTD",
      +      "QTD",
      +      "YTD",
      +      "CURRENT_MONTH",
      +      "CURRENT_QUARTER",
      +      "CURRENT_YEAR",
      +      "LAST_WEEK",
      +      "LAST_MONTH",
      +      "LAST_6_MONTHS",
      +      "LAST_12_MONTHS",
      +      "LAST_4_YEARS",
      +      "LAST_3_MONTHS",
      +      "LAST_INVOICE_MONTH"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / dashboardContext / properties / datePreset / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "TRAILING_90_DAYS",
      -      "TRAILING_30_DAYS",
      -      "TRAILING_45_DAYS",
      -      "TRAILING_7_DAYS",
      -      "TRAILING_3_DAYS",
      -      "TRAILING_14_WEEKS",
      -      "MTD",
      -      "QTD",
      -      "YTD",
      -      "CURRENT_MONTH",
      -      "CURRENT_QUARTER",
      -      "CURRENT_YEAR",
      -      "LAST_WEEK",
      -      "LAST_MONTH",
      -      "LAST_6_MONTHS",
      -      "LAST_12_MONTHS",
      -      "LAST_4_YEARS",
      -      "LAST_3_MONTHS",
      -      "LAST_INVOICE_MONTH"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "TRAILING_90_DAYS",
      +      "TRAILING_30_DAYS",
      +      "TRAILING_45_DAYS",
      +      "TRAILING_7_DAYS",
      +      "TRAILING_3_DAYS",
      +      "TRAILING_1_DAYS",
      +      "TRAILING_14_WEEKS",
      +      "MTD",
      +      "QTD",
      +      "YTD",
      +      "CURRENT_MONTH",
      +      "CURRENT_QUARTER",
      +      "CURRENT_YEAR",
      +      "LAST_WEEK",
      +      "LAST_MONTH",
      +      "LAST_6_MONTHS",
      +      "LAST_12_MONTHS",
      +      "LAST_4_YEARS",
      +      "LAST_3_MONTHS",
      +      "LAST_INVOICE_MONTH"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / operations / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "add",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "discriminator": {
      -          "propertyName": "type"
      -        },
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      -            "properties": {
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "textContent": {
      -                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      -                "type": "string"
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "text",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "textContent",
      -              "title"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "aggBy": {
      -                "default": "Month",
      -                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -                "enum": [
      -                  "Hour",
      -                  "Day",
      -                  "Week",
      -                  "Month",
      -                  "Period"
      -                ],
      -                "type": "string"
      -              },
      -              "compare": {
      -                "additionalProperties": false,
      -                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -                "properties": {
      -                  "chartType": {
      -                    "default": "WATERFALL",
      -                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -                    "enum": [
      -                      "WATERFALL",
      -                      "TABLE",
      -                      "KPI_BREAKDOWN"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "enabled": {
      -                    "default": true,
      -                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -                    "type": "boolean"
      -                  },
      -                  "from": {
      -                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "to": {
      -                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "datePreset": {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "TRAILING_90_DAYS",
      -                      "TRAILING_30_DAYS",
      -                      "TRAILING_45_DAYS",
      -                      "TRAILING_7_DAYS",
      -                      "TRAILING_3_DAYS",
      -                      "TRAILING_14_WEEKS",
      -                      "MTD",
      -                      "QTD",
      -                      "YTD",
      -                      "CURRENT_MONTH",
      -                      "CURRENT_QUARTER",
      -                      "CURRENT_YEAR",
      -                      "LAST_WEEK",
      -                      "LAST_MONTH",
      -                      "LAST_6_MONTHS",
      -                      "LAST_12_MONTHS",
      -                      "LAST_4_YEARS",
      -                      "LAST_3_MONTHS",
      -                      "LAST_INVOICE_MONTH"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      -              },
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "displayOptions": {
      -                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision. get_skill dashboards.",
      -                "properties": {
      -                  "hideEmptyRows": {
      -                    "description": "Hide rows with abs displayed sum < 0.01",
      -                    "type": "boolean"
      -                  },
      -                  "precision": {
      -                    "description": "Fraction digits 0–6",
      -                    "maximum": 6,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "showTotal": {
      -                    "description": "Show Total column",
      -                    "type": "boolean"
      -                  },
      -                  "sort": {
      -                    "properties": {
      -                      "by": {
      -                        "description": "total | cost | groupBy | query letter (a)",
      -                        "minLength": 1,
      -                        "type": "string"
      -                      },
      -                      "direction": {
      -                        "default": "DESC",
      -                        "description": "ASC | DESC (default DESC)",
      -                        "enum": [
      -                          "ASC",
      -                          "DESC"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "by"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "topN": {
      -                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      -                    "maximum": 100,
      -                    "minimum": 1,
      -                    "type": "integer"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "extendDashboardConditions": {
      -                "default": true,
      -                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      -                "type": "boolean"
      -              },
      -              "from": {
      -                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "limit": {
      -                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE widget, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      -                "maximum": 1000,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "queries": {
      -                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      -                "items": {
      -                  "additionalProperties": {},
      -                  "propertyNames": {
      -                    "type": "string"
      -                  },
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "scopeId": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "to": {
      -                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "chart",
      -                "default": "chart",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "title"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "additionalProperties": {},
      -        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to overwrite (keeps its position).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "remove",
      -        "type": "string"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to delete.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "add",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "discriminator": {
      +          "propertyName": "type"
      +        },
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      +            "properties": {
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "textContent": {
      +                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      +                "type": "string"
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "text",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "textContent",
      +              "title"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "aggBy": {
      +                "default": "Month",
      +                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +                "enum": [
      +                  "Hour",
      +                  "Day",
      +                  "Week",
      +                  "Month",
      +                  "Period"
      +                ],
      +                "type": "string"
      +              },
      +              "compare": {
      +                "additionalProperties": false,
      +                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +                "properties": {
      +                  "chartType": {
      +                    "default": "WATERFALL",
      +                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +                    "enum": [
      +                      "WATERFALL",
      +                      "TABLE",
      +                      "KPI_BREAKDOWN"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "enabled": {
      +                    "default": true,
      +                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +                    "type": "boolean"
      +                  },
      +                  "from": {
      +                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "to": {
      +                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "datePreset": {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "TRAILING_90_DAYS",
      +                      "TRAILING_30_DAYS",
      +                      "TRAILING_45_DAYS",
      +                      "TRAILING_7_DAYS",
      +                      "TRAILING_3_DAYS",
      +                      "TRAILING_1_DAYS",
      +                      "TRAILING_14_WEEKS",
      +                      "MTD",
      +                      "QTD",
      +                      "YTD",
      +                      "CURRENT_MONTH",
      +                      "CURRENT_QUARTER",
      +                      "CURRENT_YEAR",
      +                      "LAST_WEEK",
      +                      "LAST_MONTH",
      +                      "LAST_6_MONTHS",
      +                      "LAST_12_MONTHS",
      +                      "LAST_4_YEARS",
      +                      "LAST_3_MONTHS",
      +                      "LAST_INVOICE_MONTH"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      +              },
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "displayOptions": {
      +                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision. get_skill dashboards.",
      +                "properties": {
      +                  "hideEmptyRows": {
      +                    "description": "Hide rows with abs displayed sum < 0.01",
      +                    "type": "boolean"
      +                  },
      +                  "precision": {
      +                    "description": "Fraction digits 0–6",
      +                    "maximum": 6,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "showTotal": {
      +                    "description": "Show Total column",
      +                    "type": "boolean"
      +                  },
      +                  "sort": {
      +                    "properties": {
      +                      "by": {
      +                        "description": "total | cost | groupBy | query letter (a)",
      +                        "minLength": 1,
      +                        "type": "string"
      +                      },
      +                      "direction": {
      +                        "default": "DESC",
      +                        "description": "ASC | DESC (default DESC)",
      +                        "enum": [
      +                          "ASC",
      +                          "DESC"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "by"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "topN": {
      +                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      +                    "maximum": 100,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "extendDashboardConditions": {
      +                "default": true,
      +                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      +                "type": "boolean"
      +              },
      +              "from": {
      +                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "limit": {
      +                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE widget, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      +                "maximum": 1000,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "queries": {
      +                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      +                "items": {
      +                  "additionalProperties": {},
      +                  "propertyNames": {
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "scopeId": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "to": {
      +                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "chart",
      +                "default": "chart",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "title"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "additionalProperties": {},
      +        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to overwrite (keeps its position).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "remove",
      +        "type": "string"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to delete.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId"
      +    ],
      +    "type": "object"
      +  }
      +]
  9. Changed3 schema fields changed
    • changedInput schema / properties / dashboardContext / description
      Previous value: -"Partial patch for dashboard-level shared context (global filter, period, groupBy, metricId, currency, scopeId). Omitted fields keep their current values. Set `conditionsCel` to update/clear the global filter (empty string clears it). When changing period mode, null the unused side (`datePreset` vs `startDate`/`endDate`). Can be used alone or together with `operations`, `tags`, or `teamId`."New value: +"Partial patch for dashboard-level shared context (global filter, period, groupBy, metricId, currency, scopeId). Omitted fields keep their current values. Set `conditionsCel` to update/clear the global filter (empty string clears it). When changing period mode, null the unused side (`datePreset` vs `startDate`/`endDate`). Can be used alone or together with `operations` or `tags`."
    • changedInput schema / properties / operations / description
      Previous value: -"List of operations to apply atomically. Each op is \"add\" (append a new widget), \"replace\" (overwrite an existing widget in place), or \"remove\" (delete a widget). For add/replace, widgets inherit dashboard context by default; only pass per-widget overrides. Optional when `dashboardContext`, `tags`, or `teamId` is provided. Example: [{\"op\":\"add\",\"widget\":{\"title\":\"Monthly cost\",\"queries\":[{\"type\":\"cost\",\"name\":\"a\",\"chartType\":\"BAR\"}],\"aggBy\":\"Month\"}}]."New value: +"List of operations to apply atomically. Each op is \"add\" (append a new widget), \"replace\" (overwrite an existing widget in place), or \"remove\" (delete a widget). For add/replace, widgets inherit dashboard context by default; only pass per-widget overrides. Optional when `dashboardContext` or `tags` is provided. Example: [{\"op\":\"add\",\"widget\":{\"title\":\"Monthly cost\",\"queries\":[{\"type\":\"cost\",\"name\":\"a\",\"chartType\":\"BAR\"}],\"aggBy\":\"Month\"}}]."
    • removedInput schema / properties / teamId
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "description": "Team to assign the dashboard to (from `list_teams`), or null to detach from any team. Optional; omit to leave team unchanged."
      -}
  10. Changed3 schema fields changed
    • changedInput schema / properties / context / properties / datePreset / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "TRAILING_90_DAYS",
      -      "TRAILING_30_DAYS",
      -      "TRAILING_45_DAYS",
      -      "TRAILING_7_DAYS",
      -      "TRAILING_3_DAYS",
      -      "TRAILING_14_WEEKS",
      -      "MTD",
      -      "QTD",
      -      "YTD",
      -      "LAST_WEEK",
      -      "LAST_MONTH",
      -      "LAST_6_MONTHS",
      -      "LAST_12_MONTHS",
      -      "LAST_4_YEARS",
      -      "LAST_3_MONTHS",
      -      "LAST_INVOICE_MONTH"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "TRAILING_90_DAYS",
      +      "TRAILING_30_DAYS",
      +      "TRAILING_45_DAYS",
      +      "TRAILING_7_DAYS",
      +      "TRAILING_3_DAYS",
      +      "TRAILING_14_WEEKS",
      +      "MTD",
      +      "QTD",
      +      "YTD",
      +      "CURRENT_MONTH",
      +      "CURRENT_QUARTER",
      +      "CURRENT_YEAR",
      +      "LAST_WEEK",
      +      "LAST_MONTH",
      +      "LAST_6_MONTHS",
      +      "LAST_12_MONTHS",
      +      "LAST_4_YEARS",
      +      "LAST_3_MONTHS",
      +      "LAST_INVOICE_MONTH"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / dashboardContext / properties / datePreset / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "TRAILING_90_DAYS",
      -      "TRAILING_30_DAYS",
      -      "TRAILING_45_DAYS",
      -      "TRAILING_7_DAYS",
      -      "TRAILING_3_DAYS",
      -      "TRAILING_14_WEEKS",
      -      "MTD",
      -      "QTD",
      -      "YTD",
      -      "LAST_WEEK",
      -      "LAST_MONTH",
      -      "LAST_6_MONTHS",
      -      "LAST_12_MONTHS",
      -      "LAST_4_YEARS",
      -      "LAST_3_MONTHS",
      -      "LAST_INVOICE_MONTH"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "TRAILING_90_DAYS",
      +      "TRAILING_30_DAYS",
      +      "TRAILING_45_DAYS",
      +      "TRAILING_7_DAYS",
      +      "TRAILING_3_DAYS",
      +      "TRAILING_14_WEEKS",
      +      "MTD",
      +      "QTD",
      +      "YTD",
      +      "CURRENT_MONTH",
      +      "CURRENT_QUARTER",
      +      "CURRENT_YEAR",
      +      "LAST_WEEK",
      +      "LAST_MONTH",
      +      "LAST_6_MONTHS",
      +      "LAST_12_MONTHS",
      +      "LAST_4_YEARS",
      +      "LAST_3_MONTHS",
      +      "LAST_INVOICE_MONTH"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / operations / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "add",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "discriminator": {
      -          "propertyName": "type"
      -        },
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      -            "properties": {
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "textContent": {
      -                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      -                "type": "string"
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "text",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "textContent",
      -              "title"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "aggBy": {
      -                "default": "Month",
      -                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -                "enum": [
      -                  "Hour",
      -                  "Day",
      -                  "Week",
      -                  "Month",
      -                  "Period"
      -                ],
      -                "type": "string"
      -              },
      -              "compare": {
      -                "additionalProperties": false,
      -                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -                "properties": {
      -                  "chartType": {
      -                    "default": "WATERFALL",
      -                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -                    "enum": [
      -                      "WATERFALL",
      -                      "TABLE",
      -                      "KPI_BREAKDOWN"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "enabled": {
      -                    "default": true,
      -                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -                    "type": "boolean"
      -                  },
      -                  "from": {
      -                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "to": {
      -                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "datePreset": {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "TRAILING_90_DAYS",
      -                      "TRAILING_30_DAYS",
      -                      "TRAILING_45_DAYS",
      -                      "TRAILING_7_DAYS",
      -                      "TRAILING_3_DAYS",
      -                      "TRAILING_14_WEEKS",
      -                      "MTD",
      -                      "QTD",
      -                      "YTD",
      -                      "LAST_WEEK",
      -                      "LAST_MONTH",
      -                      "LAST_6_MONTHS",
      -                      "LAST_12_MONTHS",
      -                      "LAST_4_YEARS",
      -                      "LAST_3_MONTHS",
      -                      "LAST_INVOICE_MONTH"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      -              },
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "displayOptions": {
      -                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision. get_skill dashboards.",
      -                "properties": {
      -                  "hideEmptyRows": {
      -                    "description": "Hide rows with abs displayed sum < 0.01",
      -                    "type": "boolean"
      -                  },
      -                  "precision": {
      -                    "description": "Fraction digits 0–6",
      -                    "maximum": 6,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "showTotal": {
      -                    "description": "Show Total column",
      -                    "type": "boolean"
      -                  },
      -                  "sort": {
      -                    "properties": {
      -                      "by": {
      -                        "description": "total | cost | groupBy | query letter (a)",
      -                        "minLength": 1,
      -                        "type": "string"
      -                      },
      -                      "direction": {
      -                        "default": "DESC",
      -                        "description": "ASC | DESC (default DESC)",
      -                        "enum": [
      -                          "ASC",
      -                          "DESC"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "by"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "topN": {
      -                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      -                    "maximum": 100,
      -                    "minimum": 1,
      -                    "type": "integer"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "extendDashboardConditions": {
      -                "default": true,
      -                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      -                "type": "boolean"
      -              },
      -              "from": {
      -                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "limit": {
      -                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE widget, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      -                "maximum": 1000,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "queries": {
      -                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      -                "items": {
      -                  "additionalProperties": {},
      -                  "propertyNames": {
      -                    "type": "string"
      -                  },
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "scopeId": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "to": {
      -                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "chart",
      -                "default": "chart",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "title"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "additionalProperties": {},
      -        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to overwrite (keeps its position).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "remove",
      -        "type": "string"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to delete.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "add",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "discriminator": {
      +          "propertyName": "type"
      +        },
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      +            "properties": {
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "textContent": {
      +                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      +                "type": "string"
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "text",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "textContent",
      +              "title"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "aggBy": {
      +                "default": "Month",
      +                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +                "enum": [
      +                  "Hour",
      +                  "Day",
      +                  "Week",
      +                  "Month",
      +                  "Period"
      +                ],
      +                "type": "string"
      +              },
      +              "compare": {
      +                "additionalProperties": false,
      +                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +                "properties": {
      +                  "chartType": {
      +                    "default": "WATERFALL",
      +                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +                    "enum": [
      +                      "WATERFALL",
      +                      "TABLE",
      +                      "KPI_BREAKDOWN"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "enabled": {
      +                    "default": true,
      +                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +                    "type": "boolean"
      +                  },
      +                  "from": {
      +                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "to": {
      +                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "datePreset": {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "TRAILING_90_DAYS",
      +                      "TRAILING_30_DAYS",
      +                      "TRAILING_45_DAYS",
      +                      "TRAILING_7_DAYS",
      +                      "TRAILING_3_DAYS",
      +                      "TRAILING_14_WEEKS",
      +                      "MTD",
      +                      "QTD",
      +                      "YTD",
      +                      "CURRENT_MONTH",
      +                      "CURRENT_QUARTER",
      +                      "CURRENT_YEAR",
      +                      "LAST_WEEK",
      +                      "LAST_MONTH",
      +                      "LAST_6_MONTHS",
      +                      "LAST_12_MONTHS",
      +                      "LAST_4_YEARS",
      +                      "LAST_3_MONTHS",
      +                      "LAST_INVOICE_MONTH"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      +              },
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "displayOptions": {
      +                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision. get_skill dashboards.",
      +                "properties": {
      +                  "hideEmptyRows": {
      +                    "description": "Hide rows with abs displayed sum < 0.01",
      +                    "type": "boolean"
      +                  },
      +                  "precision": {
      +                    "description": "Fraction digits 0–6",
      +                    "maximum": 6,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "showTotal": {
      +                    "description": "Show Total column",
      +                    "type": "boolean"
      +                  },
      +                  "sort": {
      +                    "properties": {
      +                      "by": {
      +                        "description": "total | cost | groupBy | query letter (a)",
      +                        "minLength": 1,
      +                        "type": "string"
      +                      },
      +                      "direction": {
      +                        "default": "DESC",
      +                        "description": "ASC | DESC (default DESC)",
      +                        "enum": [
      +                          "ASC",
      +                          "DESC"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "by"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "topN": {
      +                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      +                    "maximum": 100,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "extendDashboardConditions": {
      +                "default": true,
      +                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      +                "type": "boolean"
      +              },
      +              "from": {
      +                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "limit": {
      +                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE widget, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      +                "maximum": 1000,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "queries": {
      +                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      +                "items": {
      +                  "additionalProperties": {},
      +                  "propertyNames": {
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "scopeId": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "to": {
      +                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "chart",
      +                "default": "chart",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "title"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "additionalProperties": {},
      +        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to overwrite (keeps its position).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "remove",
      +        "type": "string"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to delete.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId"
      +    ],
      +    "type": "object"
      +  }
      +]
  11. Changed1 schema field changed
    • changedInput schema / properties / operations / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "add",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "discriminator": {
      -          "propertyName": "type"
      -        },
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      -            "properties": {
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "textContent": {
      -                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      -                "type": "string"
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "text",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "textContent",
      -              "title"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "aggBy": {
      -                "default": "Month",
      -                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -                "enum": [
      -                  "Hour",
      -                  "Day",
      -                  "Week",
      -                  "Month",
      -                  "Period"
      -                ],
      -                "type": "string"
      -              },
      -              "compare": {
      -                "additionalProperties": false,
      -                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -                "properties": {
      -                  "chartType": {
      -                    "default": "WATERFALL",
      -                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -                    "enum": [
      -                      "WATERFALL",
      -                      "TABLE",
      -                      "KPI_BREAKDOWN"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "enabled": {
      -                    "default": true,
      -                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -                    "type": "boolean"
      -                  },
      -                  "from": {
      -                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "to": {
      -                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "datePreset": {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "TRAILING_90_DAYS",
      -                      "TRAILING_30_DAYS",
      -                      "TRAILING_45_DAYS",
      -                      "TRAILING_7_DAYS",
      -                      "TRAILING_3_DAYS",
      -                      "TRAILING_14_WEEKS",
      -                      "MTD",
      -                      "QTD",
      -                      "YTD",
      -                      "LAST_WEEK",
      -                      "LAST_MONTH",
      -                      "LAST_6_MONTHS",
      -                      "LAST_12_MONTHS",
      -                      "LAST_4_YEARS",
      -                      "LAST_3_MONTHS",
      -                      "LAST_INVOICE_MONTH"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      -              },
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "displayOptions": {
      -                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision. get_skill dashboards.",
      -                "properties": {
      -                  "hideEmptyRows": {
      -                    "description": "Hide rows with abs displayed sum < 0.01",
      -                    "type": "boolean"
      -                  },
      -                  "precision": {
      -                    "description": "Fraction digits 0–6",
      -                    "maximum": 6,
      -                    "minimum": 0,
      -                    "type": "integer"
      -                  },
      -                  "showTotal": {
      -                    "description": "Show Total column",
      -                    "type": "boolean"
      -                  },
      -                  "sort": {
      -                    "properties": {
      -                      "by": {
      -                        "description": "total | cost | groupBy | query letter (a)",
      -                        "minLength": 1,
      -                        "type": "string"
      -                      },
      -                      "direction": {
      -                        "default": "DESC",
      -                        "description": "ASC | DESC (default DESC)",
      -                        "enum": [
      -                          "ASC",
      -                          "DESC"
      -                        ],
      -                        "type": "string"
      -                      }
      -                    },
      -                    "required": [
      -                      "by"
      -                    ],
      -                    "type": "object"
      -                  },
      -                  "topN": {
      -                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      -                    "maximum": 100,
      -                    "minimum": 1,
      -                    "type": "integer"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "extendDashboardConditions": {
      -                "default": true,
      -                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      -                "type": "boolean"
      -              },
      -              "from": {
      -                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "limit": {
      -                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -                "maximum": 1000,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "queries": {
      -                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      -                "items": {
      -                  "additionalProperties": {},
      -                  "propertyNames": {
      -                    "type": "string"
      -                  },
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "scopeId": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "to": {
      -                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "chart",
      -                "default": "chart",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "title"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "additionalProperties": {},
      -        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to overwrite (keeps its position).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "remove",
      -        "type": "string"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to delete.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "add",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "discriminator": {
      +          "propertyName": "type"
      +        },
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      +            "properties": {
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "textContent": {
      +                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      +                "type": "string"
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "text",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "textContent",
      +              "title"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "aggBy": {
      +                "default": "Month",
      +                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +                "enum": [
      +                  "Hour",
      +                  "Day",
      +                  "Week",
      +                  "Month",
      +                  "Period"
      +                ],
      +                "type": "string"
      +              },
      +              "compare": {
      +                "additionalProperties": false,
      +                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +                "properties": {
      +                  "chartType": {
      +                    "default": "WATERFALL",
      +                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +                    "enum": [
      +                      "WATERFALL",
      +                      "TABLE",
      +                      "KPI_BREAKDOWN"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "enabled": {
      +                    "default": true,
      +                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +                    "type": "boolean"
      +                  },
      +                  "from": {
      +                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "to": {
      +                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "datePreset": {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "TRAILING_90_DAYS",
      +                      "TRAILING_30_DAYS",
      +                      "TRAILING_45_DAYS",
      +                      "TRAILING_7_DAYS",
      +                      "TRAILING_3_DAYS",
      +                      "TRAILING_14_WEEKS",
      +                      "MTD",
      +                      "QTD",
      +                      "YTD",
      +                      "LAST_WEEK",
      +                      "LAST_MONTH",
      +                      "LAST_6_MONTHS",
      +                      "LAST_12_MONTHS",
      +                      "LAST_4_YEARS",
      +                      "LAST_3_MONTHS",
      +                      "LAST_INVOICE_MONTH"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      +              },
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "displayOptions": {
      +                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision. get_skill dashboards.",
      +                "properties": {
      +                  "hideEmptyRows": {
      +                    "description": "Hide rows with abs displayed sum < 0.01",
      +                    "type": "boolean"
      +                  },
      +                  "precision": {
      +                    "description": "Fraction digits 0–6",
      +                    "maximum": 6,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "showTotal": {
      +                    "description": "Show Total column",
      +                    "type": "boolean"
      +                  },
      +                  "sort": {
      +                    "properties": {
      +                      "by": {
      +                        "description": "total | cost | groupBy | query letter (a)",
      +                        "minLength": 1,
      +                        "type": "string"
      +                      },
      +                      "direction": {
      +                        "default": "DESC",
      +                        "description": "ASC | DESC (default DESC)",
      +                        "enum": [
      +                          "ASC",
      +                          "DESC"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "by"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "topN": {
      +                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      +                    "maximum": 100,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "extendDashboardConditions": {
      +                "default": true,
      +                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      +                "type": "boolean"
      +              },
      +              "from": {
      +                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "limit": {
      +                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups. On a non-comparison TABLE widget, use displayOptions.topN for the row cap and omit this — the two are mutually exclusive there.",
      +                "maximum": 1000,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "queries": {
      +                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      +                "items": {
      +                  "additionalProperties": {},
      +                  "propertyNames": {
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "scopeId": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "to": {
      +                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "chart",
      +                "default": "chart",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "title"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "additionalProperties": {},
      +        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to overwrite (keeps its position).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "remove",
      +        "type": "string"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to delete.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId"
      +    ],
      +    "type": "object"
      +  }
      +]
  12. Changed1 schema field changed
    • changedInput schema / properties / operations / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "add",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "discriminator": {
      -          "propertyName": "type"
      -        },
      -        "oneOf": [
      -          {
      -            "additionalProperties": false,
      -            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      -            "properties": {
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "textContent": {
      -                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      -                "type": "string"
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "text",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "type",
      -              "textContent",
      -              "title"
      -            ],
      -            "type": "object"
      -          },
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "aggBy": {
      -                "default": "Month",
      -                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      -                "enum": [
      -                  "Hour",
      -                  "Day",
      -                  "Week",
      -                  "Month",
      -                  "Period"
      -                ],
      -                "type": "string"
      -              },
      -              "compare": {
      -                "additionalProperties": false,
      -                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      -                "properties": {
      -                  "chartType": {
      -                    "default": "WATERFALL",
      -                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      -                    "enum": [
      -                      "WATERFALL",
      -                      "TABLE",
      -                      "KPI_BREAKDOWN"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  "enabled": {
      -                    "default": true,
      -                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      -                    "type": "boolean"
      -                  },
      -                  "from": {
      -                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  },
      -                  "to": {
      -                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      -                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                    "type": "string"
      -                  }
      -                },
      -                "type": "object"
      -              },
      -              "datePreset": {
      -                "anyOf": [
      -                  {
      -                    "enum": [
      -                      "TRAILING_90_DAYS",
      -                      "TRAILING_30_DAYS",
      -                      "TRAILING_45_DAYS",
      -                      "TRAILING_7_DAYS",
      -                      "TRAILING_3_DAYS",
      -                      "TRAILING_14_WEEKS",
      -                      "MTD",
      -                      "QTD",
      -                      "YTD",
      -                      "LAST_WEEK",
      -                      "LAST_MONTH",
      -                      "LAST_6_MONTHS",
      -                      "LAST_12_MONTHS",
      -                      "LAST_4_YEARS",
      -                      "LAST_3_MONTHS",
      -                      "LAST_INVOICE_MONTH"
      -                    ],
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      -              },
      -              "description": {
      -                "default": "",
      -                "type": "string"
      -              },
      -              "extendDashboardConditions": {
      -                "default": true,
      -                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      -                "type": "boolean"
      -              },
      -              "from": {
      -                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "h": {
      -                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 9007199254740991,
      -                "type": "integer"
      -              },
      -              "limit": {
      -                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      -                "maximum": 1000,
      -                "minimum": 1,
      -                "type": "integer"
      -              },
      -              "queries": {
      -                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      -                "items": {
      -                  "additionalProperties": {},
      -                  "propertyNames": {
      -                    "type": "string"
      -                  },
      -                  "type": "object"
      -                },
      -                "type": "array"
      -              },
      -              "scopeId": {
      -                "anyOf": [
      -                  {
      -                    "type": "string"
      -                  },
      -                  {
      -                    "type": "null"
      -                  }
      -                ],
      -                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -              },
      -              "title": {
      -                "type": "string"
      -              },
      -              "to": {
      -                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "type": {
      -                "const": "chart",
      -                "default": "chart",
      -                "type": "string"
      -              },
      -              "w": {
      -                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 12,
      -                "type": "integer"
      -              },
      -              "x": {
      -                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      -                "maximum": 11,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "y": {
      -                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      -                "maximum": 9007199254740991,
      -                "minimum": 0,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "title"
      -            ],
      -            "type": "object"
      -          }
      -        ]
      -      }
      -    },
      -    "required": [
      -      "op"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "replace",
      -        "type": "string"
      -      },
      -      "widget": {
      -        "additionalProperties": {},
      -        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      -        "propertyNames": {
      -          "type": "string"
      -        },
      -        "type": "object"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to overwrite (keeps its position).",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId",
      -      "widget"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "op": {
      -        "const": "remove",
      -        "type": "string"
      -      },
      -      "widgetId": {
      -        "description": "ID of the widget to delete.",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "op",
      -      "widgetId"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "add",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "description": "Widget definition to append. Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "discriminator": {
      +          "propertyName": "type"
      +        },
      +        "oneOf": [
      +          {
      +            "additionalProperties": false,
      +            "description": "Text block widget (notes, headings, commentary). No queries or period — does not inherit dashboard metric/groupBy.",
      +            "properties": {
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "textContent": {
      +                "description": "Markdown or plain text body. Stored as `{ type: \"text\", textContent }` — same as the UI text widget.",
      +                "type": "string"
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "text",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "type",
      +              "textContent",
      +              "title"
      +            ],
      +            "type": "object"
      +          },
      +          {
      +            "additionalProperties": false,
      +            "properties": {
      +              "aggBy": {
      +                "default": "Month",
      +                "description": "Time grain for the series: Hour, Day, Week, Month, or Period (default Month).",
      +                "enum": [
      +                  "Hour",
      +                  "Day",
      +                  "Week",
      +                  "Month",
      +                  "Period"
      +                ],
      +                "type": "string"
      +              },
      +              "compare": {
      +                "additionalProperties": false,
      +                "description": "Add a comparison period to show cost evolution side-by-side. Omit `from`/`to` to compare against the preceding period automatically; set `chartType` to choose how it renders.",
      +                "properties": {
      +                  "chartType": {
      +                    "default": "WATERFALL",
      +                    "description": "How the comparison renders: WATERFALL (default, contribution to change), TABLE (before/after rows), or KPI_BREAKDOWN (per-group KPI cards). Note KPI_BREAKDOWN and TABLE widgets cannot be exported as PNG via get_widget_png.",
      +                    "enum": [
      +                      "WATERFALL",
      +                      "TABLE",
      +                      "KPI_BREAKDOWN"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  "enabled": {
      +                    "default": true,
      +                    "description": "Defaults to true — supplying `compare` at all turns the comparison on. Pass false to keep the block while disabling it (useful when echoing back a payload from `get`).",
      +                    "type": "boolean"
      +                  },
      +                  "from": {
      +                    "description": "Comparison period start date. Omit (together with `to`) to compare against the preceding period, derived from the main period.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  },
      +                  "to": {
      +                    "description": "Comparison period end date. Required together with `from`; omit both to auto-derive.",
      +                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                    "type": "string"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "datePreset": {
      +                "anyOf": [
      +                  {
      +                    "enum": [
      +                      "TRAILING_90_DAYS",
      +                      "TRAILING_30_DAYS",
      +                      "TRAILING_45_DAYS",
      +                      "TRAILING_7_DAYS",
      +                      "TRAILING_3_DAYS",
      +                      "TRAILING_14_WEEKS",
      +                      "MTD",
      +                      "QTD",
      +                      "YTD",
      +                      "LAST_WEEK",
      +                      "LAST_MONTH",
      +                      "LAST_6_MONTHS",
      +                      "LAST_12_MONTHS",
      +                      "LAST_4_YEARS",
      +                      "LAST_3_MONTHS",
      +                      "LAST_INVOICE_MONTH"
      +                    ],
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Widget-level date preset override. Omit to inherit dashboardContext.datePreset or startDate/endDate; use only when this widget differs from the dashboard period."
      +              },
      +              "description": {
      +                "default": "",
      +                "type": "string"
      +              },
      +              "displayOptions": {
      +                "description": "TABLE-only. sort {by, direction}, hideEmptyRows, topN (omit limit), showTotal, precision. get_skill dashboards.",
      +                "properties": {
      +                  "hideEmptyRows": {
      +                    "description": "Hide rows with abs displayed sum < 0.01",
      +                    "type": "boolean"
      +                  },
      +                  "precision": {
      +                    "description": "Fraction digits 0–6",
      +                    "maximum": 6,
      +                    "minimum": 0,
      +                    "type": "integer"
      +                  },
      +                  "showTotal": {
      +                    "description": "Show Total column",
      +                    "type": "boolean"
      +                  },
      +                  "sort": {
      +                    "properties": {
      +                      "by": {
      +                        "description": "total | cost | groupBy | query letter (a)",
      +                        "minLength": 1,
      +                        "type": "string"
      +                      },
      +                      "direction": {
      +                        "default": "DESC",
      +                        "description": "ASC | DESC (default DESC)",
      +                        "enum": [
      +                          "ASC",
      +                          "DESC"
      +                        ],
      +                        "type": "string"
      +                      }
      +                    },
      +                    "required": [
      +                      "by"
      +                    ],
      +                    "type": "object"
      +                  },
      +                  "topN": {
      +                    "description": "Ranked rows 1–100 after hide-empty + sort. Omit limit.",
      +                    "maximum": 100,
      +                    "minimum": 1,
      +                    "type": "integer"
      +                  }
      +                },
      +                "type": "object"
      +              },
      +              "extendDashboardConditions": {
      +                "default": true,
      +                "description": "Whether this widget AND-merges the dashboard's `context.conditionsCel` with its own `filterCel`. Defaults to true — omit to inherit the dashboard filter. Set false only when the widget must ignore dashboard-wide conditions.",
      +                "type": "boolean"
      +              },
      +              "from": {
      +                "description": "Widget-level date override (inclusive), e.g. '2025-01-01'. Omit when the widget uses the dashboard context period.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "h": {
      +                "description": "Grid height in rows. When provided, the widget keeps this exact height instead of the auto-computed default. Obtain the value from the `h` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 9007199254740991,
      +                "type": "integer"
      +              },
      +              "limit": {
      +                "description": "Max groups/rows per series. Omit to use the default (100). Increase up to 1000 when you need more than 100 breakdown groups.",
      +                "maximum": 1000,
      +                "minimum": 1,
      +                "type": "integer"
      +              },
      +              "queries": {
      +                "description": "Same series objects as the `query` tool `queries` array (cost / metric / usage / externalMetric / formula / budget). Each requires `type` (never omit) and a `name` (prefer short ids like a/b/c); put human labels in `alias`. On dashboard chart widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `dashboardContext`. Call get_skill skillId: \"dashboards\" for examples.",
      +                "items": {
      +                  "additionalProperties": {},
      +                  "propertyNames": {
      +                    "type": "string"
      +                  },
      +                  "type": "object"
      +                },
      +                "type": "array"
      +              },
      +              "scopeId": {
      +                "anyOf": [
      +                  {
      +                    "type": "string"
      +                  },
      +                  {
      +                    "type": "null"
      +                  }
      +                ],
      +                "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +              },
      +              "title": {
      +                "type": "string"
      +              },
      +              "to": {
      +                "description": "Widget-level end date override (inclusive). Required together with `from` only when overriding the dashboard period; omit when inheriting context.",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "type": {
      +                "const": "chart",
      +                "default": "chart",
      +                "type": "string"
      +              },
      +              "w": {
      +                "description": "Grid width in columns (1–12). When provided, the widget keeps this exact width instead of the auto-computed default. Obtain the value from the `w` field returned by `get`.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 12,
      +                "type": "integer"
      +              },
      +              "x": {
      +                "description": "Grid column index (0-based, 0 = left edge, max 11). When provided together with `y` (on a create_dashboard widget or an update_dashboard `add`) the widget is placed at the exact position instead of being auto-packed. Use `x`/`y` from `get` to copy a widget at its original position, or set manually (e.g. top-left: x=0 y=0, top-right of a half-width widget: x=6 y=0). Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing. When `w` is also set, `x + w` must be <= 12.",
      +                "maximum": 11,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "y": {
      +                "description": "Grid row index (0-based, 0 = top). Rows grow downward; combine with `x` to pin a widget to a specific spot. Both `x` and `y` must be supplied together — if only one is given the position falls back to auto-packing.",
      +                "maximum": 9007199254740991,
      +                "minimum": 0,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "title"
      +            ],
      +            "type": "object"
      +          }
      +        ]
      +      }
      +    },
      +    "required": [
      +      "op"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "replace",
      +        "type": "string"
      +      },
      +      "widget": {
      +        "additionalProperties": {},
      +        "description": "Same widget object as `widget` on op: \"add\" (text or chart). Chart `queries` match the `query` tool shape; pass only overrides relative to dashboard context.",
      +        "propertyNames": {
      +          "type": "string"
      +        },
      +        "type": "object"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to overwrite (keeps its position).",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId",
      +      "widget"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "op": {
      +        "const": "remove",
      +        "type": "string"
      +      },
      +      "widgetId": {
      +        "description": "ID of the widget to delete.",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "op",
      +      "widgetId"
      +    ],
      +    "type": "object"
      +  }
      +]
  13. First observed

TDQS

A4.9/5.0
Behavior5/5

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

Annotations already flag destructiveHint=true and readOnlyHint=false; the description goes well beyond that by disclosing fill/clear semantics (empty description clears, empty conditionsCel clears the filter, `[]` clears tags, omitted fields are kept), the inheritance rules for widgets, and that the response contains `inheritedContext` plus a URL that must be relayed to the user. Those are the exact behaviors an agent needs before performing a destructive partial patch.

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?

It is front-loaded with purpose and when-to-use before diving into widget inheritance and patch semantics, and nearly every sentence carries operational detail. It loses a point because a few clauses duplicate what the schema already documents verbatim (tag replacement and `[]` clearing, empty conditionsCel clearing), which lengthens an already dense block.

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

Completeness5/5

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

For a 10-parameter tool with deep nested operations, no output schema, and destructive semantics, the definition covers the required-one-of constraint, id sourcing, inheritance behavior, opt-out flags, tag creation side effects, and the returned URL/inheritedContext. Nothing an agent needs to call it correctly appears to be missing.

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

Parameters5/5

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

Schema coverage is already 100%, yet the description still adds meaning the schema cannot express: the partial-patch/omit-to-keep contract for dashboardContext, which series inherit period/conditionsCel/metricId/currency/groupBy and which do not (budget groupBy is explicit), the extendDashboardConditions escape hatch, `visible: false` for hidden formula inputs, and the text-widget shape. This is substantive semantic guidance rather than restatement.

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?

The first sentence names a specific verb and resource and enumerates the mutable surface (name, description, dashboardContext, widgets, tags). It also draws an explicit boundary against a sibling: 'Sharing is not an update_dashboard field — use get_object_permissions / set_object_permissions', so an agent will not confuse it with create_dashboard or the permission tools.

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?

It states the triggering condition ('Use when the user asks to change an existing dashboard's name, filters, or widgets'), tells the agent to obtain the id via `search`, and imposes a constraint that at least one of dashboardContext/operations/tags/name/description is required. Competing tools are named for the cases this tool does not cover (search, get_skill, list_tags, get_object_permissions/set_object_permissions).

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