Skip to main content
Glama

Costory: Your Finops MCP

create_report

Destructive

Save a Costory report with widgets, destinations, and a delivery schedule. Use when the user requests a saved or scheduled report. NOW sends immediately; recurring schedules enable future delivery. Delivery may be partial, and archiving the report does not retract messages already sent. New reports are creator-only (you get Admin). To share, call set_object_permissions after create — do not send PRIVATE/PUBLIC or teamId. The get_skill guide "reports" explains context-first workflow and DIGEST preview iteration. Put shared settings in reportContext (period required when query widgets are present: datePreset when a preset matches; plus metricId, common groupBy, currency, optional conditionsCel / scopeId). Query widgets inherit by default and should only specify overrides — do not repeat from/to, datePreset, groupBy, metricId, or currency when they match reportContext. Schedule modes: • NOW — create an on-demand report and immediately deliver it to every destination. DANGER ZONE: this sends real messages now. Summarize scope, schedule, and every destination, then ask the user to confirm before calling. • UNSCHEDULED — save an on-demand draft without delivery. • SCHEDULED — create a recurring report (DAILY / WEEKDAYS / WEEKLY / MONTHLY). DANGER ZONE: this authorizes future channel delivery. Summarize the recurring schedule and every destination, then ask the user to confirm before calling. Optional tagIds: existing IDs from list_tags and/or { name, color? } for new tags; color defaults to #6366F1; missing tags are created. Omit and [] both leave the report untagged. Widget types: DASHBOARD_PDF, GRAPH_SNAPSHOT, TOP_FLOP, TEXT, and DIGEST. A DASHBOARD_PDF widget renders an existing dashboard as a PDF — pass { type: "DASHBOARD_PDF", dashboardId: "<id from search>" } (dashboardId required). TEXT widgets use { type: "TEXT", contentMarkdown } (not dashboard textContent). DIGEST hierarchy: reportContext.groupBy (default root) + ordered additionalGroupBy (deeper levels); also supports thresholds. Per-widget override: set DIGEST useDashboardGroupBy: false to ignore reportContext.groupBy for that widget — the first additionalGroupBy item (or queries[0].groupBy) becomes the root; false requires at least one dimension. DIGEST accepts a per-widget queries[0].filterCel (CEL) — AND-combined with reportContext.conditionsCel by default (extendDashboardConditions defaults true), applied to both the comparison periods, and named by the AI summary. Use it for focused digests (e.g. Kubernetes only: cos_cluster_name != null) next to an unfiltered org-wide digest in the same report. DIGEST AI (opt-in, slower): display ("tree" default | "table" | "summary" for LLM executive narrative) and enableAiInvestigation (boolean, default false — per-node deep analysis, independent of display). DIGEST aggBy is Month or Week — never Period (Period is TOP_FLOP). Preview and create use the same reportContext + widget shape. For WEEKLY schedules, schedule.weekday is required (0 = Sunday … 6 = Saturday). Destinations: SLACK/TEAMS take channelId; EMAIL takes email (a single address, the literal ALL_ACTIVE_USERS to reach every active user, or destinations.email.self from list_available_destinations for "email me"). Mergeable same-type items (two emails, two Slack/Teams channels) are stored as one destination and share one execution; mixed types stay separate. Exclusive sentinels (ALL_ACTIVE_USERS, SHARED_SLACK) stay on their own destination and execution. Returns report URL and nextRunAt; NOW also returns execution URLs and per-destination status. EXAMPLE monthly DIGEST: { schedule: { mode: "UNSCHEDULED" }, reportContext: { datePreset: "LAST_MONTH", groupBy: "cos_environment", metricId: "cost", currency: "USD" }, widgets: [{ type: "DIGEST", queries: [{ type: "cost", name: "a" }], aggBy: "Month", additionalGroupBy: ["cos_sub_account_id", "cos_service_name"], minAbsoluteDiff: 100, minRelativeDiff: 5, topLargestAbsoluteChange: 20, display: "summary", enableAiInvestigation: false }, { type: "DIGEST", title: "Kubernetes", queries: [{ type: "cost", name: "a", filterCel: "cos_cluster_name != null" }], aggBy: "Week" }], destinations: [{ destinationType: "SLACK", channelId: "C…" }] } EXAMPLE namespace-rooted DIGEST (overrides reportContext.groupBy for this widget only): { schedule: { mode: "UNSCHEDULED" }, reportContext: { datePreset: "LAST_MONTH", groupBy: "cos_environment", metricId: "cost", currency: "USD" }, widgets: [{ type: "DIGEST", title: "Kubernetes", useDashboardGroupBy: false, queries: [{ type: "cost", name: "a" }], aggBy: "Month", additionalGroupBy: ["cos_namespace_reallocated", "cos_workload_name"] }], destinations: [{ destinationType: "SLACK", channelId: "C…" }] } EXAMPLE GRAPH_SNAPSHOT + TOP_FLOP: { schedule: { mode: "SCHEDULED", period: "WEEKLY", weekday: 1, firstRunAt: "2026-08-04T10:00:00.000Z" }, reportContext: { metricId: "cost", currency: "USD", groupBy: "cos_service_name", datePreset: "LAST_WEEK" }, widgets: [{ type: "GRAPH_SNAPSHOT", title: "Cost by service — trailing weeks", queries: [{ type: "cost", name: "a", chartType: "LINE" }], datePreset: "TRAILING_14_WEEKS", aggBy: "Week" }, { type: "TOP_FLOP", title: "Last week movers by service", queries: [{ type: "cost", name: "a" }], aggBy: "Period", topN: 5, flopN: 5 }], destinations: [{ destinationType: "SLACK", channelId: "C…" }] }

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": {
      "schedule": "<schedule>",
      "widgets": "<widgets>",
      "destinations": "<destinations>",
      "context": "<context>"
    },
    "name": "create_report"
  }
}

Input Schema

NameRequiredDescriptionDefault
nameNoOptional; empty or omitted → server generates a name from content.
slugNoOrganization slug. Omit to auto-detect from your account (fails if you belong to multiple orgs).
scoutNoScout persona NAME (from list_scouts) or its id, assigned to dynamic explanations. Omitted = no scout.
tagIdsNoPass existing tag IDs from `list_tags`, and/or new tag objects `{ name, color? }` (created in the org if missing; color defaults to #6366F1). Omit and [] both leave the report untagged.
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.
widgetsYesOne or more report widgets (DIGEST / GRAPH_SNAPSHOT / TOP_FLOP / TEXT / DASHBOARD_PDF / DIVIDER). DIVIDER is the Slack thread cut (at most one): widgets above post in the channel, widgets below as replies. Call get_skill skillId: "reports" for examples.
scheduleYesDelivery mode: NOW (sends immediately), UNSCHEDULED (draft), or SCHEDULED (recurring; WEEKLY requires `weekday`).
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.
descriptionNoOptional longer description (default empty).
destinationsYesDelivery targets: `{ destinationType, channelId }` or `{ destinationType: "EMAIL", email }`. Resolve channels via `list_available_destinations`.
reportContextNoReport-level shared context. Put period (datePreset when a preset matches), metricId, common groupBy, currency, optional conditionsCel / scopeId here — query widgets omit those fields to inherit. Call get_skill skillId: "reports" first.
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.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed7 schema fields changed
    • changedInput schema / definitions / ReportMcpContext / 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."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 / definitions / ReportMcpQueries / description
      Previous value: -"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 inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Budget groupBy is explicit (budget VD bqName); it does not inherit reportContext.groupBy. Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports."New value: +"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 inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Budget groupBy is explicit (budget VD bqName); it does not inherit reportContext.groupBy. Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports."
    • 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 / reportContext / description
      Previous value: -"Report-level shared context. Put period (prefer datePreset), metricId, common groupBy, currency, optional conditionsCel / scopeId here — query widgets omit those fields to inherit. Call get_skill skillId: \"reports\" first."New value: +"Report-level shared context. Put period (datePreset when a preset matches), metricId, common groupBy, currency, optional conditionsCel / scopeId here — query widgets omit those fields to inherit. Call get_skill skillId: \"reports\" first."
    • changedInput schema / properties / scout / description
      Previous value: -"Scout persona NAME (from list_scouts) — preferred — or its id, assigned to dynamic explanations. Omitted = no scout."New value: +"Scout persona NAME (from list_scouts) or its id, assigned to dynamic explanations. Omitted = no scout."
    • changedInput schema / properties / widgets / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "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"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "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": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "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": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      -        "type": [
      -          "string",
      -          "null"
      -        ]
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "queries",
      -      "type"
      -    ],
      -    "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"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      -        "type": [
      -          "string",
      -          "null"
      -        ]
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "queries",
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DIVIDER",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "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"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "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"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "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"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      -        "type": [
      -          "string",
      -          "null"
      -        ]
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      -        "maximum": 100,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      },
      -      "useDashboardGroupBy": {
      -        "default": true,
      -        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "queries",
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "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"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "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": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "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": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "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"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DIVIDER",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` by default, or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Use datePreset or reportContext when available.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "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"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "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"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Use display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "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"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      },
      +      "useDashboardGroupBy": {
      +        "default": true,
      +        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
    • changedInput schema / required
      Previous value: -[
      -  "schedule",
      -  "widgets",
      -  "destinations",
      -  "context",
      -  "llm_model"
      -]New value: +[
      +  "schedule",
      +  "widgets",
      +  "destinations",
      +  "context"
      +]
  2. Changed6 schema fields changed
    • removedInput schema / properties / context / allOf
      Removed value: -[
      -  {
      -    "$ref": "#/definitions/ReportMcpContext"
      -  }
      -]
    • changedInput schema / properties / context / description
      Previous value: -"Deprecated alias for `reportContext`; 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.\""
    • addedInput schema / properties / context / type
      Added 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: -[
      -  "schedule",
      -  "widgets",
      -  "destinations"
      -]New value: +[
      +  "schedule",
      +  "widgets",
      +  "destinations",
      +  "context",
      +  "llm_model"
      +]
  3. Changed10 schema fields changed
    • removedInput schema / definitions / ReportMcpContext / properties / groupBy / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / definitions / ReportMcpContext / properties / groupBy / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / definitions / ReportMcpContext / properties / metricId / anyOf
      Removed value: -[
      -  {
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / definitions / ReportMcpContext / properties / metricId / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • removedInput schema / definitions / ReportMcpContext / properties / scopeId / anyOf
      Removed value: -[
      -  {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ]
      -  },
      -  {
      -    "type": "null"
      -  }
      -]
    • addedInput schema / definitions / ReportMcpContext / properties / scopeId / type
      Added value: +[
      +  "string",
      +  "null"
      +]
    • changedInput schema / properties / schedule / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "mode": {
      -        "const": "NOW",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "mode"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "mode": {
      -        "const": "UNSCHEDULED",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "mode"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "firstRunAt": {
      -        "description": "First send date as ISO-8601 UTC datetime (e.g. 2026-07-16T00:00:00.000Z). The time of day is ignored; the report is due for that whole UTC day.",
      -        "format": "date-time",
      -        "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])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
      -        "type": "string"
      -      },
      -      "mode": {
      -        "const": "SCHEDULED",
      -        "type": "string"
      -      },
      -      "period": {
      -        "description": "Recurrence: DAILY, WEEKDAYS, WEEKLY, or MONTHLY. WEEKLY requires `weekday`.",
      -        "enum": [
      -          "DAILY",
      -          "WEEKDAYS",
      -          "WEEKLY",
      -          "MONTHLY"
      -        ],
      -        "type": "string"
      -      },
      -      "weekday": {
      -        "description": "Day of week for WEEKLY: 0 = Sunday … 6 = Saturday. Required when period is WEEKLY (Zod refine; may appear optional in JSON Schema).",
      -        "maximum": 6,
      -        "minimum": 0,
      -        "type": "integer"
      -      }
      -    },
      -    "required": [
      -      "mode",
      -      "period"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "mode": {
      +        "const": "NOW",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "mode"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "mode": {
      +        "const": "UNSCHEDULED",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "mode"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "firstRunAt": {
      +        "description": "First send date as ISO-8601 UTC datetime (e.g. 2026-07-16T00:00:00.000Z). The time of day is ignored; the report is due for that whole UTC day.",
      +        "format": "date-time",
      +        "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])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
      +        "type": "string"
      +      },
      +      "mode": {
      +        "const": "SCHEDULED",
      +        "type": "string"
      +      },
      +      "period": {
      +        "description": "Recurrence: DAILY, WEEKDAYS, WEEKLY, or MONTHLY. WEEKLY requires `weekday`.",
      +        "enum": [
      +          "DAILY",
      +          "WEEKDAYS",
      +          "WEEKLY",
      +          "MONTHLY"
      +        ],
      +        "type": "string"
      +      },
      +      "weekday": {
      +        "description": "Day of week for WEEKLY: 0 = Sunday … 6 = Saturday. Required when period is WEEKLY (Zod refine; may appear optional in JSON Schema).",
      +        "maximum": 6,
      +        "minimum": 0,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "mode",
      +      "period"
      +    ],
      +    "type": "object"
      +  }
      +]
    • addedInput schema / properties / scout
      Added value: +{
      +  "description": "Scout persona NAME (from list_scouts) — preferred — or its id, assigned to dynamic explanations. Omitted = no scout.",
      +  "minLength": 1,
      +  "type": "string"
      +}
    • changedInput schema / properties / widgets / description
      Previous value: -"One or more report widgets (DIGEST / GRAPH_SNAPSHOT / TOP_FLOP / TEXT / DASHBOARD_PDF). Call get_skill skillId: \"reports\" for examples."New value: +"One or more report widgets (DIGEST / GRAPH_SNAPSHOT / TOP_FLOP / TEXT / DASHBOARD_PDF / DIVIDER). DIVIDER is the Slack thread cut (at most one): widgets above post in the channel, widgets below as replies. Call get_skill skillId: \"reports\" for examples."
    • changedInput schema / properties / widgets / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "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"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "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": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "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": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "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"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "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"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "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"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "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"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      -        "maximum": 100,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      },
      -      "useDashboardGroupBy": {
      -        "default": true,
      -        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      -        "type": "boolean"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "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"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "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": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "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": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "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"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "DIVIDER",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "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"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "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"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "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"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries.",
      +        "type": [
      +          "string",
      +          "null"
      +        ]
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      },
      +      "useDashboardGroupBy": {
      +        "default": true,
      +        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "queries",
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  4. Changed1 schema field changed
    • changedInput schema / properties / widgets / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "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"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "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": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "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": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "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"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "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"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "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"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "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"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "queries": {
      -        "$ref": "#/definitions/ReportMcpQueries"
      -      },
      -      "scopeId": {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ],
      -        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      -      },
      -      "title": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      -        "maximum": 100,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "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"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "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": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "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": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "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"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "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"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "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"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "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"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      },
      +      "useDashboardGroupBy": {
      +        "default": true,
      +        "description": "Use `reportContext.groupBy` as this DIGEST's root group-by (default true). Set false to override: the report context group-by is ignored for this widget and the first `additionalGroupBy` item (or `queries[0].groupBy`) becomes the root. `false` requires at least one dimension (a non-empty `additionalGroupBy` or a `queries[0].groupBy`). Example: useDashboardGroupBy: false + additionalGroupBy: [\"cos_namespace_reallocated\",\"cos_workload_name\"] → root cos_namespace_reallocated, report context key ignored for this widget only.",
      +        "type": "boolean"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  5. Changed1 schema field changed
    • changedInput schema / definitions / ReportMcpQueries / description
      Previous value: -"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 inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports."New value: +"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 inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Budget groupBy is explicit (budget VD bqName); it does not inherit reportContext.groupBy. Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports."
  6. Changed9 schema fields changed
    • addedInput schema / definitions
      Added value: +{
      +  "ReportMcpContext": {
      +    "properties": {
      +      "conditionsCel": {
      +        "description": "Report-wide CEL filter merged into cost and usage widgets. Omit or empty string for no report-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."
      +      },
      +      "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": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Default group-by axis inherited by widgets that omit `groupBy`. For DIGEST, this is the root hierarchy axis — put deeper levels in `additionalGroupBy`."
      +      },
      +      "metricId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Default metric inherited by widget cost queries that omit `metricId`."
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "anyOf": [
      +              {
      +                "type": "string"
      +              },
      +              {
      +                "type": "null"
      +              }
      +            ]
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Applied report-wide unless a widget overrides."
      +      },
      +      "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)."
      +      }
      +    },
      +    "type": "object"
      +  },
      +  "ReportMcpQueries": {
      +    "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 inherits metricId/currency/groupBy from reportContext; usage requires metricId (omit groupBy = ungrouped). Cost/usage inherit conditionsCel. `visible: false` hides a series. DIGEST: one cost query. See skill reports.",
      +    "items": {
      +      "additionalProperties": {},
      +      "propertyNames": {
      +        "type": "string"
      +      },
      +      "type": "object"
      +    },
      +    "type": "array"
      +  }
      +}
    • addedInput schema / properties / context / allOf
      Added value: +[
      +  {
      +    "$ref": "#/definitions/ReportMcpContext"
      +  }
      +]
    • removedInput schema / properties / context / properties
      Removed value: -{
      -  "conditionsCel": {
      -    "description": "Report-wide CEL filter merged into cost widgets. Omit or empty string for no report-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."
      -  },
      -  "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": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default group-by axis inherited by widgets that omit `groupBy`. For DIGEST, this is the root hierarchy axis — put deeper levels in `additionalGroupBy`."
      -  },
      -  "metricId": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default metric inherited by widget cost queries that omit `metricId`."
      -  },
      -  "scopeId": {
      -    "anyOf": [
      -      {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Optional saved team scope id (from list_teams). Applied report-wide unless a widget overrides."
      -  },
      -  "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)."
      -  }
      -}
    • removedInput schema / properties / context / type
      Removed value: -"object"
    • addedInput schema / properties / reportContext / allOf
      Added value: +[
      +  {
      +    "$ref": "#/definitions/ReportMcpContext"
      +  }
      +]
    • removedInput schema / properties / reportContext / properties
      Removed value: -{
      -  "conditionsCel": {
      -    "description": "Report-wide CEL filter merged into cost widgets. Omit or empty string for no report-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."
      -  },
      -  "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": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default group-by axis inherited by widgets that omit `groupBy`. For DIGEST, this is the root hierarchy axis — put deeper levels in `additionalGroupBy`."
      -  },
      -  "metricId": {
      -    "anyOf": [
      -      {
      -        "type": "string"
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Default metric inherited by widget cost queries that omit `metricId`."
      -  },
      -  "scopeId": {
      -    "anyOf": [
      -      {
      -        "anyOf": [
      -          {
      -            "type": "string"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      {
      -        "type": "null"
      -      }
      -    ],
      -    "description": "Optional saved team scope id (from list_teams). Applied report-wide unless a widget overrides."
      -  },
      -  "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)."
      -  }
      -}
    • removedInput schema / properties / reportContext / type
      Removed value: -"object"
    • changedInput schema / properties / widgets / description
      Previous value: -"One or more report widgets (DIGEST / GRAPH_SNAPSHOT / TOP_FLOP / TEXT / DASHBOARD_PDF). For query-backed widgets prefer sparse cost `queries` and inherit period / groupBy / metricId / currency from `reportContext`. Call get_skill skillId: \"reports\" for examples."New value: +"One or more report widgets (DIGEST / GRAPH_SNAPSHOT / TOP_FLOP / TEXT / DASHBOARD_PDF). Call get_skill skillId: \"reports\" for examples."
    • changedInput schema / properties / widgets / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "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"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "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": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "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": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "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"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "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"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "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"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "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"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      -        "maximum": 100,
      -        "minimum": 1,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "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"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "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": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "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": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "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"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "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"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "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"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "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"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "queries": {
      +        "$ref": "#/definitions/ReportMcpQueries"
      +      },
      +      "scopeId": {
      +        "anyOf": [
      +          {
      +            "type": "string"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ],
      +        "description": "Optional saved team scope id (from list_teams). Merges the scope whereClause into cost/usage queries."
      +      },
      +      "title": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  7. 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."New value: +"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate."
    • changedInput schema / properties / reportContext / 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."New value: +"Default date preset inherited when a widget omits date fields. Forecast: CURRENT_MONTH / CURRENT_QUARTER / CURRENT_YEAR. Prefer this over startDate/endDate."
  8. 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 / reportContext / 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"
      +  }
      +]
  9. Changed2 schema fields changed
    • changedInput schema / properties / schedule / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "mode": {
      -        "const": "NOW",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "mode"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "mode": {
      -        "const": "UNSCHEDULED",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "mode"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "firstRunAt": {
      -        "description": "First send time as ISO-8601 UTC datetime (e.g. 2026-07-16T10:00:00.000Z)",
      -        "format": "date-time",
      -        "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])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
      -        "type": "string"
      -      },
      -      "mode": {
      -        "const": "SCHEDULED",
      -        "type": "string"
      -      },
      -      "period": {
      -        "description": "Recurrence: DAILY, WEEKDAYS, WEEKLY, or MONTHLY. WEEKLY requires `weekday`.",
      -        "enum": [
      -          "DAILY",
      -          "WEEKDAYS",
      -          "WEEKLY",
      -          "MONTHLY"
      -        ],
      -        "type": "string"
      -      },
      -      "weekday": {
      -        "description": "Day of week for WEEKLY: 0 = Sunday … 6 = Saturday. Required when period is WEEKLY (Zod refine; may appear optional in JSON Schema).",
      -        "maximum": 6,
      -        "minimum": 0,
      -        "type": "integer"
      -      }
      -    },
      -    "required": [
      -      "mode",
      -      "period"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "mode": {
      +        "const": "NOW",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "mode"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "mode": {
      +        "const": "UNSCHEDULED",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "mode"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "firstRunAt": {
      +        "description": "First send date as ISO-8601 UTC datetime (e.g. 2026-07-16T00:00:00.000Z). The time of day is ignored; the report is due for that whole UTC day.",
      +        "format": "date-time",
      +        "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])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$",
      +        "type": "string"
      +      },
      +      "mode": {
      +        "const": "SCHEDULED",
      +        "type": "string"
      +      },
      +      "period": {
      +        "description": "Recurrence: DAILY, WEEKDAYS, WEEKLY, or MONTHLY. WEEKLY requires `weekday`.",
      +        "enum": [
      +          "DAILY",
      +          "WEEKDAYS",
      +          "WEEKLY",
      +          "MONTHLY"
      +        ],
      +        "type": "string"
      +      },
      +      "weekday": {
      +        "description": "Day of week for WEEKLY: 0 = Sunday … 6 = Saturday. Required when period is WEEKLY (Zod refine; may appear optional in JSON Schema).",
      +        "maximum": 6,
      +        "minimum": 0,
      +        "type": "integer"
      +      }
      +    },
      +    "required": [
      +      "mode",
      +      "period"
      +    ],
      +    "type": "object"
      +  }
      +]
    • addedInput schema / properties / tagIds
      Added value: +{
      +  "description": "Pass existing tag IDs from `list_tags`, and/or new tag objects `{ name, color? }` (created in the org if missing; color defaults to #6366F1). Omit and [] both leave the report untagged.",
      +  "items": {
      +    "anyOf": [
      +      {
      +        "description": "Existing tag ID",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "color": {
      +            "default": "#6366F1",
      +            "description": "Hex color for the new tag (defaults to #6366F1)",
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "name": {
      +            "minLength": 1,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "name"
      +        ],
      +        "type": "object"
      +      }
      +    ]
      +  },
      +  "type": "array"
      +}
  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",
      -      "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 / reportContext / 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 / widgets / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "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"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "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": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "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": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "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"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "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"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "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"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "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"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      -        "type": "number"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "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"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "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": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "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": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "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"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "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"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "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"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "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"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface (integer 1–100). Applied at every tree level.",
      +        "maximum": 100,
      +        "minimum": 1,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  11. Changed2 schema fields changed
    • removedInput schema / properties / teamId
      Removed value: -{
      -  "anyOf": [
      -    {
      -      "type": "string"
      -    },
      -    {
      -      "type": "null"
      -    }
      -  ],
      -  "description": "Optional owning team id. Independent of type/visibility; omit or null for no team."
      -}
    • removedInput schema / properties / visibility
      Removed value: -{
      -  "default": "PRIVATE",
      -  "description": "PRIVATE (default) or PUBLIC (maps to API `type`). Set `teamId` to share with a team — there is no TEAM visibility value. TEMPLATE is dashboard-only.",
      -  "enum": [
      -    "PRIVATE",
      -    "PUBLIC"
      -  ],
      -  "type": "string"
      -}
  12. 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 / reportContext / 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 / widgets / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "datePreset": {
      -        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      -        "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"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      -        "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": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "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": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "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"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "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"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "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"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "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"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      -        "type": "number"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "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"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "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": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "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": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "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"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 50,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 50,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "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"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "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"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "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"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      +        "type": "number"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  13. Changed2 schema fields changed
    • changedInput schema / properties / visibility / description
      Previous value: -"PRIVATE (default), PUBLIC, or TEMPLATE (maps to API `type`). Set `teamId` to share with a team — there is no TEAM visibility value."New value: +"PRIVATE (default) or PUBLIC (maps to API `type`). Set `teamId` to share with a team — there is no TEAM visibility value. TEMPLATE is dashboard-only."
    • changedInput schema / properties / visibility / enum
      Previous value: -[
      -  "PRIVATE",
      -  "PUBLIC",
      -  "TEMPLATE"
      -]New value: +[
      +  "PRIVATE",
      +  "PUBLIC"
      +]
  14. Changed1 schema field changed
    • changedInput schema / properties / widgets / items / oneOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dashboardId": {
      -        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "DASHBOARD_PDF",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "dashboardId"
      -    ],
      -    "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": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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": {
      -        "const": "GRAPH_SNAPSHOT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "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"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "flopN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "from": {
      -        "description": "Widget-level start date override. Omit to inherit report context period.",
      -        "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"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      -        "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"
      -      },
      -      "topN": {
      -        "default": 5,
      -        "maximum": 50,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "type": {
      -        "const": "TOP_FLOP",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "contentMarkdown": {
      -        "maxLength": 10000,
      -        "minLength": 1,
      -        "type": "string"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "title": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "type": {
      -        "const": "TEXT",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type",
      -      "contentMarkdown"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "additionalGroupBy": {
      -        "default": [],
      -        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      -        "items": {
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "type": "array"
      -      },
      -      "aggBy": {
      -        "default": "Month",
      -        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      -        "enum": [
      -          "Week",
      -          "Month"
      -        ],
      -        "type": "string"
      -      },
      -      "compare": {
      -        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      -        "properties": {
      -          "from": {
      -            "description": "Comparison period start date.",
      -            "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"
      -          },
      -          "to": {
      -            "description": "Comparison period end date.",
      -            "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"
      -          }
      -        },
      -        "required": [
      -          "from",
      -          "to"
      -        ],
      -        "type": "object"
      -      },
      -      "datePreset": {
      -        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      -        "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"
      -      },
      -      "description": {
      -        "default": "",
      -        "type": "string"
      -      },
      -      "display": {
      -        "default": "tree",
      -        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      -        "enum": [
      -          "tree",
      -          "table",
      -          "summary"
      -        ],
      -        "type": "string"
      -      },
      -      "enableAiInvestigation": {
      -        "default": false,
      -        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      -        "type": "boolean"
      -      },
      -      "from": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "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"
      -      },
      -      "minAbsoluteDiff": {
      -        "default": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "minRelativeDiff": {
      -        "default": 5,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      -        "default": "Cost changes",
      -        "type": "string"
      -      },
      -      "to": {
      -        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      -        "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"
      -      },
      -      "topLargestAbsoluteChange": {
      -        "default": 20,
      -        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      -        "type": "number"
      -      },
      -      "type": {
      -        "const": "DIGEST",
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "type"
      -    ],
      -    "type": "object"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "dashboardId": {
      +        "description": "Id of the dashboard to render as a PDF (from `search`/`get`).",
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "datePreset": {
      +        "description": "Optional period override for the PDF. Omit to inherit the report (and destination) period.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Optional custom range start (YYYY-MM-DD). Use with to instead of datePreset.",
      +        "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"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Optional custom range end (inclusive, YYYY-MM-DD). Use with from instead of datePreset.",
      +        "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": {
      +        "const": "DASHBOARD_PDF",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "dashboardId"
      +    ],
      +    "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": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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": {
      +        "const": "GRAPH_SNAPSHOT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "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"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Use either datePreset OR explicit from/to, not both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "flopN": {
      +        "default": 5,
      +        "maximum": 50,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "from": {
      +        "description": "Widget-level start date override. Omit to inherit report context period.",
      +        "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"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Widget-level end date override (inclusive). Omit to inherit report context period.",
      +        "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"
      +      },
      +      "topN": {
      +        "default": 5,
      +        "maximum": 50,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "type": {
      +        "const": "TOP_FLOP",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "contentMarkdown": {
      +        "maxLength": 10000,
      +        "minLength": 1,
      +        "type": "string"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "title": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "type": {
      +        "const": "TEXT",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type",
      +      "contentMarkdown"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "additionalGroupBy": {
      +        "default": [],
      +        "description": "Deeper DIGEST hierarchy levels AFTER the root groupBy, in order. Root axis is `reportContext.groupBy` (preferred) or `queries[0].groupBy` when overriding. Example: reportContext.groupBy=\"cos_environment\" + additionalGroupBy=[\"cos_sub_account_id\",\"cos_service_name\"] → tree path environment → project → service.",
      +        "items": {
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "type": "array"
      +      },
      +      "aggBy": {
      +        "default": "Month",
      +        "description": "DIGEST time grain: Week or Month (default Month). Never Period (use TOP_FLOP for whole-period movers).",
      +        "enum": [
      +          "Week",
      +          "Month"
      +        ],
      +        "type": "string"
      +      },
      +      "compare": {
      +        "description": "Required only with explicit from/to when not using datePreset or reportContext. Prefer datePreset / reportContext.",
      +        "properties": {
      +          "from": {
      +            "description": "Comparison period start date.",
      +            "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"
      +          },
      +          "to": {
      +            "description": "Comparison period end date.",
      +            "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"
      +          }
      +        },
      +        "required": [
      +          "from",
      +          "to"
      +        ],
      +        "type": "object"
      +      },
      +      "datePreset": {
      +        "description": "Widget-level period override for scheduled DIGESTs (same DatePreset as dashboards, e.g. LAST_WEEK). Omit to inherit `reportContext.datePreset` / startDate/endDate. Mutually exclusive with explicit from/to/compare — do not set both.",
      +        "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"
      +      },
      +      "description": {
      +        "default": "",
      +        "type": "string"
      +      },
      +      "display": {
      +        "default": "tree",
      +        "description": "DIGEST presentation: \"tree\" (default, change tree only — faster), \"summary\" (LLM executive narrative — slower; opt-in AI summary), or \"table\" (flat table). Set \"summary\" when the user wants the AI write-up.",
      +        "enum": [
      +          "tree",
      +          "table",
      +          "summary"
      +        ],
      +        "type": "string"
      +      },
      +      "enableAiInvestigation": {
      +        "default": false,
      +        "description": "When true, deepest-leaf cost movers get per-node AI investigation before delivery (async analysis_agent_run — noticeably slower). Default false. Independent of display: \"summary\" (executive narrative). Prefer display: \"summary\" alone for a written overview; enable this only when the user wants deep node analysis.",
      +        "type": "boolean"
      +      },
      +      "from": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "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"
      +      },
      +      "minAbsoluteDiff": {
      +        "default": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "minRelativeDiff": {
      +        "default": 5,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "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 report widgets prefer sparse `{ type: \"cost\", name: \"a\", alias?, filterCel? }` and inherit metricId / currency / groupBy / period from `reportContext`. DIGEST: exactly one `{ type: \"cost\", ... }`. Call get_skill skillId: \"reports\" 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": {
      +        "default": "Cost changes",
      +        "type": "string"
      +      },
      +      "to": {
      +        "description": "Only for one-off custom ranges (YYYY-MM-DD). Omit to inherit report context. Do not set when datePreset is set.",
      +        "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"
      +      },
      +      "topLargestAbsoluteChange": {
      +        "default": 20,
      +        "description": "How many largest-absolute-change nodes to surface. Allowed values: 5, 10, 15, or 20.",
      +        "type": "number"
      +      },
      +      "type": {
      +        "const": "DIGEST",
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "type"
      +    ],
      +    "type": "object"
      +  }
      +]
  15. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare destructiveHint=true and openWorldHint=true; the description still adds material context: partial delivery is possible, archiving does not retract already-sent messages, new reports are creator-only with Admin, and DIGEST AI/"summary" display is noticeably slower. It also states what the call returns (report URL, nextRunAt, and for NOW the execution URLs plus per-destination status).

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

Conciseness3/5

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

Front-loaded correctly — purpose, trigger, and the danger-zone warnings come first — but it is extremely long and re-states schema detail verbatim (tag color default #6366F1, DIGEST display enum descriptions, topN/flopN defaults). The two full JSON examples are useful but push the block well past what an agent can absorb in one pass.

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 12-parameter, polymorphic-widget, delivery-capable mutation tool with no output schema, the description covers the dangerous modes, permission model, inheritance rules, per-widget type specifics, and return values. The few unmentioned parameters (context, llm_model, conversation_id) are analytics-only and self-documented in the schema.

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 100%, so the 3 baseline would apply, yet the description adds real semantics on top: reportContext is the inheritance source and widgets should only specify overrides, omit vs [] for tagIds both mean untagged, WEEKLY requires schedule.weekday with the 0=Sunday mapping, destination merging/sentinel rules, and the useDashboardGroupBy=false root-swap behavior. Two worked examples make the nesting concrete.

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

Purpose5/5

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

Opens with a specific verb+resource: "Save a Costory report with widgets, destinations, and a delivery schedule." It immediately scopes the tool to saved/scheduled reports, which separates it from preview_report_widget, run_report_now, and update_report without needing the schema.

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?

Explicit trigger ("Use when the user requests a saved or scheduled report"), explicit exclusions ("do not send PRIVATE/PUBLIC or teamId" — use set_object_permissions after create), mandatory prerequisite (get_skill "reports"), and a required confirmation step for the two sending modes. An agent knows both when to call it and what to do before calling.

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