Public log

@doitintl/doit-mcp-server

DoiT official MCP Server

npm · fingerprint 24c2a2ab792402c1659c922a · repository · RSS

241tools
7recorded versions
45dtracked
changed 2d ago

What changed

Changed 2026-10-15 11:23 UTC

1 schema or annotation change with the description left byte-identical.

--- pinned/async_run_inline
+++ observed/async_run_inline
  {
    "annotations": {
      "destructiveHint": true,
-             "description": "Limit by change filter. A report may configure at most two of\n`metricFilter`, `limitByChange`, and rank `group` limits — not all three.",
+             "description": "Limit by change filter; a report may configure at most two of `metricFilter`,\n`limitByChange` and rank `group` limits. Without `secondaryTimeRange` the change is\na period-over-period delta between adjacent time buckets. With it, each row's\nprimary-range total is compared with its secondary-range total, so column dimensions\n(`dimensions`, which `timeInterval` fills implicitly when omitted) only add buckets\nto those totals, while `group` gives every row its own change. A percentage change\nis comparable while both periods hold the same number of buckets; an absolute change\nis their plain difference and so scales with the bucket count. A row present in only\none range counts as zero there, so a percentage threshold cannot be met from zero. A\npercentage-typed custom metric, or count aggregation, is rejected with\n`LIMIT_BY_CHANGE_METRIC_NOT_ADDITIVE_WITH_SECONDARY`.",
              "properties": {
                "changeType": {
                  "enum": [

Changed 2026-10-09 13:08 UTC

1 description rewritten, 1 schema or annotation change with the description left byte-identical, 3 tools added.

+ tool added: assign_customer_group_user_group

--- pinned/async_run_inline
+++ observed/async_run_inline
  {
    "annotations": {
      "destructiveHint": true,
-             "description": "This option has no impact when reading reports via API.",
+             "description": "Orders the columns produced by `dimensions`, both in the console and in a rendered\n`fileOutput` export. It does not reorder the `rows` of a JSON result.\n`a_to_z` orders the columns by the dimension value, which for the `year`/`month`/`day`\ndimensions of a time series means chronologically. The default `desc` orders them by the\nmetric instead, so a monthly report charts its priciest month first rather than in time\norder — set `a_to_z` for a time series you intend to export.\nA report with a forecast is always charted chronologically and ignores this field, and a\ncomparative `displayValues` mode requires `a_to_z`.",
              "enum": [
                "asc",
                "desc",
-             "description": "This option has no impact when reading reports via API.",
+             "description": "Orders the rows produced by `group`, both in the console and in a rendered `fileOutput`\nexport. `a_to_z` orders them by the dimension value, `asc`/`desc` by the metric. It does\nnot reorder the `rows` of a JSON result.",
              "enum": [
                "asc",
                "desc",
--- pinned/delete_customer_group
+++ observed/delete_customer_group
  {
    "annotations": {
      "destructiveHint": true,
-   "description": "Manage explicit, named groups of downstream customers and the users scoped to them. Deletes a customer group owned by the authenticated tenant. Groups with assigned users cannot be deleted. Requires the UsersManager permission.",
+   "description": "Manage explicit, named groups of downstream customers and the users scoped to them. Deletes a customer group owned by the authenticated tenant. Groups with assigned users or user groups cannot be deleted. Requires the UsersManager permission.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,

+ tool added: list_customer_group_user_groups

+ tool added: unassign_customer_group_user_group

Changed 2026-10-07 13:12 UTC

94 descriptions rewritten, 16 schema or annotation changes with the description left byte-identical, 1 tool removed.

--- pinned/ask_ava_sync
+++ observed/ask_ava_sync
  {
    "_meta": {
      "openai/toolInvocation/invoked": "AVA responded",
-   "description": "Ask DoiT AVA, the cloud cost and infrastructure expert, a question about the user's DoiT account, cloud spending, anomalies, or optimization opportunities. AVA has access to the customer's billing data, usage patterns, and DoiT-specific features. Use this for DoiT or cloud-specific questions only — not for general-purpose AI queries. Note: AVA can take a long time to respond for complex questions. If it does not respond in time, a clear error is returned with guidance to retry or simplify the question.",
+   "description": "Ask DoiT AVA, DoiT's AI assistant for cloud cost and infrastructure, a question about the user's DoiT account, cloud spending, anomalies, or optimization opportunities. AVA has access to the customer's billing data, usage patterns, and DoiT-specific features. It answers DoiT and cloud-specific questions, not general-purpose ones. Complex questions may take a long time. Timeouts and application error envelopes (including HTTP 200) return MCP errors.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/assign_objects_to_label
+++ observed/assign_objects_to_label
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Assignments updated",
-   "description": "Use this when the user wants to assign or unassign cloud resources to a label. Ask the user to confirm the assignments before executing. Do NOT use this for creating labels (use create_label) or viewing assignments (use get_label_assignments).",
+   "description": "Use this when the user wants to assign or unassign DoiT console objects (reports, budgets, alerts, allocations, metrics or annotations) to a custom console label. Preset labels cannot be assigned. Requires edit permission on every object; validation is all-or-nothing. add/remove modify associations, not a replacement list. Changes apply immediately. Do NOT use this for creating labels (use create_label) or viewing assignments (use get_label_assignments).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/build_cloud_flow
+++ observed/build_cloud_flow
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow built",
-   "description": "Use this when the user wants to build a brand-new CloudFlow automation from scratch using natural language. Streams real-time progress while the AI builds the flow, then returns the newly created flow's ID, the builder's answer, and the build steps that ran. Use refine_cloudflow to change an existing flow; use this only to create a new one. Generated codeNode code is frequently broken in ways that pass validation and fail silently at run time. Always export_cloudflow_flow and test-run the result, and check the per-node output, before reporting success.",
+   "description": "Use this when the user wants to build a brand-new CloudFlow automation from scratch using natural language. Creates the draft before planning, so flowId can be returned even if the builder stops early. Streams progress and returns flowId, conversationId, the answer, and any build steps. Reusing conversationId continues the conversation but this endpoint still creates a new draft; refine_cloudflow targets an existing flow. Generated codeNode code can pass validation and fail silently or error at run time, so a successful build shows only that a draft was saved. export_cloudflow_flow returns the saved code; a completed test run's per-node output shows whether it works. Test runs execute real actions, including on drafts.",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "conversationId": {
          "description": "Optional conversation ID to continue an existing build session.",
--- pinned/compare_spend
+++ observed/compare_spend
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Spend comparison ready",
-   "description": "Use this when the user wants to compare spend between two time periods (e.g. 'Compare my costs this quarter vs last quarter', 'How did January compare to February?'). Period 1 is a rolling lookback; period 2 is an explicit date range. For more than two periods or advanced comparative analysis, use run_query instead.",
+   "description": "Use this when the user wants to compare spend between two time periods (e.g. 'Compare the latest three months including this month with January through March'). Period 1 is N-1 full calendar months plus current month-to-date; period 2 is an explicit date range. Returns two separate sets of monthly rows, each independently limited to its top 10 groups across that period. Groups can differ; no difference or percentage change is computed. For more than two periods or advanced comparative analysis, use run_query instead.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Dimension to group by (default \"service\").",
+         "description": "Grouping (default \"service\"): service = cloud service, project = project/account/subscription, cloud = cloud provider. Each period independently selects its top 10 groups.",
          "enum": [
            "service",
            "project",
-         "description": "How many months to look back for period 1 (default 3). Includes the current month.",
+         "description": "Period 1 covers N-1 full calendar months plus current month-to-date, 1–24 (default 3). It is not necessarily a calendar quarter.",
          "maximum": 24,
          "minimum": 1,
          "type": "integer"
-         "description": "The comparison period as an explicit date range.",
+         "description": "Comparison period as explicit inclusive UTC calendar dates in RFC3339 format.",
          "properties": {
            "from": {
-             "description": "Start date in RFC3339 format (e.g. '2025-01-01T00:00:00Z').",
+             "description": "Start timestamp in RFC3339 format, with Z or a UTC offset. The API uses the UTC calendar 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            },
            "to": {
-             "description": "End date in RFC3339 format (e.g. '2025-03-31T23:59:59Z').",
+             "description": "End timestamp in RFC3339 format, with Z or a UTC offset. The API includes this UTC calendar 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
              "type": "string"
            }
          },
--- pinned/confirm_action
+++ observed/confirm_action
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Action confirmed",
-   "description": "Finalizes a pending write action (e.g. creating, updating, or deleting a resource) that was previously staged by another tool. Only call this after the user has explicitly confirmed the action summary returned by the previous tool call. If the user declined, do not call this tool — the token will expire automatically. Pass the token exactly as it was returned.",
+   "description": "Runs a generated DELETE operation that another tool staged and returned as `status: \"approval_required\"` with a summary and a one-time approval token. Intended for use after the user approves that summary. A token that is never confirmed expires after 5 minutes, and the staged action does not run. The token is bound to the authenticated caller and must match exactly. An attempted confirmation consumes it even if the caller differs or execution fails. Creates and updates are not staged by the current tool registry.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "The approval token returned by a previous write/mutating tool call. Exactly as received, no quoting changes.",
+         "description": "The one-time, user-bound approval token returned by a staged generated DELETE call. Expires after five minutes. Exactly as received, no quoting changes.",
          "minLength": 1,
          "type": "string"
        }
--- pinned/cost_breakdown
+++ observed/cost_breakdown
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Cost breakdown ready",
-   "description": "Use this when the user wants a simple cost breakdown by service, project, or cloud provider (e.g. 'What are my top services by cost?', 'Which projects cost the most?'). Returns the top-N items ranked by cost descending. For complex multi-filter or multi-metric queries, use run_query instead.",
+   "description": "Use this when the user wants a simple cost breakdown by service, project, or cloud provider (e.g. 'What are my top services by cost?', 'Which projects cost the most?'). Selects the top-N groups by total cost across the range and returns monthly rows for each. The range includes the partial current month; months=1 means month-to-date. Output row order is not a cost ranking. For complex multi-filter or multi-metric queries, use run_query instead.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "How many months to look back (default 1). The current in-progress month is always included.",
+         "description": "Number of calendar months, 1–24 (default 1): N-1 complete months plus the current month-to-date. 1 means current month-to-date.",
          "maximum": 24,
          "minimum": 1,
          "type": "integer"
-         "description": "Number of top results to return (default 10, max 25).",
+         "description": "Top dimension values ranked across the range (default 10, max 25). Each value can have a row per month; this is not a row cap.",
          "maximum": 25,
          "minimum": 1,
          "type": "integer"
--- pinned/cost_trend
+++ observed/cost_trend
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Cost trend ready",
-   "description": "Use this when the user wants to see monthly spend over time (e.g. 'Show me my cost trend', 'How has my spend changed over the last 6 months?'). Returns monthly cost data points, optionally broken down by service/project/cloud. For daily granularity or custom time intervals, use run_query instead.",
+   "description": "Use this when the user wants to see monthly spend over time (e.g. 'Show me my cost trend', 'How has my spend changed over the last 6 months?'). Returns monthly cost data points, optionally broken down by service/project/cloud. The last point is the partial current month; months=1 means month-to-date. For daily granularity or custom time intervals, use run_query instead.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "How many months of history to include (default 6).",
+         "description": "Number of calendar months, 1–36 (default 6): N-1 complete months plus the partial current month-to-date.",
          "maximum": 36,
          "minimum": 1,
          "type": "integer"
-         "description": "When groupBy is set, limit to top-N groups by cost (default 5).",
+         "description": "When groupBy is set, select top-N groups by total cost across the range (default 5, max 25), not a row cap.",
          "maximum": 25,
          "minimum": 1,
          "type": "integer"
--- pinned/create_alert
+++ observed/create_alert
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Alert created",
-   "description": "Use this when the user wants to set up a new cost alert with thresholds and notification settings. Ask the user to confirm the alert parameters before executing. Do NOT use this for creating budgets (use create_budget) or viewing existing alerts (use list_alerts).",
+   "description": "Use this when the user wants to set up a new cost alert with thresholds and notification settings. Changes apply immediately. Do NOT use this for creating budgets (use create_budget) or viewing existing alerts (use list_alerts).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-             "description": "Condition type (e.g., 'value', 'forecasted', 'percentage').",
+             "description": "Condition type; defaults to percentage-change on create. Omitted on update means unchanged.",
+             "enum": [
+               "value",
+               "percentage-change",
+               "forecast"
+             ],
              "type": "string"
            },
            "currency": {
-             "description": "Currency code. Accepted values: USD, ILS, EUR, AUD, CAD, GBP, DKK, NOK, SEK, BRL, SGD, MXN, CHF, MYR, TWD, EGP, ZAR, JPY, IDR, AED, THB, COP.",
+             "description": "Currency code; defaults to the customer's currency on create, unchanged when omitted on update. Accepted values: USD, ILS, EUR, AUD, CAD, GBP, DKK, NOK, SEK, BRL, SGD, MXN, CHF, MYR, TWD, EGP, ZAR, JPY, IDR, AED, THB, COP.",
              "enum": [
                "USD",
                "ILS",
-             "description": "The data source for the alert (e.g., 'billing').",
+             "description": "Data source; defaults to billing on create. Omitted on update means unchanged.",
+             "enum": [
+               "billing",
+               "billing-datahub",
+               "kubernetes-utilization",
+               "tokenomics"
+             ],
              "type": "string"
            },
            "evaluateForEach": {
-             "description": "The metric to evaluate (required). Object with 'type' and 'value' fields.",
+             "description": "The metric to evaluate; required on create. Object with 'type' and 'value' fields.",
              "properties": {
                "type": {
                  "description": "Metric type identifier (e.g., 'basic', 'custom', 'extended').",
-             "description": "Filters that define the scope of the alert.",
+             "description": "Filters that define the scope of the alert. On update, omit to preserve; [] clears the scopes.",
              "items": {
                "additionalProperties": false,
                "properties": {
-                   "description": "Filter mode. Accepted values: is, starts_with, ends_with, contains, regexp.",
+                   "description": "Filter mode; defaults to 'is' at the API. Accepted values: is, starts_with, ends_with, contains, regexp.",
                    "enum": [
                      "is",
                      "starts_with",
-                 "type",
-                 "mode"
+                 "type"
                ],
                "type": "object"
              },
-             "description": "The time interval to evaluate the condition (required). Accepted values: hour, day, week, month, quarter, year.",
+             "description": "The time interval to evaluate the condition; required on create. Accepted values: day, week, month, quarter, year.",
              "enum": [
-               "hour",
                "day",
                "week",
                "month",
-             "description": "The alert threshold value (required).",
+             "description": "The alert threshold value; required on create.",
              "type": "number"
            }
          },
-           "value"
+           "value",
+           "operator"
          ],
          "type": "object"
        },
-         "description": "Alert name (required, non-empty).",
+         "description": "Alert name (required, 1–64 characters).",
+         "maxLength": 64,
          "minLength": 1,
          "type": "string"
        },
-         "description": "List of email addresses to notify when the alert is triggered.",
+         "description": "Email addresses to notify when triggered. On create, defaults to the caller's email; omitted on update preserves recipients. The API requires at least one email or existing Slack destination.",
          "items": {
            "format": "email",
            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
--- pinned/create_allocation
+++ observed/create_allocation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Allocation created",
-   "description": "Use this when the user wants to create a new cost allocation rule. Ask the user to confirm the allocation parameters before executing. Do NOT use this for viewing existing allocations (use list_allocations) or labels (use create_label).",
+   "description": "Use this when the user wants to create a new cost allocation rule. Changes apply immediately. Do NOT use this for viewing existing allocations (use list_allocations) or labels (use create_label).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "description": {
-         "description": "Description of the allocation's purpose",
+         "description": "Description of the allocation. On update omission or an empty string preserves the stored description; the API does not support clearing it",
          "type": "string"
        },
        "name": {
+         "minLength": 1,
          "type": "string"
        },
        "rule": {
+         "additionalProperties": false,
          "description": "A single allocation rule that defines one grouping. Provide this for a single-rule allocation. Mutually exclusive with 'rules'",
          "properties": {
            "components": {
+               "additionalProperties": false,
                "properties": {
                  "include_null": {
                    "description": "If true, include resources with no value for this dimension",
-                   "description": "Key of an existing dimension, label, or tag key",
+                   "description": "Key of an existing dimension, label or tag. For type allocation_rule, use key allocation_rule and existing rule IDs as values",
                    "type": "string"
                  },
                  "mode": {
-                   "description": "The matching mode for values",
+                   "description": "Required matching mode; regexp requires exactly one pattern in values and a dimension that supports regular expressions",
                    "enum": [
                      "is",
                      "contains",
-                     "ends_with"
+                     "ends_with",
+                     "regexp"
                    ],
                    "type": "string"
                  },
-                     "attribution_group",
+                     "allocation_rule",
                      "gke",
                      "gke_label"
                    ],
-             "description": "Logical formula combining components (e.g., 'A AND B')",
+             "description": "Logical formula combining components by array order: A is the first component, B the second (e.g., 'A AND B')",
              "type": "string"
            }
          },
+         "required": [
+           "components",
+           "formula"
+         ],
          "type": "object"
        },
        "rules": {
-         "description": "Ordered list of allocation rules for a group allocation. Must include at least two rules. Mutually exclusive with 'rule'",
+         "description": "Ordered list of at least two group rules. create creates a rule, update edits a rule, select includes it unchanged. On update this replaces the entire list; include every rule to retain. Mutually exclusive with rule; allocation type cannot change",
          "items": {
-           "properties": {
-             "action": {
-               "description": "Required action for this rule (e.g., 'create', 'update', 'select')",
-               "enum": [
-                 "create",
-                 "update",
-                 "select"
-               ],
-               "type": "string"
-             },
-             "components": {
-               "description": "Array of allocation components that define this rule",
-               "items": {
-                 "properties": {
-                   "include_null": {
-                     "description": "If true, include resources with no value for this dimension",
-                     "type": "boolean"
-                   },
-                   "inverse_selection": {
-                     "description": "If true, exclude matching values instead of including them",
-                     "type": "boolean"
-                   },
-                   "key": {
-                     "description": "Key of an existing dimension, label, or tag key",
-                     "type": "string"
-                   },
-                   "mode": {
-                     "description": "The matching mode for values",
-                     "enum": [
-                       "is",
-                       "contains",
-                       "starts_with",
-                       "ends_with"
+           "oneOf": [
+             {
+               "additionalProperties": false,
+               "properties": {
+                 "action": {
+                   "const": "create",
+                   "description": "Create a new rule and include it in the group; omit id.",
+                   "type": "string"
+                 },
+                 "components": {
+                   "description": "Array of allocation components that define this rule",
+                   "items": {
+                     "additionalProperties": false,
+                     "properties": {
+                       "include_null": {
+                         "description": "If true, include resources with no value for this dimension",
+                         "type": "boolean"
+                       },
+                       "inverse_selection": {
+                         "description": "If true, exclude matching values instead of including them",
+                         "type": "boolean"
+                       },
+                       "key": {
+                         "description": "Key of an existing dimension, label or tag. For type allocation_rule, use key allocation_rule and existing rule IDs as values",
+                         "type": "string"
+                       },
+                       "mode": {
+                         "description": "Required matching mode; regexp requires exactly one pattern in values and a dimension that supports regular expressions",
+                         "enum": [
+                           "is",
+                           "contains",
+                           "starts_with",
+                           "ends_with",
+                           "regexp"
+                         ],
+                         "type": "string"
+                       },
+                       "type": {
+                         "description": "The type of the component",
+                         "enum": [
+                           "datetime",
+                           "fixed",
+                           "optional",
+                           "label",
+                           "tag",
+                           "project_label",
+                           "system_label",
+                           "attribution",
+                           "allocation_rule",
+                           "gke",
+                           "gke_label"
+                         ],
+                         "type": "string"
+                       },
+                       "values": {
+                         "description": "Values to match against",
+                         "items": {
+                           "type": "string"
+                         },
+                         "type": "array"
+                       }
+                     },
+                     "required": [
+                       "key",
+                       "type",
+                       "values",
+                       "mode"
                      ],
-                     "type": "string"
+                     "type": "object"
                    },
-                   "type": {
-                     "description": "The type of the component",
-                     "enum": [
-                       "datetime",
-                       "fixed",
-                       "optional",
-                       "label",
-                       "tag",
-                       "project_label",
-                       "system_label",
-                       "attribution",
-                       "attribution_group",
-                       "gke",
-                       "gke_label"
+                   "type": "array"
+                 },
+                 "description": {
+                   "description": "Description of the new rule.",
+                   "type": "string"
+                 },
+                 "formula": {
+                   "description": "Logical formula combining components by array order: A is the first component, B the second (e.g., 'A AND B')",
+                   "type": "string"
+                 },
+                 "id": {
+                   "description": "Must be absent for create.",
+                   "not": {}
+                 },
+                 "name": {
+                   "description": "Required name for the new rule.",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "components",
+                 "formula",
+                 "action",
+                 "name"
+               ],
+               "type": "object"
+             },
+             {
+               "additionalProperties": false,
+               "properties": {
+                 "action": {
+                   "const": "update",
+                   "description": "Update an existing rule and include it in the group.",
+                   "type": "string"
+                 },
+                 "components": {
+                   "description": "Array of allocation components that define this rule",
+                   "items": {
+                     "additionalProperties": false,
+                     "properties": {
+                       "include_null": {
+                         "description": "If true, include resources with no value for this dimension",
+                         "type": "boolean"
+                       },
+                       "inverse_selection": {
+                         "description": "If true, exclude matching values instead of including them",
+                         "type": "boolean"
+                       },
+                       "key": {
+                         "description": "Key of an existing dimension, label or tag. For type allocation_rule, use key allocation_rule and existing rule IDs as values",
+                         "type": "string"
+                       },
+                       "mode": {
+                         "description": "Required matching mode; regexp requires exactly one pattern in values and a dimension that supports regular expressions",
+                         "enum": [
+                           "is",
+                           "contains",
+                           "starts_with",
+                           "ends_with",
+                           "regexp"
+                         ],
+                         "type": "string"
+                       },
+                       "type": {
+                         "description": "The type of the component",
+                         "enum": [
+                           "datetime",
+                           "fixed",
+                           "optional",
+                           "label",
+                           "tag",
+                           "project_label",
+                           "system_label",
+                           "attribution",
+                           "allocation_rule",
+                           "gke",
+                           "gke_label"
+                         ],
+                         "type": "string"
+                       },
+                       "values": {
+                         "description": "Values to match against",
+                         "items": {
+                           "type": "string"
+                         },
+                         "type": "array"
+                       }
+                     },
+                     "required": [
+                       "key",
+                       "type",
+                       "values",
+                       "mode"
                      ],
-                     "type": "string"
+                     "type": "object"
                    },
-                   "values": {
-                     "description": "Values to match against",
-                     "items": {
-                       "type": "string"
-                     },
-                     "type": "array"
-                   }
+                   "type": "array"
                  },
-                 "required": [
-                   "key",
-                   "type",
-                   "values",
-                   "mode"
-                 ],
-                 "type": "object"
+                 "description": {
+                   "description": "Description of the updated rule.",
+                   "type": "string"
+                 },
+                 "formula": {
+                   "description": "Logical formula combining components by array order: A is the first component, B the second (e.g., 'A AND B')",
+                   "type": "string"
+                 },
+                 "id": {
+                   "description": "Required ID of the existing rule to update.",
+                   "minLength": 1,
+                   "type": "string"
+                 },
+                 "name": {
+                   "description": "New name for the updated rule; omit to preserve its name.",
+                   "minLength": 1,
+                   "type": "string"
+                 }
                },
-               "type": "array"
-             },
-             "description": {
-               "description": "Description of the rule",
-               "type": "string"
-             },
-             "formula": {
-               "description": "Logical formula combining components (e.g., 'A AND B')",
-               "type": "string"
-             },
-             "id": {
-               "description": "Rule ID (for existing rules), required for 'update' and 'select' actions",
-               "type": "string"
+               "required": [
+                 "components",
+                 "formula",
+                 "action",
+                 "id"
+               ],
+               "type": "object"
              },
-             "name": {
-               "description": "Name of the rule",
-               "type": "string"
+             {
+               "additionalProperties": false,
+               "properties": {
+                 "action": {
+                   "const": "select",
+                   "description": "Include an existing rule unchanged; only id is needed.",
+                   "type": "string"
+                 },
+                 "id": {
+                   "description": "Required ID of the existing rule to select.",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "action",
+                 "id"
+               ],
+               "type": "object"
              }
-           },
-           "type": "object"
+           ]
          },
+         "minItems": 2,
          "type": "array"
        },
        "unallocatedCosts": {
-         "description": "Custom label for values that do not fit into any allocation rule (required when using 'rules' for group allocations)",
+         "description": "Group-only label for unmatched costs. On update omission or null preserves the stored label; a string updates it independently of rules",
          "type": [
            "string",
            "null"
-       "name",
-       "description"
+       "name"
      ],
      "type": "object"
    },
--- pinned/create_annotation
+++ observed/create_annotation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Annotation created",
-   "description": "Use this when the user wants to add a new annotation to mark a specific date or event in cost data. Ask the user to confirm the annotation details before executing. Do NOT use this for creating labels (use create_label) or alerts (use create_alert).",
+   "description": "Use this when the user wants to add a new annotation to mark a specific date or event in cost data. Changes apply immediately. Do NOT use this for creating labels (use create_label) or alerts (use create_alert).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "The date associated with the annotation in ISO 8601 date-time format (required).",
-         "format": "date-time",
+         "allOf": [
+           {
+             "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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
+           },
+           {
+             "pattern": "T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$"
+           }
+         ],
+         "description": "Required RFC 3339 timestamp with seconds and a timezone: Z or ±HH:MM (e.g. 2026-01-15T00:00:00Z). Fractional seconds are supported.",
          "minLength": 1,
-         "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"
        }
      },
--- pinned/create_budget
+++ observed/create_budget
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Budget created",
-   "description": "Use this when the user wants to create a new cloud budget with spending limits and alert thresholds. Requires budget name, currency, type, and start period. Ask the user to confirm the budget parameters before executing. Do NOT use this for viewing existing budgets (use list_budgets or get_budget) or creating alerts (use create_alert).",
+   "description": "Use this when the user wants to create a new cloud budget with spending limits and alert thresholds. Requires name, currency, type, startPeriod, and exactly one of scope/scopes. Requires amount unless usePrevSpend is true, endPeriod for fixed budgets, and timeInterval for recurring budgets (ignored for fixed). Changes apply immediately. Do NOT use this for viewing existing budgets (use list_budgets or get_budget) or creating alerts (use create_alert).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Budget period amount. Required if usePrevSpend is false.",
+         "description": "Budget period amount. Required unless usePrevSpend is true.",
          "exclusiveMinimum": 0,
          "type": "number"
        },
-         "description": "Budget start date as a UNIX timestamp in milliseconds (required).",
+         "description": "Budget start date as a UNIX timestamp in milliseconds (required, on or after 2018-01-01 UTC).",
          "maximum": 9007199254740991,
-         "minimum": -9007199254740991,
+         "minimum": 1514764800000,
          "type": "integer"
        },
        "timeInterval": {
-         "description": "Recurring budget interval. Required for recurring budgets. Accepted values: day, week, month, quarter, year.",
+         "description": "Recurring budget interval. Required for recurring budgets; ignored for fixed budgets. Accepted values: day, week, month, quarter, year.",
          "enum": [
            "day",
            "week",
--- pinned/create_cloudflow_connection
+++ observed/create_cloudflow_connection
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow connection created",
-   "description": "Use this when the user wants to create a new CloudFlow cloud provider connection (a GCP or AWS account connected for automation). Exactly one of gcpConfig or awsConfig must be supplied. Ask the user to confirm the connection details before executing. Do NOT use this to update an existing connection (use update_cloudflow_connection) or to trigger a flow (use trigger_cloud_flow).",
+   "description": "Use this when the user wants to create a new CloudFlow cloud provider connection (a GCP or AWS account connected for automation). Exactly one of gcpConfig or awsConfig must be supplied. Changes apply immediately. Do NOT use this to update an existing connection (use update_cloudflow_connection) or to trigger a flow (use trigger_cloud_flow).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
+       "idempotencyKey": {
+         "description": "Idempotency-Key for this create attempt. Reuse the same key and body for retries within 24 hours; a different body with the same key fails with 422, an in-progress request with 409. A new key starts a separate create. The API fingerprints MCP tracking parameters; a changed client/server version can cause a same-key conflict. Keep the original request context and key. If an HTTP failure has only generic text, do not infer a status or retry automatically.",
+         "minLength": 1,
+         "pattern": "^[\\x21-\\x7e]+$",
+         "type": "string"
+       },
        "name": {
          "description": "Human-readable connection name (required, non-empty).",
          "minLength": 1,
+       "idempotencyKey",
        "name"
      ],
      "type": "object"
--- pinned/create_datahub_dataset
+++ observed/create_datahub_dataset
  {
    "_meta": {
      "openai/toolInvocation/invoked": "DataHub dataset created",
-   "description": "Use this when the user wants to create a new DataHub dataset. Ask the user to confirm the dataset name and description before executing. Do NOT use this for viewing datasets (use list_datahub_datasets) or sending events (use send_datahub_events).",
+   "description": "Use this when the user wants to create a new DataHub dataset. Changes apply immediately. Do NOT use this for viewing datasets (use list_datahub_datasets) or sending events (use send_datahub_events).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/create_folder
+++ observed/create_folder
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Folder created",
-   "description": "Use this when the user wants to create a new Cloud Analytics folder to organize reports and allocations. Ask the user to confirm the folder details before executing. Do NOT use this for creating reports (use create_report) or labels (use create_label).",
+   "description": "Use this when the user wants to create a new Cloud Analytics folder to organize reports and allocations. A duplicate sibling name or invalid parent is rejected. Changes apply immediately. Do NOT use this for creating reports (use create_report) or labels (use create_label).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/create_label
+++ observed/create_label
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Label created",
-   "description": "Use this when the user wants to create a new resource label. Ask the user to confirm the label details before executing. Do NOT use this for viewing existing labels (use list_labels) or annotations (use create_annotation).",
+   "description": "Use this when the user wants to create a new DoiT console label for organizing analytics objects. Names must be unique within the customer. Requires Cloud Analytics Admin. Changes apply immediately. Do NOT use this for viewing existing labels (use list_labels) or annotations (use create_annotation).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/create_report
+++ observed/create_report
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Report created",
-   "description": "Use this when the user wants to save a new Cloud Analytics report with a specific configuration. Ask the user to confirm the report parameters before executing. Do NOT use this for one-time queries without saving (use run_query).",
+   "description": "Use this when the user wants to save a new Cloud Analytics report with a specific configuration. Creates a new custom report immediately without replacing existing reports. Omitted config fields take API defaults: basic cost, last 7 days including today, daily time rows, and billing (or billing-datahub when the customer has DataHub metrics). System labels are rejected. Do NOT use this for one-time queries without saving (use run_query).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Configuration for the report. Use the dimension tool to look up valid dimension IDs.",
+         "description": "Configuration for the report. Valid dimension IDs come from list_dimensions or get_dimension.",
          "properties": {
            "advancedAnalysis": {
              "additionalProperties": false,
-             "description": "Custom time range. Only use when timeRange mode is 'custom'.",
+             "description": "Explicit dates, alongside timeRange (not nested inside it). Required for new custom queries/reports and when switching a saved relative report to custom mode. On update, omitted dates can reuse valid stored custom dates; omitted timeRange requires a stored custom mode. The API uses inclusive UTC calendar days.",
              "properties": {
                "from": {
-                 "description": "Start timestamp in RFC3339 format. Example: '2024-03-10T23:00:00Z'.",
+                 "description": "Start timestamp in RFC3339 format, with Z or a UTC offset. The API uses the UTC calendar 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "type": "string"
                },
                "to": {
-                 "description": "End timestamp in RFC3339 format. Example: '2024-03-12T23:00:00Z'.",
+                 "description": "End timestamp in RFC3339 format, with Z or a UTC offset. The API includes this UTC calendar 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "type": "string"
                }
              },
-             "description": "Data source for the report. Accepted values: billing, bqlens, billing-datahub, kubernetes-utilization.",
+             "description": "Data source; defaults to billing, or billing-datahub when the customer has DataHub metrics. Accepted values: billing, bqlens, billing-datahub, kubernetes-utilization.",
              "enum": [
                "billing",
                "bqlens",
-                   "description": "Dimension identifier. Use the dimension tool to get valid IDs.",
+                   "description": "Dimension identifier. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "type": {
-                   "description": "The field to filter on. Use the dimension tool to get valid IDs.",
+                   "description": "The field to filter on. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "inverse": {
-                   "description": "Filter match mode. Accepted values: is, starts_with, ends_with, contains, regexp.",
+                   "description": "Filter match mode. Defaults to 'is' (exact match). Accepted values: is, starts_with, ends_with, contains, regexp.",
                    "enum": [
                      "is",
                      "starts_with",
-                   "description": "Values to filter on.",
+                   "description": "Stored dimension values to match exactly in 'is' mode (case-sensitive): provider IDs for cloud_provider, service names for service_description. get_dimension returns available values.",
                    "items": {
                      "type": "string"
                    },
-                 "type",
-                 "mode"
+                 "type"
                ],
                "type": "object"
              },
-                   "description": "Dimension ID for the group-by row. Use the dimension tool to get valid IDs.",
+                   "description": "Dimension ID for the group-by row. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "limit": {
-                   "description": "Limit to top/bottom N results.",
+                   "description": "Select top/bottom N values of this dimension per parent group, ranked across the query range. Time dimensions still split result rows.",
                    "properties": {
                      "metric": {
                        "additionalProperties": false,
-                       "description": "Number of items to show.",
+                       "description": "Number of dimension values to select per parent group, not a cap on returned rows; time dimensions can produce multiple rows per selected value.",
                        "maximum": 9007199254740991,
                        "minimum": -9007199254740991,
                        "type": "integer"
-             "description": "Report layout / visualization type. Accepted values: column_chart, stacked_column_chart, bar_chart, stacked_bar_chart, line_chart, spline_chart, area_chart, area_spline_chart, stacked_area_chart, treemap_chart, table, table_heatmap, table_row_heatmap, table_col_heatmap, csv_export, sheets_export.",
+             "description": "Report layout / visualization type. Accepted values: column_chart, stacked_column_chart, bar_chart, stacked_bar_chart, line_chart, spline_chart, area_chart, area_spline_chart, stacked_area_chart, treemap_chart, table, table_heatmap, table_row_heatmap, table_col_heatmap, sankey_chart, column_and_line_chart, trend_board, cumulative_comparison.",
              "enum": [
                "column_chart",
                "stacked_column_chart",
-               "csv_export",
-               "sheets_export"
+               "sankey_chart",
+               "column_and_line_chart",
+               "trend_board",
+               "cumulative_comparison"
              ],
              "type": "string"
            },
-             "description": "List of metrics to apply (max 4). Preferred over the deprecated 'metric' field.",
+             "description": "List of metrics to apply (max 4). Defaults to basic cost on new reports/queries. Non-empty arrays replace stored metrics on update; [] leaves metrics unchanged. Preferred over the deprecated 'metric' field.",
              "items": {
                "additionalProperties": false,
                "properties": {
-             "description": "Time interval for grouping data. Accepted values: hour, day, dayCumSum, week, isoweek, month, quarter, year, week_day.",
+             "description": "Time interval for grouping data (default day). On update, supplying this with dimensions omitted resets time columns to this interval. Accepted values: hour, day, dayCumSum, week, isoweek, month, quarter, year, week_day.",
              "enum": [
                "hour",
                "day",
-             "description": "Time range for the report. Preferred over customTimeRange.",
+             "description": "Time range; defaults to the last 7 days including today on new reports/queries. For custom dates use {mode: 'custom'} and sibling config.customTimeRange.",
              "properties": {
                "amount": {
-                 "description": "Number of time units (0–5000). Required when mode is 'last'.",
+                 "description": "Number of calendar periods (0–5000). Required for 'last'.",
                  "maximum": 5000,
                  "minimum": 0,
                  "type": "integer"
-               "customTimeRange": {
-                 "additionalProperties": false,
-                 "description": "Custom date range. Required when mode is 'custom'.",
-                 "properties": {
-                   "from": {
-                     "description": "Start date in RFC3339 format.",
-                     "type": "string"
-                   },
-                   "to": {
-                     "description": "End date in RFC3339 format.",
-                     "type": "string"
-                   }
-                 },
-                 "required": [
-                   "from",
-                   "to"
-                 ],
-                 "type": "object"
-               },
                "includeCurrent": {
-                 "description": "Whether to include the current (in-progress) period.",
+                 "description": "For 'last', true includes the current partial period in amount; false (default) selects completed periods. With amount 1 and unit month, true means month-to-date and false means the previous full month. Ignored for 'current' and 'custom'.",
                  "type": "boolean"
                },
                "mode": {
-                 "description": "Time range mode. Accepted values: last, current, custom. Use 'custom' with customTimeRange for specific dates.",
+                 "description": "Time range mode: 'last' selects N calendar periods; 'current' selects the current calendar period through its end; 'custom' requires dates in config.customTimeRange, alongside timeRange.",
                  "enum": [
                    "last",
                    "current",
-                 "description": "Time unit. Accepted values: day, week, month, quarter, year. Required when mode is 'last'.",
+                 "description": "Time unit. Accepted values: day, week, month, quarter, year. Required for 'last' and 'current'; forbidden for 'custom'.",
                  "enum": [
                    "day",
                    "week",
-         "description": "Optional list of label IDs to assign to the report.",
+         "description": "Optional DoiT console label IDs to assign. System labels are rejected.",
          "items": {
            "type": "string"
          },
--- pinned/create_ticket
+++ observed/create_ticket
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Ticket created",
-   "description": "Use this when the user wants to create a new support ticket. Ask the user to confirm the ticket details before executing. Do NOT use this for viewing existing tickets (use list_tickets) or cloud incidents (use get_cloud_incidents).",
+   "description": "Use this when the user wants to create a new support ticket. The ticket is opened with DoiT support immediately. Do NOT use this for viewing existing tickets (use list_tickets) or cloud incidents (use get_cloud_incidents).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "ticket": {
+         "additionalProperties": false,
          "properties": {
            "body": {
              "description": "The body of the ticket (can include html formatting)",
-             "description": "Ticket create time",
+             "description": "Deprecated compatibility field. Ignored; the server sets the ticket creation time.",
              "type": "string"
            },
            "platform": {
-             "description": "Platform of the ticket",
+             "description": "Support platform ID from list_platforms (id), rather than an asset type or display name.",
              "enum": [
                "cloud_management_platform",
                "google_cloud_platform",
-               "perfectscale"
+               "perfectscale",
+               "finance___billing",
+               "credits___request"
              ],
              "type": "string"
            },
-             "description": "Ticket product details",
+             "description": "Support product displayName from list_products for the selected platform, e.g. Invoice Management. Forwarded unchanged to the API; routing depends on the display name, not the catalog id.",
              "type": "string"
            },
            "severity": {
-             "description": "Ticket severity",
+             "description": "Ticket severity: low, normal, high, or urgent.",
              "enum": [
                "low",
                "normal",
-           "created",
            "platform",
            "product",
            "severity",
--- pinned/export_cloudflow_flow
+++ observed/export_cloudflow_flow
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Manage CloudFlow. Serializes the flow — plus every flow it references through subflow nodes — into a\ntenant-neutral, credential-free JSON bundle that can be imported into any tenant with\nthe import operation. Tenant-scoped references (connections, Datastore tables, global\nvariables) are declared as named requirements and rebound at import time; policy and\nSlack-channel references cannot travel and are recorded as unsupported references.\nThe bundle never contains credentials, tenant identifiers, schedules, or execution state. codeNode contract: upstream data comes only from `nodes[\"<node name>\"]` (a dict of lists); the code body must end in a top-level `return`; `schema` is required. Code that defines an uncalled function, reads a bare `input`, or assigns `output` completes with `{message: null}` — no error, no result.",
+   "description": "Manage CloudFlow. Serializes the flow — plus every flow it references through subflow nodes — into a\ntenant-neutral, credential-free JSON bundle that can be imported into any tenant with\nthe import operation. Tenant-scoped references (connections, Datastore tables, global\nvariables) are declared as named requirements and rebound at import time; policy and\nSlack-channel references cannot travel and are recorded as unsupported references.\nThe bundle never contains credentials, tenant identifiers, schedules, or execution state. codeNode: JavaScript (default) uses $nodes[\"<node name>\"] and $variables; Python uses nodes and variables. Upstream values are lists. A top-level return produces {message: value}; no return gives JS {} / Python {message: null}. Bare input is not injected; accessing it as upstream data fails the node. A schema (JSON Schema string) is required.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/export_datahub_dataset_records
+++ observed/export_datahub_dataset_records
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Ingest third-party cost, usage, and metric-based data for analysis. Returns one page of the live records of a DataHub dataset, as CSV (default) or as newline-delimited JSON in the same shape as the `/datahub/v1/events` payload.\n\nA time window is required: `startTime` is inclusive, `endTime` is exclusive, and the window must not exceed 366 days. Rows are ordered by their event time and event id, and pages never overlap: read the `X-Next-Page-Token` response header and pass it back as `pageToken` until the header is absent. `X-Row-Count` carries the number of rows in the page. Only live rows are returned; rows deleted through the console or the delete endpoints are excluded.\n\nEvery row starts with five provenance columns (`event_id`, `batch`, `source`, `export_time`, `updated_by`) followed by the dataset's business columns in the CSV ingest vocabulary (`usage_date`, `fixed.<key>`, `label.<key>`, `project_label.<key>`, `system_label.<key>`, `metric.<type>`). The business columns are computed from the rows of each page, so consecutive pages can have different label and metric columns; union the headers when concatenating pages. Datasets created with the FOCUS schema template use the FOCUS column names instead and can only be exported as CSV.\n\nTo re-import an export into another dataset, drop the `batch`, `source`, `export_time` and `updated_by` columns, and either drop `event_id` or rename it to `id`. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Ingest third-party cost, usage, and metric-based data for analysis. Returns one page of the live records of a DataHub dataset, as CSV (default) or as newline-delimited JSON in the same shape as the `/datahub/v1/events` payload.\n\nA time window is required: `startTime` is inclusive, `endTime` is exclusive, and the window must not exceed 366 days. Rows are ordered by their event time and event id, and pages never overlap: read the `X-Next-Page-Token` response header and pass it back as `pageToken` until the header is absent. `X-Row-Count` carries the number of rows in the page. Only live rows are returned; rows deleted through the console or the delete endpoints are excluded.\n\nEvery row starts with five provenance columns (`event_id`, `batch`, `source`, `export_time`, `updated_by`) followed by the dataset's business columns in the CSV ingest vocabulary (`usage_date`, `fixed.<key>`, `label.<key>`, `project_label.<key>`, `system_label.<key>`, `metric.<type>`). The business columns are computed from the rows of each page, so consecutive pages can have different label and metric columns; union the headers when concatenating pages. Datasets created with the FOCUS schema template use the FOCUS column names instead and can only be exported as CSV.\n\nTo re-import an export into another dataset, drop the `batch`, `source`, `export_time` and `updated_by` columns, and either drop `event_id` or rename it to `id`. This tool returns a JSON envelope with data (the unchanged CSV or JSONL page body) and pageToken (from X-Next-Page-Token). Pass a non-empty pageToken back as pageToken to advance; null means the final page. MCP does not expose the HTTP headers directly.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/find_cloud_diagrams
+++ observed/find_cloud_diagrams
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagrams found",
-     "destructiveHint": false,
+     "destructiveHint": true,
      "openWorldHint": true,
-     "readOnlyHint": true
+     "readOnlyHint": false
    },
    "coversEndpoint": "post:/clouddiagrams/v1/scheme/find",
-   "description": "Use this when the user wants to find architecture diagrams or cloud infrastructure diagrams. Returns matching diagram files. Do NOT use this for cost analysis (use run_query) or incidents (use get_cloud_incidents).",
+   "description": "Use this when the user wants to find architecture diagrams or cloud infrastructure diagrams. Matches cloud resource IDs (cld_id or props.id) and returns diagram viewer URLs and image URLs. Creates a sheet filter and queues image rendering. Do NOT use this for cost analysis (use run_query) or incidents (use get_cloud_incidents).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Resource IDs to find diagrams for.",
+         "description": "Cloud resource IDs matched against cld_id or props.id; these are not diagram component IDs.",
          "items": {
            "type": "string"
          },
--- pinned/get_active_theme
+++ observed/get_active_theme
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Active theme loaded",
-   "description": "Use this when the user wants to know which color theme is currently active for their account (the theme applied to Cloud Analytics reports). Returns the active theme id; the reserved sentinel \"default\" means no custom or preset theme is selected and the built-in default is in use. Do NOT use this to list all themes (use list_themes) or to fetch a specific theme by id (use get_theme).",
+   "description": "Use this when the user wants to know which color theme is currently active for the authenticated user (the theme applied to Cloud Analytics reports). Returns the active theme id; the reserved sentinel \"default\" means no custom or preset theme is selected and the built-in default is in use. Do NOT use this to list all themes (use list_themes) or to fetch a specific theme by id (use get_theme).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/get_alert
+++ observed/get_alert
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Alert details loaded",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "The ID of the alert to retrieve.",
-         "description": "Partial name match (case-insensitive). Used to find the alert when ID is unknown.",
+         "description": "Case-insensitive partial name lookup in the 200 most recent alerts only. Multiple matches return an ambiguity error. ID takes precedence.",
          "type": "string"
        }
      },
--- pinned/get_allocation
+++ observed/get_allocation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Allocation loaded",
-   "description": "Use this when the user wants to view details of a specific cost allocation. Accepts either the allocation ID or a partial name (case-insensitive). Do NOT use this for listing all allocations (use list_allocations) or running queries (use run_query).",
+   "description": "Use this when the user wants to view details of a specific cost allocation. Accepts either the allocation ID or a case-insensitive partial name. Name lookup searches only the first 200 allocations; multiple matches return an error listing names, and id takes precedence. Do NOT use this for listing all allocations (use list_allocations) or running queries (use run_query).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "The ID of the allocation to retrieve.",
-         "description": "Partial name match (case-insensitive). Used to find the allocation when ID is unknown.",
+         "description": "Case-insensitive substring search of only the first 200 allocations. Multiple matches return an ambiguity error listing names; id takes precedence.",
          "type": "string"
        }
      },
--- pinned/get_annotation
+++ observed/get_annotation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Annotation loaded",
-   "description": "Use this when the user wants to view details of a specific annotation. Accepts either the annotation ID or a partial content match (case-insensitive). Do NOT use this for listing all annotations (use list_annotations) or labels (use list_labels).",
+   "description": "Use this when the user wants to view details of a specific annotation. Accepts either the annotation ID or a partial content match (case-insensitive) within the first 200 annotations. Multiple matches return an ambiguity error listing content; id takes precedence. Do NOT use this for listing all annotations (use list_annotations) or labels (use list_labels).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "content": {
-         "description": "Partial content match (case-insensitive). Used to find the annotation when ID is unknown.",
+         "description": "Case-insensitive substring search of only the first 200 annotations. Multiple matches return an ambiguity error listing content; id takes precedence.",
          "type": "string"
        },
        "id": {
--- pinned/get_anomalies
+++ observed/get_anomalies
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Anomaly check complete",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "pageToken": {
-         "description": "Token for pagination. Use this to get the next page of results.",
+         "description": "Token for pagination, from a previous response; returns the next page of results.",
          "type": "string"
        }
      },
--- pinned/get_anomaly
+++ observed/get_anomaly
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Anomaly details loaded",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "anomaly ID",
--- pinned/get_asset
+++ observed/get_asset
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Asset details loaded",
-   "description": "Use this when the user wants to view details of a specific cloud asset. Accepts either the asset ID or a partial name (case-insensitive). Do NOT use this for listing all assets (use list_assets) or cost analysis (use run_query).",
+   "description": "Use this when the user wants to view details of a specific cloud asset. Accepts an asset ID, which takes precedence over name, or a case-insensitive partial name lookup within the first 249 assets only. Multiple name matches return an ambiguity error. Do NOT use this for listing all assets (use list_assets) or cost analysis (use run_query).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
-         "description": "The ID of the asset to retrieve.",
+         "description": "The ID of the asset to retrieve. Takes precedence when both id and name are provided.",
          "type": "string"
        },
        "name": {
-         "description": "Partial name match (case-insensitive). Used to find the asset when ID is unknown.",
+         "description": "Case-insensitive substring lookup within the first 249 assets only. Multiple matches return an ambiguity error; id takes precedence.",
          "type": "string"
        }
      },
--- pinned/get_aws_account
+++ observed/get_aws_account
  {
    "_meta": {
      "openai/toolInvocation/invoked": "AWS account loaded",
-   "description": "Use this when the user wants the CloudConnect details of a specific connected AWS account, such as its IAM role ARN, billing S3 bucket, and which DoiT features are enabled or supported. Requires the 12-digit AWS account ID. Do NOT use this for Google Cloud or Azure accounts.",
+   "description": "Use this when the user wants the CloudConnect details of a specific connected AWS account, such as its IAM role ARN, S3 bucket for real-time data, and which DoiT features are enabled or supported. Requires the 12-digit AWS account ID. Do NOT use this for Google Cloud or Azure accounts.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/get_budget
+++ observed/get_budget
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Budget details loaded",
-         "description": "Partial name match (case-insensitive). Used to find the budget when ID is unknown.",
+         "description": "Case-insensitive partial name lookup in the 200 most recent budgets only. Multiple matches return an ambiguity error. ID takes precedence.",
          "type": "string"
        }
      },
--- pinned/get_cloud_connect_supported_features
+++ observed/get_cloud_connect_supported_features
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Supported features loaded",
-   "description": "Use this when the user wants to know which DoiT CloudConnect features a connected cloud account supports and whether the account currently has the required permissions for each feature. Accepts an AWS account ID or Azure tenant ID. Returns the list of supported features with their permission status.",
+   "description": "Use this when the user wants to know which DoiT CloudConnect features a connected AWS account supports and whether the account currently has the required permissions for each feature. Accepts a 12-digit AWS account ID, including AWS standalone accounts. Azure tenant IDs are unsupported. Returns the list of supported features with their permission status.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "The cloud provider account ID (AWS account ID or Azure tenant ID) to check supported features for.",
-         "minLength": 1,
+         "description": "The 12-digit AWS account ID to check supported features for (including AWS standalone accounts).",
+         "pattern": "^\\d{12}$",
          "type": "string"
        }
      },
--- pinned/get_cloud_diagram_components
+++ observed/get_cloud_diagram_components
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagram components retrieved",
-   "description": "Use this when the user wants to discover all cloud infrastructure diagrams and their layers (statussheets), or to look up layer IDs needed for other diagram endpoints. Returns all diagrams with their connected layers and optionally their component data. This is the primary discovery endpoint — use it before calling endpoints that require a layer ID. Optionally filter by diagram IDs (scheme_ids) or layer IDs (layer_ids), and set include_components=true to get full component lists. Do NOT use this for cost analysis (use run_query) or diagram search (use search_cloud_diagrams).",
+   "description": "Use this when the user wants to discover all cloud infrastructure diagrams and their layers (statussheets), or to look up layer IDs needed for other diagram endpoints. With no filters, returns accessible application and infrastructure diagrams with layer metadata and no component data. Returns maps keyed by diagram and layer IDs. Selectors must belong to diagrams accessible to the authenticated customer and user. scheme_ids and the diagrams owning layer_ids are combined, not intersected. The layer IDs required by other diagram tools come from this tool. Optionally filter by diagram IDs (scheme_ids) or layer IDs (layer_ids), and set include_components=true to load projected component maps for up to five requested or resolved layers. Larger selections return an error before loading components; discover metadata first, then request batches of at most five layer_ids. Do NOT use this for cost analysis (use run_query) or diagram search (use search_cloud_diagrams).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Include component data (nodes, elements, groups, links, etc.) in the response. Defaults to false for lighter responses. Enable when you need component IDs for other diagram endpoints.",
+         "description": "Load component maps for up to five selected layers, or resolved diagram layers when layer_ids is omitted. Larger selections return an error; discover layer IDs with this option false, then request batches of at most five layer_ids. With no IDs, first discovers accessible application/infrastructure diagrams. Defaults to false. Component fields use API projections, not full resource properties.",
          "type": "boolean"
        },
        "layer_ids": {
-         "description": "Filter to specific layer (statussheet) IDs. Omit to return all layers.",
+         "description": "Select these layer (statussheet) IDs and their owning diagrams. Component data is loaded only for selected layers, or resolved diagram layers when include_components is true.",
          "items": {
            "type": "string"
          },
-         "description": "Filter to specific diagram IDs. Omit to return all diagrams.",
+         "description": "Select these diagram IDs. When combined with layer_ids, also returns the diagrams owning those layers.",
          "items": {
            "type": "string"
          },
-         "description": "Exclude layers that have no components. Defaults to false.",
+         "description": "Omit empty layers from each diagram's layer metadata; diagrams remain in the result. Defaults to false.",
          "type": "boolean"
        }
      },
--- pinned/get_cloud_diagram_cost_snapshot
+++ observed/get_cloud_diagram_cost_snapshot
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagram cost snapshot retrieved",
-   "description": "Use this when the user wants a cost snapshot for a specific cloud infrastructure diagram layer over a time period — total spend, period-over-period trend percentage, the top resources and services by cost, and a cost trend over time. Requires the diagram layer ID and a startDate/endDate (YYYY-MM-DD). Do NOT use this for account-wide cost analysis (use run_query) or budgets (use list_budgets).",
+   "description": "Use this when the user wants a cost snapshot for a specific cloud infrastructure diagram layer over a time period — the API-reported total, trendingPct as a percentage (25 means 25%, null when no prior value is available), the top five resources and top five services by cost, and the last twelve trend buckets. Both dates are inclusive. Requires the diagram layer ID and a startDate/endDate (YYYY-MM-DD). Do NOT use this for account-wide cost analysis (use run_query) or budgets (use list_budgets).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "End of the period (calendar date, YYYY-MM-DD, e.g. 2026-04-30).",
+         "description": "Inclusive end date (YYYY-MM-DD, e.g. 2026-04-30).",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
          "type": "string"
        },
-         "description": "Start of the period (calendar date, YYYY-MM-DD, e.g. 2026-04-01).",
+         "description": "Inclusive start date (YYYY-MM-DD, e.g. 2026-04-01).",
          "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
          "type": "string"
        }
--- pinned/get_cloud_diagram_resource_relationships
+++ observed/get_cloud_diagram_resource_relationships
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Resource relationships retrieved",
-   "description": "Use this when the user wants to understand how a specific resource in a cloud infrastructure diagram is connected to other resources — its upstream/downstream edges and group membership. Returns the anchor resource plus related resources with their relation type and hop distance. Requires the diagram layer ID and the resource ID. Do NOT use this for cost analysis (use get_cloud_diagram_cost_snapshot or run_query).",
+   "description": "Use this when the user wants to understand how a specific resource in a cloud infrastructure diagram is connected to other resources — its upstream/downstream edges and optional group membership (only when kind is group_members or both). Returns the anchor resource plus up to 200 relations with their type and hop distance; truncated is true when more than 200 relations exist. Requires the diagram layer ID and the resource ID. Do NOT use this for cost analysis (use get_cloud_diagram_cost_snapshot or run_query).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/get_cloud_incident
+++ observed/get_cloud_incident
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Incident details loaded",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "The ID of the cloud incident.",
-         "type": "string"
+         "type": [
+           "string",
+           "number"
+         ]
        },
        "title": {
-         "description": "Partial title match (case-insensitive). Used to find the incident when ID is unknown.",
+         "description": "Case-insensitive partial title lookup in the 200 most recent incidents only. Multiple matches return an ambiguity error. ID takes precedence.",
          "type": "string"
        }
      },
--- pinned/get_cloud_incidents
+++ observed/get_cloud_incidents
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Incidents loaded",
-   "description": "Use this when the user wants to check for active cloud platform outages, service disruptions, or incidents from AWS, Google Cloud, or Azure. Do NOT use this for cost anomalies (use get_anomalies) or support tickets (use list_tickets).",
+   "description": "Use this when the user wants to check for active cloud platform outages, service disruptions, or incidents from AWS or Google Cloud. Both active and archived incidents are included unless status is filtered. Do NOT use this for cost anomalies (use get_anomalies) or support tickets (use list_tickets).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "filter": {
-         "description": "Filter string in format 'key:value|key:value'. Multiple values for same key are treated as OR, different keys as AND. Example: 'platform:google-cloud|status:active' or 'platform:google-cloud|platform:amazon-web-services'",
+         "description": "Exact filters in format key:value|key:value. Keys: platform (amazon-web-services or google-cloud), status (active or archived), product. Different keys use AND; repeated values of one key use OR. Only one key may repeat. Example: platform:google-cloud|status:active.",
          "type": "string"
        },
        "pageToken": {
-         "description": "Token for pagination. Use this to get the next page of results.",
+         "description": "Token for pagination, from a previous response; returns the next page of results.",
          "type": "string"
        },
        "platform": {
-         "description": "platform name",
-         "enum": [
-           "amazon-web-services",
-           "google-cloud-project",
-           "g-suite",
-           "office-365",
-           "google-cloud",
-           "open-ai"
+         "anyOf": [
+           {
+             "enum": [
+               "amazon-web-services",
+               "google-cloud"
+             ],
+             "type": "string"
+           },
+           {
+             "const": "google-cloud-project",
+             "type": "string"
+           }
          ],
-         "type": "string"
+         "description": "Platform constraint: amazon-web-services or google-cloud. Legacy google-cloud-project is normalized to google-cloud. If filter also contains platform, it must specify this same single platform."
        }
      },
      "type": "object"
--- pinned/get_cloud_overview
+++ observed/get_cloud_overview
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Cloud overview ready",
-   "description": "Use this when the user wants a high-level overview or dashboard of their entire cloud infrastructure. Returns cost by cloud provider, top services per cloud, top projects per cloud, recent cost anomalies, and recent cloud incidents — all in a single call. Do NOT use this for detailed drill-downs (use run_query), single-provider analysis, or anomaly-only queries.",
+   "description": "Use this when the user wants a high-level overview or dashboard of their entire cloud infrastructure. Returns cost by cloud provider, top services per cloud, top projects per cloud, recent cost anomalies, and recent cloud incidents — all in a single call. Costs cover the last 30 days including today, with daily rows; services and projects are limited to top 5 values per cloud across that range. Returns at most 5 anomalies and 5 AWS/Google Cloud provider incidents (not account-specific incidents). Failed sections silently return empty arrays, so empty data does not establish zero spend or no incidents. Do NOT use this for detailed drill-downs (use run_query), single-provider analysis, or anomaly-only queries.",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {},
      "type": "object"
    },
--- pinned/get_commitment
+++ observed/get_commitment
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Returns details of a specific Enterprise Discount Program (EDP) commitment contract, identified by its ID. Includes the full breakdown of commitment periods, per-period contracted values, and current spend attainment against the committed amount.",
+   "description": "Returns details of a specific spend commitment contract for Google Cloud, AWS, or Azure, identified by its ID. Includes the full breakdown of commitment periods, per-period contracted values, and current spend attainment against the committed amount.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/get_datahub_dataset
+++ observed/get_datahub_dataset
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Dataset loaded",
-   "description": "Use this when the user wants to view details of a specific DataHub dataset by its ID. Returns full dataset metadata and schema. Do NOT use this for listing all datasets (use list_datahub_datasets) or cost queries (use run_query).",
+   "description": "Use this when the user wants to view details of a specific DataHub dataset by its name. Returns dataset metadata, including the schemaTemplate identifier when present, rather than the full column schema. Do NOT use this for listing all datasets (use list_datahub_datasets) or cost queries (use run_query).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/get_dimension
+++ observed/get_dimension
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Dimension loaded",
-   "description": "Use this to look up the valid filter values for a specific dimension before calling run_query — for example, call get_dimension({type: 'fixed', id: 'cloud_provider'}) to get the exact provider IDs available for this customer. Also use this when the user wants to view dimension details. Do NOT use this for listing all dimensions (use list_dimensions) or running queries (use run_query).",
+   "description": "Use this when the valid filter values for a specific dimension are needed, such as for a run_query filter, or when the user wants to view dimension details. Returns id, label, type and all available value/cloud pairs in one response, without pagination. For example, get_dimension({type: 'fixed', id: 'cloud_provider'}) returns the exact provider IDs available for this customer. Do NOT use this for listing all dimensions (use list_dimensions) or running queries (use run_query).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
-         "description": "Dimension id",
+         "description": "Dimension identifier paired with type, from list_dimensions. For allocation, use the group ID; for allocation_rule, use 'allocation_rule' (the dimension key, not an individual rule ID).",
          "type": "string"
        },
        "type": {
-         "description": "Dimension type",
+         "description": "Dimension type paired with id; use the type returned by list_dimensions. Includes allocation and allocation_rule and legacy attribution types.",
          "enum": [
            "datetime",
            "fixed",
+           "allocation",
+           "allocation_rule",
            "gke",
            "gke_label"
          ],
--- pinned/get_folder
+++ observed/get_folder
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Folder loaded",
-   "description": "Use this when the user wants to view details of a specific Cloud Analytics folder. Accepts either the folder ID or a partial name (case-insensitive). Do NOT use this for listing all folders (use list_folders) or viewing reports (use get_report_config).",
+   "description": "Use this when the user wants to view details of a specific Cloud Analytics folder. Accepts either the folder ID or a case-insensitive partial name. Name lookup searches only the first 200 folders; multiple matches return an error listing names, and id takes precedence. Do NOT use this for listing all folders (use list_folders) or viewing reports (use get_report_config).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "The ID of the folder to retrieve.",
-         "description": "Partial name match (case-insensitive). Used to find the folder when ID is unknown.",
+         "description": "Case-insensitive substring search of only the first 200 folders. Multiple matches return an ambiguity error listing names; id takes precedence.",
          "type": "string"
        }
      },
--- pinned/get_insight_resources
+++ observed/get_insight_resources
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insight resources ready",
-   "description": "Use this when the user wants to see which specific resources are affected by an optimization insight. Returns resource IDs, accounts, potential savings, and remediation details. Do NOT use this for listing all insights (use list_insights).",
+   "description": "Use this when the user wants to see which specific resources are affected by an optimization insight. Returns a page of resourceResults with rowCount and pageToken, resource IDs, accounts, savings or risk counts. There is no dedicated remediation field. Default page size is 1000; follow pageToken for more resources. Do NOT use this for listing all insights (use list_optimization_recommendations).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
+       "maxResults": {
+         "default": 1000,
+         "description": "Maximum resources per page, 1–5000; defaults to 1000.",
+         "maximum": 5000,
+         "minimum": 1,
+         "type": "integer"
+       },
+       "pageToken": {
+         "description": "Opaque cursor returned by the previous resource page.",
+         "type": "string"
+       },
        "source": {
          "description": "The source of the insight (e.g. 'aws-cost-optimization-hub', 'aws-trusted-advisor'). Use the 'source' field from list_optimization_recommendations.",
          "type": "string"
--- pinned/get_invoice
+++ observed/get_invoice
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Invoice details loaded",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "The ID of the invoice to retrieve.",
--- pinned/get_label
+++ observed/get_label
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Label loaded",
-   "description": "Use this when the user wants to view details of a specific label. Accepts either the label ID or a partial name (case-insensitive). Do NOT use this for listing all labels (use list_labels) or annotations (use list_annotations).",
+   "description": "Use this when the user wants to view details of a specific DoiT console label (not a cloud resource label). Accepts either the label ID or a case-insensitive partial name. Name lookup searches only the first 200 labels; multiple matches return an error listing names, and id takes precedence. Do NOT use this for listing all labels (use list_labels) or annotations (use list_annotations).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "The ID of the label to retrieve.",
-         "description": "Partial name match (case-insensitive). Used to find the label when ID is unknown.",
+         "description": "Case-insensitive substring search of only the first 200 labels. Multiple matches return an ambiguity error listing names; id takes precedence.",
          "type": "string"
        }
      },
--- pinned/get_label_assignments
+++ observed/get_label_assignments
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Assignments loaded",
-   "description": "Use this when the user wants to see which resources are assigned to a specific label. Returns a list of assigned objects. Do NOT use this for viewing label details (use get_label) or allocations (use list_allocations).",
+   "description": "Use this when the user wants to see which DoiT console objects are assigned to a label. Returns objectId and objectType pairs, without object details. Do NOT use this for viewing label details (use get_label) or allocations (use list_allocations).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/get_report_results
+++ observed/get_report_results
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Report data ready",
-   "description": "Use this when the user wants to retrieve the data results of a specific saved report. Accepts either the report ID or a partial name (case-insensitive). Do NOT use this for listing all reports (use list_reports) or running ad-hoc queries (use run_query).",
+   "description": "Use this when the user wants to retrieve the data results of a specific saved report. Uses the report's saved time range, resolved at execution for relative ranges. Accepts an ID or a case-insensitive substring name lookup within the first 200 newest reports; multiple matches return an ambiguity error and id takes precedence. Do NOT use this for listing all reports (use list_reports) or running ad-hoc queries (use run_query).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "The ID of the report to retrieve results for.",
-         "description": "Partial report name match (case-insensitive). Used to find the report when ID is unknown.",
+         "description": "Case-insensitive substring lookup within the first 200 newest reports only. Multiple matches return an ambiguity error; id takes precedence when both are provided.",
          "type": "string"
        }
      },
--- pinned/get_resource_permissions
+++ observed/get_resource_permissions
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Resource permissions loaded",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "resourceId": {
          "description": "The ID of the resource (alert, budget, report, or allocation) to retrieve permissions for.",
--- pinned/get_statussheet_components
+++ observed/get_statussheet_components
  {
    "annotations": {
-     "destructiveHint": true,
+     "destructiveHint": false,
      "openWorldHint": true,
-     "readOnlyHint": false
+     "readOnlyHint": true
    },
    "description": "Cloud Diagrams visualize your cloud infrastructure and resource relationships. Returns the specified components of a diagram layer. Provide at least one component\ntype with one or more IDs in the request body (for example, `node` or `element`).",
    "inputSchema": {
-         "read_data",
-         "write_data"
+         "read_data"
        ],
        "type": "oauth2"
      }
--- pinned/get_theme
+++ observed/get_theme
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Theme loaded",
-   "description": "Use this when the user wants to view details of a specific custom color theme. Accepts either the theme ID or a partial name (case-insensitive). Do NOT use this for listing all themes (use list_themes).",
+   "description": "Use this when the user wants to view details of a specific custom color theme. Accepts either the custom theme ID or a partial name (case-insensitive) across all custom themes. Multiple matches return an error listing names; id takes precedence. Preset themes cannot be fetched with this tool. Do NOT use this for listing all themes (use list_themes).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "id": {
          "description": "The ID of the custom theme to retrieve.",
-         "description": "Partial name match (case-insensitive). Used to find the theme when ID is unknown.",
+         "description": "Case-insensitive substring search across the custom themes returned by list_themes (not paginated). Multiple matches return an ambiguity error listing names; id takes precedence.",
          "type": "string"
        }
      },
--- pinned/import_cloudflow_flow
+++ observed/import_cloudflow_flow
  {
    "annotations": {
      "destructiveHint": true,
-   "description": "Manage CloudFlow. Creates every flow of a previously exported bundle in the authenticated tenant.\nImports are create-only: each call creates new draft flows with new IDs — nothing is\npublished and no schedule is activated until the target tenant publishes.\n\nRequirements declared by the bundle are resolved through `bindings` (requirement key →\ntarget-tenant resource ID). Unbound connections and Datastore tables leave the\nreferencing nodes flagged incomplete; unbound global variables are auto-created. Pass\n`options.createMissingTables: true` to create missing Datastore tables from the schemas\nembedded in the bundle (structure only, never row data).\n\n**Dry-run**: pass `?dryRun=true` to validate without writing. The response is an import\nplan: per-requirement resolutions with candidate bindings in the target tenant, the\nflows that would be created, and every validation issue at once. codeNode contract: upstream data comes only from `nodes[\"<node name>\"]` (a dict of lists); the code body must end in a top-level `return`; `schema` is required. Code that defines an uncalled function, reads a bare `input`, or assigns `output` completes with `{message: null}` — no error, no result.",
+   "description": "Manage CloudFlow. Creates every flow of a previously exported bundle in the authenticated tenant.\nImports are create-only: each call creates new draft flows with new IDs — nothing is\npublished and no schedule is activated until the target tenant publishes.\n\nRequirements declared by the bundle are resolved through `bindings` (requirement key →\ntarget-tenant resource ID). Unbound connections and Datastore tables leave the\nreferencing nodes flagged incomplete; unbound global variables are auto-created. Pass\n`options.createMissingTables: true` to create missing Datastore tables from the schemas\nembedded in the bundle (structure only, never row data).\n\n**Dry-run**: pass `?dryRun=true` to validate without writing. The response is an import\nplan: per-requirement resolutions with candidate bindings in the target tenant, the\nflows that would be created, and every validation issue at once. Idempotency-Key is required even with dryRun. Same key/request replays within 24 hours; different request fails with 422, an in-progress match with 409. Dry-runs validate existing fingerprints without storing a replay. codeNode: JavaScript (default) uses $nodes[\"<node name>\"] and $variables; Python uses nodes and variables. Upstream values are lists. A top-level return produces {message: value}; no return gives JS {} / Python {message: null}. Bare input is not injected; accessing it as upstream data fails the node. A schema (JSON Schema string) is required. The API fingerprints MCP tracking parameters; a changed client/server version can cause a same-key conflict. Keep the original request context and key. If an HTTP failure has only generic text, do not infer a status or retry automatically.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/invite_user
+++ observed/invite_user
  {
    "_meta": {
      "openai/toolInvocation/invoked": "User invited",
-   "description": "Use this when the user wants to invite a new person to the organization. Ask the user to confirm the email, role, and organization before executing. Do NOT use this for updating existing users (use update_user) or listing users (use list_users).",
+   "description": "Use this when the user wants to invite a new person to the organization. The invitation email is sent immediately. Omitted roleId defaults to Support User. The email domain must be permitted by the customer's invitation policy; existing users and pending invitees cannot be re-invited. Do NOT use this for updating existing users (use update_user) or listing users (use list_users).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "The email address of the user to invite (required).",
+         "description": "The email address of the user to invite (required). Its domain must be permitted by the customer's invitation policy; existing users and pending invitees cannot be re-invited.",
          "format": "email",
          "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
          "type": "string"
-         "description": "The ID of the role to assign to the invited user.",
+         "description": "The role ID from list_roles to assign to the invited user. Omission defaults to Support User.",
          "type": "string"
        }
      },
--- pinned/list_alert_slack_channels
+++ observed/list_alert_slack_channels
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Notifications triggered when cloud costs exceed defined thresholds or meet specific conditions. Lists Slack destinations eligible for Alert notifications for the authenticated customer and caller. Returns canonical identifiers for recipientsSlackChannels and integration status. User credentials include visible private channels; service accounts return public/shared channels only. Results are sorted by stable destination identity. Keep nameContains unchanged when following pageToken. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Notifications triggered when cloud costs exceed defined thresholds or meet specific conditions. Lists Slack destinations eligible for Alert notifications for the authenticated customer and caller. Returns canonical identifiers for recipientsSlackChannels and integration status. User credentials include visible private channels; service accounts return public/shared channels only. Results are sorted by stable destination identity. Keep nameContains unchanged when following pageToken. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_alerts
+++ observed/list_alerts
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Alerts loaded",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "filter": {
-         "description": "Expression for filtering results. Syntax: key:[<value>]. Multiple filters joined with |. Available keys: owner, name.",
+         "description": "Exact, case-sensitive filters: owner (email) or name. Use key:value and join distinct keys with | (AND). Repeated keys are rejected. Example: owner:user@example.com|name:Daily costs.",
          "type": "string"
        },
        "maxResults": {
-         "description": "Maximum number of results to return in a single page",
+         "description": "Maximum results per page. Tool default 40; valid range 1–500. Out-of-range values fall back to 50 at the API.",
          "type": "string"
        },
        "pageToken": {
--- pinned/list_allocations
+++ observed/list_allocations
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Allocations loaded",
-   "description": "Use this when the user wants to see their cost allocation rules or configurations. Returns a list of allocations. Supports partial name filtering. Do NOT use this for cost queries (use run_query) or labels (use list_labels).",
+   "description": "Use this when the user wants to see their cost allocation rules or configurations. Returns a list of allocations. Returns pages of 40; pass the returned pageToken for another page (null means no next page). The case-insensitive partial name filter applies only to that returned page. Do NOT use this for cost queries (use run_query) or labels (use list_labels).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "name": {
-         "description": "Partial name filter (case-insensitive). Returns only allocations whose name contains this string.",
+         "description": "Partial name filter (case-insensitive). Returns only allocations on the returned page whose name contains this string.",
          "type": "string"
        },
        "pageToken": {
-         "description": "Token for pagination. Use this to get the next page of results.",
+         "description": "Token for pagination, from a previous response; returns the next page of results.",
          "type": "string"
        }
      },
--- pinned/list_annotations
+++ observed/list_annotations
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Annotations loaded",
-         "description": "An expression for filtering the results. Valid fields: content, timestamp, labels. Example: content:budget",
+         "description": "Filter using key:value, with different keys joined by | (AND). Repeated keys are rejected (400); values match exactly and case-sensitively. Only content is supported; timestamp and labels are not filter keys. Example: content:budget",
          "type": "string"
        },
        "maxResults": {
-         "description": "The maximum number of results to return in a single page. Defaults to 500.",
+         "description": "The maximum number of results per page, as an integer string (1-500). Out-of-range integers fall back to 50; non-integers are rejected. This tool defaults to 500.",
          "type": "string"
        },
        "pageToken": {
-         "description": "A field by which the results will be sorted. Accepted values: id, content, timestamp, timeCreated, timeModified.",
+         "description": "A field by which the results will be sorted. Accepted values: id, content, timestamp.",
          "enum": [
            "id",
            "content",
-           "timestamp",
-           "timeCreated",
-           "timeModified"
+           "timestamp"
          ],
          "type": "string"
        },
--- pinned/list_assets
+++ observed/list_assets
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Assets loaded",
-   "description": "Use this when the user wants to browse their cloud assets, subscriptions, or resources. Returns a paginated list of assets. Supports partial name filtering. Do NOT use this for cost analysis (use run_query) or checking invoices (use list_invoices).",
+   "description": "Use this when the user wants to browse their cloud assets, subscriptions, or resources. Returns a paginated list of assets. Name filtering is case-insensitive and applies only to the returned page. The API cursor and unfiltered rowCount are preserved, including on pages with no matches. Do NOT use this for cost analysis (use run_query) or checking invoices (use list_invoices).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "An expression for filtering the results. Uses key:[value] syntax, e.g. \"type:g-suite\". Multiple filters can be connected using a pipe |. Different keys result in AND; same key multiple times results in OR.",
+         "description": "Server-side filter with type as the only supported key. Exact, case-sensitive values without brackets, e.g. \"type:g-suite\". Repeating type with pipe | matches any listed type (OR), e.g. \"type:g-suite|type:office-365\".",
          "type": "string"
        },
        "maxResults": {
-         "description": "Partial name filter (case-insensitive). Returns only assets whose name contains this string.",
+         "description": "Case-insensitive substring filter on the returned API page only. Other pages are not searched. pageToken and rowCount retain the API's unfiltered page values, even when no assets match.",
          "type": "string"
        },
        "pageToken": {
--- pinned/list_aws_member_accounts
+++ observed/list_aws_member_accounts
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns all member AWS accounts under the specified AWS organization that have active or historical commitment coverage. Includes 30-day statistics and estimated monthly potential savings (`monthlyPotentialSavings`) per Savings Plan (SP) type. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns all member AWS accounts under the specified AWS organization that have active or historical commitment coverage. Includes 30-day statistics and estimated monthly potential savings (`monthlyPotentialSavings`) per Savings Plan (SP) type. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_aws_organizations
+++ observed/list_aws_organizations
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns all AWS organizations (accounts) accessible to the authenticated tenant. Use as the entry point to discover AWS organization account IDs, and organization-level onboarding status of the available commitment types and savings metrics.\n\nEach item includes metadata, trailing 30-day aggregate statistics, precomputed YTD/lifetime savings totals per Savings Plan (SP) type, and estimated monthly potential savings (`monthlyPotentialSavings`) per SP type from the latest projection. Sum across items for customer-level totals. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns all AWS organizations (accounts) accessible to the authenticated tenant. Use as the entry point to discover AWS organization account IDs, and organization-level onboarding status of the available commitment types and savings metrics.\n\nEach item includes metadata, trailing 30-day aggregate statistics, precomputed YTD/lifetime savings totals per Savings Plan (SP) type, and estimated monthly potential savings (`monthlyPotentialSavings`) per SP type from the latest projection. Sum across items for customer-level totals. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_aws_organizations_settings
+++ observed/list_aws_organizations_settings
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns one item per onboarded AWS organization. Each item includes that AWS organization's commitments purchasing account (`purchaseAccountId`) and commitment settings for each commitment type activated on that AWS organization (`compute`, `database`).\n\nCommitment settings cover recommendation and automation preferences (policy, term, payment option, automation mode, commitment limits, and related fields). They are stored independently for each AWS organization and commitment type. Each item includes that organization's `purchaseAccountId` and activated commitment types.\n\nIn the DoiT Console, commitment settings are edited on an account's Settings tab and apply only to that AWS organization and commitment type; the purchasing account is set per AWS organization on Accounts Settings. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns one item per onboarded AWS organization. Each item includes that AWS organization's commitments purchasing account (`purchaseAccountId`) and commitment settings for each commitment type activated on that AWS organization (`compute`, `database`).\n\nCommitment settings cover recommendation and automation preferences (policy, term, payment option, automation mode, commitment limits, and related fields). They are stored independently for each AWS organization and commitment type. Each item includes that organization's `purchaseAccountId` and activated commitment types.\n\nIn the DoiT Console, commitment settings are edited on an account's Settings tab and apply only to that AWS organization and commitment type; the purchasing account is set per AWS organization on Accounts Settings. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_aws_planned_purchases
+++ observed/list_aws_planned_purchases
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns planned purchases (laddering projections) for the AWS organization. One item per commitment type that has a projection available (typically `compute` and/or `database`; up to four commitment types as PerfectScale for Commitments expands).\n\nWith no filters, returns all available planned-purchase items for the AWS organization in stable commitment-type order (`compute`, then `database`, then any future commitment types in enum order). When a filtered commitment type has no planned purchases, the response is an empty `items` array (not `404`). Partial items return only the fields available at response time.\n\n`404` is returned only when the AWS organization does not exist or the caller cannot access it. An AWS organization that is not onboarded for PerfectScale for Commitments still returns `200` with an empty `items` array when no planned purchases exist — use `GET /ps4commitments/v1/aws/organizations` (or get-by-id) for `onboardingStatus`.\n\n**Pagination**: results are returned in stable commitment-type order (`compute`, then `database`, then any future commitment types in enum order). Use `maxResults` to limit page size (default 50, max 500). When more items remain, the response includes a non-null `pageToken`; pass it unchanged on the next request with the same query parameters (`service`, `maxResults`). `rowCount` is the number of items in this page. An invalid `pageToken` returns `400` with code `pagination_token_invalid`; an expired token returns `400` with code `pagination_token_expired`. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns planned purchases (laddering projections) for the AWS organization. One item per commitment type that has a projection available (typically `compute` and/or `database`; up to four commitment types as PerfectScale for Commitments expands).\n\nWith no filters, returns all available planned-purchase items for the AWS organization in stable commitment-type order (`compute`, then `database`, then any future commitment types in enum order). When a filtered commitment type has no planned purchases, the response is an empty `items` array (not `404`). Partial items return only the fields available at response time.\n\n`404` is returned only when the AWS organization does not exist or the caller cannot access it. An AWS organization that is not onboarded for PerfectScale for Commitments still returns `200` with an empty `items` array when no planned purchases exist — use `GET /ps4commitments/v1/aws/organizations` (or get-by-id) for `onboardingStatus`.\n\n**Pagination**: results are returned in stable commitment-type order (`compute`, then `database`, then any future commitment types in enum order). Use `maxResults` to limit page size (default 50, max 500). When more items remain, the response includes a non-null `pageToken`; pass it unchanged on the next request with the same query parameters (`service`, `maxResults`). `rowCount` is the number of items in this page. An invalid `pageToken` returns `400` with code `pagination_token_invalid`; an expired token returns `400` with code `pagination_token_expired`. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_aws_reserved_instances
+++ observed/list_aws_reserved_instances
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns a paginated list of Reserved Instances (RIs) for the specified AWS organization. Optionally filter by state, instance type, instance family, region, and offering class. Omit filters to return all RIs for the AWS organization. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns a paginated list of Reserved Instances (RIs) for the specified AWS organization. Optionally filter by state, instance type, instance family, region, and offering class. Omit filters to return all RIs for the AWS organization. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_aws_savings_plans
+++ observed/list_aws_savings_plans
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns a paginated list of Savings Plans for the specified AWS organization. Optionally filter by plan type (`type`) and state (`status`). Omit both filters to return all plans for the AWS organization. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns a paginated list of Savings Plans for the specified AWS organization. Optionally filter by plan type (`type`) and state (`status`). Omit both filters to return all plans for the AWS organization. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_billing_transfer_program_management_accounts
+++ observed/list_billing_transfer_program_management_accounts
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Manage AWS billing-transfer mappings between distributors and resellers and between resellers and end customers, and list program management accounts. Lists the caller's program management accounts (PMAs) and the reseller tenants mapped to\neach one, including AWS Organizations handshake status per account. Distributor-only.\n This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Manage AWS billing-transfer mappings between distributors and resellers and between resellers and end customers, and list program management accounts. Lists the caller's program management accounts (PMAs) and the reseller tenants mapped to\neach one, including AWS Organizations handshake status per account. Distributor-only.\n This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_budgets
+++ observed/list_budgets
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Budgets loaded",
-         "description": "An expression for filtering the results. Syntax: \"key:[<value>]\". Available keys: owner, lastModified in ms (>lastModified). Multiple filters can be connected using a pipe |. Note that using different keys in the same filter results in \"AND,\" while using the same key multiple times in the same filter results in \"OR\".",
+         "description": "An expression for filtering the results. Syntax: \"key:value\". Available keys: owner, budgetName, lastModified in ms (at or after; also orders by update time), riskStatus (one of atRisk, onTrack, unknown). Multiple filters can be connected using a pipe |. Note that using different keys in the same filter results in \"AND\". The owner key can be repeated, and repeated owner values are combined with \"OR\"; for budgetName (exact, case-sensitive), lastModified and riskStatus only the first occurrence is honored.",
          "type": "string"
        },
        "maxCreationTime": {
-         "description": "The maximum number of results to return in a single page. Defaults to 50.",
+         "description": "The maximum number of results to return in a single page. Defaults to 50; maximum 250 (larger values are rejected).",
          "type": "string"
        },
        "minCreationTime": {
-         "description": "Partial name filter (case-insensitive). Returns only budgets whose name contains this string.",
+         "description": "Server-side case-insensitive substring filter on budget names, applied before pagination (nameContains).",
          "type": "string"
        },
        "pageToken": {
--- pinned/list_cloud_diagram_activity_groups
+++ observed/list_cloud_diagram_activity_groups
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Activity groups retrieved",
-   "description": "Use this when the user wants the change history of a cloud diagram layer grouped by snapshot. Returns snapshot activity groups for the given layer (ss_id), ordered by timestamp descending; each group references a snapshot and contains the individual activity records (node/link/group/attachment create/update/delete) that belong to it. Page with offset/limit and filter with tags. Do NOT use this for cost analysis (use run_query) or incidents (use get_cloud_incidents).",
+   "description": "Use this when the user wants the activity history of a cloud diagram layer. Without tags, returns ALARM, COMMIT, EVENT, and SNAPSHOT activity groups for the given layer (ss_id), ordered by timestamp descending; snapshot groups reference a snapshot and contain their individual activity records. Supplying non-empty tags restricts results to snapshots. Page with offset/limit and filter with tags. Do NOT use this for cost analysis (use run_query) or incidents (use get_cloud_incidents).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Filter activity groups by tags.",
+         "description": "Filter by snapshot tags; supplying non-empty tags restricts results to SNAPSHOT groups.",
          "items": {
            "type": "string"
          },
--- pinned/list_cloud_diagram_node_activities
+++ observed/list_cloud_diagram_node_activities
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Node activities retrieved",
-   "description": "Use this when the user wants the change history of a single component node in a cloud diagram layer. Returns individual activity records (NODE_CREATE/NODE_UPDATE/NODE_DELETE) for the given node (ss_id + nodeId), ordered by timestamp descending, each including the user who made the change. Page with offset/limit. Do NOT use this for cost analysis (use run_query) or incidents (use get_cloud_incidents).",
+   "description": "Use this when the user wants the change history of a single component node in a cloud diagram layer. Returns individual activity records (NODE_CREATE/NODE_UPDATE/NODE_DELETE) for the given node (ss_id + nodeId), ordered by timestamp descending, each including user as the ID of the user who made the change. Page with offset/limit. Do NOT use this for cost analysis (use run_query) or incidents (use get_cloud_incidents).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_cloudflow_connections
+++ observed/list_cloudflow_connections
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow connections loaded",
-         "description": "Pagination cursor returned by a previous call, to request the next page of results.",
+         "description": "Pagination cursor returned by a previous call. Expires after five minutes.",
          "type": "string"
        }
      },
--- pinned/list_cloudflow_flow_runs
+++ observed/list_cloudflow_flow_runs
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Manage CloudFlow. Returns a flow's runs, newest first. Use `mode` to separate test runs from production\nones — test runs are included by default.\n\nPer-node detail is not included here; fetch a single run to read what each node consumed\nand produced. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Manage CloudFlow. Returns a flow's runs, newest first. Use `mode` to separate test runs from production\nones — test runs are included by default.\n\nPer-node detail is not included here; fetch a single run to read what each node consumed\nand produced. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_cloudflow_templates
+++ observed/list_cloudflow_templates
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow templates loaded",
-         "description": "Pagination cursor returned by a previous call, to request the next page of results.",
+         "description": "Pagination cursor returned by a previous call. Expires after five minutes.",
          "type": "string"
        }
      },
--- pinned/list_cloudflows
+++ observed/list_cloudflows
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlows loaded",
-         "description": "Pagination cursor returned by a previous call, to request the next page of results.",
+         "description": "Pagination cursor returned by a previous call. Expires after five minutes.",
          "type": "string"
        }
      },
--- pinned/list_commitment_policies
+++ observed/list_commitment_policies
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Cloud-agnostic PerfectScale for Commitments resources — commitment policies shared by AWS and GCP. Returns every commitment policy available to the tenant: the three built-in policies\n(`conservative`, `balanced`, `max_savings`) followed by the tenant's own custom policies.\n\nCommitment policies are cloud-agnostic. A single catalog is shared by AWS and GCP, and the\nsame policy may be assigned to AWS and GCP product lines alike.\n\nBuilt-in policies are listed first, ordered from least to most aggressive target coverage;\ncustom policies follow in creation order. Percentage parameters are expressed as `1`–`100`, as\nentered in the DoiT Console. This differs from the coverage and utilization fields on\nrecommendations and inventory, which are fractions from 0 to 1.\n\nThis endpoint is read-only. Custom policies are created, edited and deleted in the DoiT\nConsole on the Commitment Policies page. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Cloud-agnostic PerfectScale for Commitments resources — commitment policies shared by AWS and GCP. Returns every commitment policy available to the tenant: the three built-in policies\n(`conservative`, `balanced`, `max_savings`) followed by the tenant's own custom policies.\n\nCommitment policies are cloud-agnostic. A single catalog is shared by AWS and GCP, and the\nsame policy may be assigned to AWS and GCP product lines alike.\n\nBuilt-in policies are listed first, ordered from least to most aggressive target coverage;\ncustom policies follow in creation order. Percentage parameters are expressed as `1`–`100`, as\nentered in the DoiT Console. This differs from the coverage and utilization fields on\nrecommendations and inventory, which are fractions from 0 to 1.\n\nThis endpoint is read-only. Custom policies are created, edited and deleted in the DoiT\nConsole on the Commitment Policies page. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_commitments
+++ observed/list_commitments
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Returns a list of commitment contracts from the DoiT Commitment Manager. These are Enterprise Discount Program (EDP) agreements — negotiated minimum spend or usage commitments between the customer and a cloud provider (Google Cloud, AWS, or Azure) .",
+   "description": "Returns a paginated list of spend commitment contracts from the DoiT Commitment Manager for Google Cloud, AWS, and Azure. These are negotiated spend commitments, rather than resource usage commitments; AWS agreements may be called Enterprise Discount Programs (EDP).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "An expression for filtering the results. Syntax: key:[<value>]. Multiple filters can be connected using pipe |. Available filter keys: name, provider. Example: provider:[google-cloud]",
+         "description": "Exact, case-sensitive filtering using key:value without brackets. Supported keys: name, provider, cloudProvider (alias of provider). Provider values: google-cloud, amazon-web-services, microsoft-azure. Different keys combine with pipe | (AND); repeated keys, including provider with cloudProvider, are rejected. Example: provider:google-cloud",
          "type": "string"
        },
        "maxResults": {
-         "description": "The maximum number of results to return in a single page. Defaults to 50.",
+         "description": "The maximum number of results per page, from 1 to 500. Defaults to 50. The API falls back to 50 for out-of-range integers and rejects non-integers.",
          "type": "string"
        },
        "pageToken": {
--- pinned/list_dimensions
+++ observed/list_dimensions
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Dimensions loaded",
-   "description": "Use this when the user wants to see available dimensions for cost analysis queries. Returns a list of dimension types and values that can be used with run_query. Do NOT use this for running cost queries directly (use run_query) or viewing allocations (use list_allocations).",
+   "description": "Use this when the user wants to see available dimensions for cost analysis queries. Returns id, label and type metadata only (no values), up to 200 dimensions per page, sorted by id. GKE dimensions are omitted. pageToken retrieves subsequent pages; rowCount counts this page. get_dimension retrieves values. Empty results return an error. Do NOT use this for running cost queries directly (use run_query) or viewing allocations (use list_allocations).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "filter": {
-         "description": "Filter string (optional) in format 'key:value|key:value'. Multiple values for same key are treated as OR, different keys as AND. The fields eligible for filtering are: type, label, key.\n          use the filter parameter only if you know the exact value of the key, otherwise the filter should be empty.",
+         "description": "Filter string in format 'key:value|key:value'. Exact, case-sensitive filters: type and label. Different keys combine with AND; repeated keys are rejected. The API accepts key but it currently matches no dimensions. An empty filter returns an unfiltered page.",
          "type": "string"
        },
        "pageToken": {
-         "description": "Token for pagination. Use this to get the next page of results.",
+         "description": "Token for pagination, from a previous response; returns the next page of results.",
          "type": "string"
        }
      },
--- pinned/list_folders
+++ observed/list_folders
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Folders loaded",
-         "description": "The maximum number of results to return in a single page. Defaults to 500.",
+         "description": "The maximum number of results per page, as an integer string (1-500). Out-of-range integers fall back to 50; non-integers are rejected. This tool defaults to 500.",
          "type": "string"
        },
        "pageToken": {
--- pinned/list_gcp_billing_accounts
+++ observed/list_gcp_billing_accounts
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns all GCP Billing Accounts accessible to the authenticated tenant. Use as the entry point to discover GCP billing account IDs, and billing-account-level onboarding status of the available product lines and savings metrics.\n\nEach item includes metadata, CUD export health, trailing 30-day aggregate statistics, and precomputed YTD/lifetime savings totals per product line. Sum across items for customer-level totals. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns all GCP Billing Accounts accessible to the authenticated tenant. Use as the entry point to discover GCP billing account IDs, and billing-account-level onboarding status of the available product lines and savings metrics.\n\nEach item includes metadata, CUD export health, trailing 30-day aggregate statistics, and precomputed YTD/lifetime savings totals per product line. Sum across items for customer-level totals. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_gcp_billing_accounts_settings
+++ observed/list_gcp_billing_accounts_settings
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns one item per onboarded GCP Billing Account. Each item includes that billing\naccount's recommendation and automation engine settings for each product line activated\non it, per region scope: one `global` entry for `compute`, and one entry per known region\nfor `cloud_sql`.\n\nCloud SQL regions come from the billing account's persisted settings: a region is added\nwhen eligible spend is first seen there and is never removed, so its settings entry\nremains listed even if spend later drops to zero. Items are sorted by\n`billingAccountId`; within an item, `services` lists `compute` before `cloud_sql`, with\n`cloud_sql` regions sorted alphabetically.\n\nSettings are stored independently on each billing account. Existing customer-level\nsettings are copied lazily when an account is first read or initialized; if no valid\nlegacy value exists, the complete backend defaults are materialized once on the account.\nOnly product lines that are activated/onboarded for a given billing account are returned.\n\nIn the DoiT Console, these settings are edited on an account's Settings tab. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns one item per onboarded GCP Billing Account. Each item includes that billing\naccount's recommendation and automation engine settings for each product line activated\non it, per region scope: one `global` entry for `compute`, and one entry per known region\nfor `cloud_sql`.\n\nCloud SQL regions come from the billing account's persisted settings: a region is added\nwhen eligible spend is first seen there and is never removed, so its settings entry\nremains listed even if spend later drops to zero. Items are sorted by\n`billingAccountId`; within an item, `services` lists `compute` before `cloud_sql`, with\n`cloud_sql` regions sorted alphabetically.\n\nSettings are stored independently on each billing account. Existing customer-level\nsettings are copied lazily when an account is first read or initialized; if no valid\nlegacy value exists, the complete backend defaults are materialized once on the account.\nOnly product lines that are activated/onboarded for a given billing account are returned.\n\nIn the DoiT Console, these settings are edited on an account's Settings tab. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_gcp_planned_purchases
+++ observed/list_gcp_planned_purchases
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns the laddering projections for the billing account, grouped by PS4C product line\n(`service`) and region. Each service group lists one entry per available\n`gcp-purchases-projection` document for that scope (`compute` scopes are `global`;\n`cloud_sql` scopes are per-region).\n\nWith no filters, returns all existing projection documents in stable order: service groups\nordered `compute` first, then `cloud_sql`; within each group, regions sorted with `global`\nfirst, then remaining regions alphabetically. Services with no projection documents are omitted\n(not returned as empty groups). When a filter matches no documents, the response is an\nempty `items` array (not `404`). Partial projection documents return only the fields\navailable in storage.\n\n**`gcp_service` and `region` filters**: omit both to return all available services and\ntheir regions; supply `gcp_service` alone to return all regions for that service; supply\nboth to return a single service/region scope. `region` requires `gcp_service` — a request\nwith `region` but no `gcp_service` returns `400` with code `gcp_service_required`. Invalid\n`gcp_service` or `region` values return `400` with code `validation_failed`.\n\n`404` is returned only when the billing account does not exist or the caller cannot access\nit. A billing account that is not onboarded for PS4C still returns `200` with an empty\n`items` array when no projection documents exist — use\n`GET /ps4commitments/v1/gcp/billing-accounts` (or get-by-id) for onboarding status.\n\n**Pagination**: results are paginated by **service group** (a whole group is never split\nacross pages). Groups keep the stable service order above. Use `maxResults` to limit\npage size (default 50, max 500). When more groups remain, the response includes a\nnon-null `pageToken`; pass it unchanged on the next request with the same query parameters\n(`gcp_service`, `region`, `maxResults`). `rowCount` is the number of service groups in\nthis page. An invalid `pageToken` returns `400` with code `pagination_token_invalid`; an\nexpired token returns `400` with code `pagination_token_expired`. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns the laddering projections for the billing account, grouped by PS4C product line\n(`service`) and region. Each service group lists one entry per available\n`gcp-purchases-projection` document for that scope (`compute` scopes are `global`;\n`cloud_sql` scopes are per-region).\n\nWith no filters, returns all existing projection documents in stable order: service groups\nordered `compute` first, then `cloud_sql`; within each group, regions sorted with `global`\nfirst, then remaining regions alphabetically. Services with no projection documents are omitted\n(not returned as empty groups). When a filter matches no documents, the response is an\nempty `items` array (not `404`). Partial projection documents return only the fields\navailable in storage.\n\n**`gcp_service` and `region` filters**: omit both to return all available services and\ntheir regions; supply `gcp_service` alone to return all regions for that service; supply\nboth to return a single service/region scope. `region` requires `gcp_service` — a request\nwith `region` but no `gcp_service` returns `400` with code `gcp_service_required`. Invalid\n`gcp_service` or `region` values return `400` with code `validation_failed`.\n\n`404` is returned only when the billing account does not exist or the caller cannot access\nit. A billing account that is not onboarded for PS4C still returns `200` with an empty\n`items` array when no projection documents exist — use\n`GET /ps4commitments/v1/gcp/billing-accounts` (or get-by-id) for onboarding status.\n\n**Pagination**: results are paginated by **service group** (a whole group is never split\nacross pages). Groups keep the stable service order above. Use `maxResults` to limit\npage size (default 50, max 500). When more groups remain, the response includes a\nnon-null `pageToken`; pass it unchanged on the next request with the same query parameters\n(`gcp_service`, `region`, `maxResults`). `rowCount` is the number of service groups in\nthis page. An invalid `pageToken` returns `400` with code `pagination_token_invalid`; an\nexpired token returns `400` with code `pagination_token_expired`. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_gcp_resource_cuds
+++ observed/list_gcp_resource_cuds
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns a paginated list of resource-based (vCPU / memory) CUDs for the billing account. Optionally filter by CUD state (`status`). Omit to return CUDs in all states. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns a paginated list of resource-based (vCPU / memory) CUDs for the billing account. Optionally filter by CUD state (`status`). Omit to return CUDs in all states. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_gcp_spend_cuds
+++ observed/list_gcp_spend_cuds
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns a paginated list of spend-based CUDs for the billing account. Optionally filter by\nCUD state (`status`); omit to return CUDs in all states.\n\n**`gcp_service` and `region` filters**: `gcp_service` narrows results to one product\nline's coverage sub-type (`compute` or `cloud_sql`); `region` additionally narrows to one\nregion scope and requires `gcp_service` — a request with `region` but no `gcp_service`\nreturns `400` with code `gcp_service_required`. A `region` that is malformed or\nincompatible with `gcp_service` (`compute` is `global`-only, `cloud_sql` is regional-only)\nreturns `400` with code `validation_failed`; a well-formed, compatible region with no\nmatching CUDs returns `200` with an empty `items` array. Note the `region` query parameter\nuses the `lower_snake_case` wire form (`us_central1`), while each item's `region` field\nechoes the raw provider value (`us-central1`). This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current GCP commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns a paginated list of spend-based CUDs for the billing account. Optionally filter by\nCUD state (`status`); omit to return CUDs in all states.\n\n**`gcp_service` and `region` filters**: `gcp_service` narrows results to one product\nline's coverage sub-type (`compute` or `cloud_sql`); `region` additionally narrows to one\nregion scope and requires `gcp_service` — a request with `region` but no `gcp_service`\nreturns `400` with code `gcp_service_required`. A `region` that is malformed or\nincompatible with `gcp_service` (`compute` is `global`-only, `cloud_sql` is regional-only)\nreturns `400` with code `validation_failed`; a well-formed, compatible region with no\nmatching CUDs returns `200` with an empty `items` array. Note the `region` query parameter\nuses the `lower_snake_case` wire form (`us_central1`), while each item's `region` field\nechoes the raw provider value (`us-central1`). This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_invoices
+++ observed/list_invoices
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Invoices loaded",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "pageToken": {
-         "description": "Token for pagination. Use this to get the next page of results.",
+         "description": "Token for pagination, from a previous response; returns the next page of results.",
          "type": "string"
        }
      },
--- pinned/list_labels
+++ observed/list_labels
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Labels loaded",
-   "description": "Use this when the user wants to see their resource labels or label configurations. Returns a list of labels with their metadata. Do NOT use this for annotations (use list_annotations) or label assignments (use get_label_assignments).",
+   "description": "Use this when the user wants to see their DoiT console labels for organizing reports, budgets, alerts, allocations, metrics and annotations. Returns label metadata; these are not cloud resource labels. Do NOT use this for annotations (use list_annotations) or label assignments (use get_label_assignments).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "An expression for filtering the results. Valid fields: name, type. Example: name:budget",
+         "description": "Filter using key:value, with different keys joined by | (AND). Repeated keys are rejected (400); values match exactly and case-sensitively. Supported keys: name, type (custom or preset). Example: name:budget",
          "type": "string"
        },
        "maxResults": {
-         "description": "The maximum number of results to return in a single page. Defaults to 500.",
+         "description": "The maximum number of results per page, as an integer string (1-500). Out-of-range integers fall back to 50; non-integers are rejected. This tool defaults to 500.",
          "type": "string"
        },
        "pageToken": {
--- pinned/list_optimization_recommendations
+++ observed/list_optimization_recommendations
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insights ready",
-   "description": "Use this when the user asks about optimization, recommendations, insights, savings opportunities, rightsizing, idle resources, security findings, or cost reduction suggestions. Also use this when the user asks 'what insights are available?' or 'show me insights'. This is the primary tool for 'what can I optimize?', 'how can I save money?', and 'what insights do I have?' questions. Returns a prioritized list of actionable insights with estimated daily savings. Do NOT use this for cost anomalies/spikes (use get_anomalies) or budget tracking (use list_budgets).",
+   "description": "Use this when the user asks about optimization, recommendations, insights, savings opportunities, rightsizing, idle resources, security findings, or cost reduction suggestions. Also use this when the user asks 'what insights are available?' or 'show me insights'. This is the primary tool for 'what can I optimize?', 'how can I save money?', and 'what insights do I have?' questions. Returns insights ordered within each page by estimated daily savings, not priority. All statuses are included unless filtered, including dismissed. easyWin is derived from easyWinDescription when present, otherwise null. Follow pageToken for more results. Do NOT use this for cost anomalies/spikes (use get_anomalies) or budget tracking (use list_budgets).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Filter by insight categories. Possible values: FinOps, OperationalExcellence, PerformanceEfficiency, Reliability, Security, Sustainability.",
-         "items": {
-           "enum": [
-             "FinOps",
-             "OperationalExcellence",
-             "PerformanceEfficiency",
-             "Reliability",
-             "Security",
-             "Sustainability"
-           ],
-           "type": "string"
-         },
-         "type": "array"
+         "anyOf": [
+           {
+             "enum": [
+               "FinOps",
+               "OperationalExcellence",
+               "Operational excellence",
+               "PerformanceEfficiency",
+               "Performance efficiency",
+               "Reliability",
+               "Security",
+               "Sustainability"
+             ],
+             "type": "string"
+           },
+           {
+             "items": {
+               "enum": [
+                 "FinOps",
+                 "OperationalExcellence",
+                 "Operational excellence",
+                 "PerformanceEfficiency",
+                 "Performance efficiency",
+                 "Reliability",
+                 "Security",
+                 "Sustainability"
+               ],
+               "type": "string"
+             },
+             "maxItems": 1,
+             "type": "array"
+           }
+         ],
+         "description": "Filter by one category; a legacy one-element array is accepted. OperationalExcellence/Operational excellence and PerformanceEfficiency/Performance efficiency are filtered within each returned page because the API's category filter cannot match them. An empty page can still have a next cursor."
        },
        "displayStatus": {
-         "description": "Filter by display status. Possible values: actionable, acknowledged, in progress, optimized, dismissed.",
+         "description": "Filter by display status. Omitted means all statuses, including dismissed. Possible values: actionable, acknowledged, in progress, optimized, dismissed.",
          "items": {
            "enum": [
              "actionable",
-         "description": "Filter for easy wins only.",
+         "description": "True selects easy wins; false selects only non-easy-wins; omit for both.",
          "type": "boolean"
        },
+       "maxResults": {
+         "description": "Results per page, 1–500. Overrides pageSize; defaults to 20 for compatibility.",
+         "maximum": 500,
+         "minimum": 1,
+         "type": "integer"
+       },
        "page": {
-         "description": "Page number for pagination (zero-based).",
+         "description": "Deprecated: only 0 (first page) is accepted. Use pageToken for continuation.",
+         "maximum": 0,
          "minimum": 0,
-         "type": "number"
+         "type": "integer"
        },
        "pageSize": {
          "default": 20,
-         "description": "Number of results per page (default 20, max 100).",
+         "description": "Deprecated alias for maxResults (default 20, max 100); maxResults takes precedence.",
          "maximum": 100,
          "minimum": 1,
-         "type": "number"
+         "type": "integer"
        },
+       "pageToken": {
+         "description": "Non-empty opaque cursor from the previous response. Omit for the first page.",
+         "minLength": 1,
+         "type": "string"
+       },
        "priority": {
          "description": "Filter by priority levels. Possible values: Low, Medium, High.",
          "items": {
-         "description": "Filter by cloud provider.",
+         "description": "Filter by cloud provider (sent as cloudProvider to the API, e.g. aws, gcp, azure).",
          "type": "string"
        },
        "searchTerm": {
-         "description": "Text search across insight titles and descriptions.",
+         "description": "Case-insensitive substring search of insight titles only.",
          "type": "string"
        }
      },
--- pinned/list_platforms
+++ observed/list_platforms
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Platforms loaded",
-   "description": "Use this when the user wants to see available cloud platforms in their DoiT account. Returns a list of platforms. Do NOT use this for cloud incidents (use get_cloud_incidents) or products (use list_products).",
+   "description": "Use this when the user wants to see the support-ticket platform catalog. Returns platform IDs and display names for create_ticket; this catalog does not list connected cloud accounts. Do NOT use this for cloud incidents (use get_cloud_incidents) or products (use list_products).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_products
+++ observed/list_products
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Products loaded",
-   "description": "Use this when the user wants to see available DoiT products or services. Returns a list of products. Do NOT use this for cloud incidents (use get_cloud_incidents) or platforms (use list_platforms).",
+   "description": "Use this when the user wants to see the support-ticket product catalog. Returns product IDs, display names, and platform IDs. create_ticket uses the product displayName and the platform ID. Customers do not see private products. This catalog does not list products purchased by the account. Do NOT use this for cloud incidents (use get_cloud_incidents) or platforms (use list_platforms).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Filter products by platform",
+         "description": "Support platform ID, not a display name. Accepted IDs: google_g_suite, amazon_web_services, microsoft_office_365, finance___billing, google_cloud_platform, microsoft_azure, cloud_management_platform, credits___request, perfectscale. Availability depends on the customer.",
          "type": "string"
        }
      },
--- pinned/list_reports
+++ observed/list_reports
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Reports loaded",
-   "description": "Use this when the user wants to see their saved Cloud Analytics reports or browse available reports. Returns a paginated list of reports with their IDs and metadata. Do NOT use this for running queries (use run_query) or getting report results (use get_report_results).",
+   "description": "Use this when the user wants to see their saved Cloud Analytics reports or browse available reports. Returns pages of up to 40 reports with IDs and metadata, newest creation first. rowCount counts this page; pageToken retrieves the next page and is null at the end. Empty results return an error. Supports server-side, case-insensitive partial name filtering through name. Do NOT use this for running queries (use run_query) or getting report results (use get_report_results).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "filter": {
-         "description": "Filter string in format 'key:value|key:value'. Multiple values for same key are treated as OR, different keys as AND. Possible filter keys: reportName, owner, type, updateTime, use the filter property only if you know for sure the value is a valid filter key, do not guess it.",
+         "description": "Filter string in format 'key:value|key:value'. Different keys are combined with AND; each key can be used once. Supported keys: reportName (exact, case-sensitive full name), owner (owner's email, exact), type (custom, preset, or managed), updateTime (milliseconds since epoch; matches reports updated at or after it), folderId (exact; 'root' for reports outside any folder). Any other key is rejected with an error. Example: 'type:custom|owner:jane@example.com'",
          "type": "string"
        },
+       "name": {
+         "description": "Partial name filter (case-insensitive). Returns only reports whose name contains this string.",
+         "type": "string"
+       },
        "pageToken": {
-         "description": "Token for pagination. Use this to get the next page of results.",
+         "description": "Token for pagination, from a previous response; returns the next page of results.",
          "type": "string"
        }
      },
--- pinned/list_service_quotas
+++ observed/list_service_quotas
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Monitor cloud service quota usage across connected accounts and projects. Returns the latest service quota usage snapshots collected by DoiT for the authenticated customer.\nResults include only quotas retained by DoiT's monitoring collectors and are not a complete or live inventory from the cloud providers.\nResults are sorted by utilization percentage in descending order. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Monitor cloud service quota usage across connected accounts and projects. Returns the latest service quota usage snapshots collected by DoiT for the authenticated customer.\nResults include only quotas retained by DoiT's monitoring collectors and are not a complete or live inventory from the cloud providers.\nResults are sorted by utilization percentage in descending order. This endpoint is paginated: a response with a non-empty `pageToken` has more results, returned when that value is passed as the `pageToken` parameter. A missing, null, or empty `pageToken` marks the last page.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/list_tickets
+++ observed/list_tickets
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Tickets loaded",
-   "description": "Use this when the user wants to view their support tickets, check ticket status, or review open issues. Returns tickets with status, priority, and platform. Supports partial subject filtering. Do NOT use this for cloud incidents (use get_cloud_incidents) or cost alerts (use list_alerts).",
+   "description": "Use this when the user wants to view their support tickets, check ticket status, or review open issues. Returns tickets with status, severity, and platform. Customers see their own tickets; organization tickets are visible when ticket sharing is enabled. Subject filtering is case-insensitive and applies only to the returned page. The API cursor and unfiltered rowCount are preserved, including on pages with no matches. Do NOT use this for cloud incidents (use get_cloud_incidents) or cost alerts (use list_alerts).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "pageSize": {
-         "description": "Number of tickets to return per page",
-         "type": "number"
+         "default": 40,
+         "description": "Number of tickets per API page, from 1 to 100. Defaults to 40; sent as maxResults.",
+         "maximum": 100,
+         "minimum": 1,
+         "type": "integer"
        },
        "pageToken": {
-         "description": "Page token for pagination",
+         "description": "Page token from a previous response; keep the same pageSize when paging.",
          "type": "string"
        },
        "subject": {
-         "description": "Partial subject filter (case-insensitive). Returns only tickets whose subject contains this string.",
+         "description": "Case-insensitive substring filter on the returned API page only. Other pages are not searched. pageToken and rowCount retain the API's unfiltered page values, even when no tickets match.",
          "type": "string"
        }
      },
--- pinned/list_users
+++ observed/list_users
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Users loaded",
-   "description": "Use this when the user wants to see users in their DoiT organization or check who has access. Returns a list of users with roles. Do NOT use this for listing roles (use list_roles) or validating the current user (use validate_user).",
+   "description": "Use this when the user wants to see users in their DoiT organization or check who has access. Includes active users and pending invitations. Returns roleId values, which resolve to role details in list_roles. Do NOT use this for listing roles (use list_roles) or validating the current user (use validate_user).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/post_insight_result
+++ observed/post_insight_result
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insight saved",
-   "description": "Use this when the user wants to create a new custom insight or update an existing one's metadata (title, description, categories, status, remediation links). Only insights owned by the 'public-api' source can be managed. This manages the insight's metadata only — the individual affected resources are managed separately (post_insight_resource_results). Do NOT use this only to change an insight's status (use update_insight_status).",
+   "description": "Use this when the user wants to create a new custom insight or update an existing one's metadata (title, description, categories, status, remediation links). Only insights owned by the 'public-api' source can be managed (the default source). Requires key, title, shortDescription, cloudProvider and categories on every call. This replaces insight metadata: omitted optional fields such as detailedDescriptionMdx, reportUrl, easyWinDescription and cloudFlowTemplateId are cleared. Affected resources are managed separately (post_insight_resource_results). For a status-only change, use update_insight_status to preserve metadata despite that endpoint's deprecation.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Details for why the insight was dismissed (only relevant when status is 'dismissed').",
+         "description": "Details for why the insight was dismissed (relevant when status is 'dismissed').",
          "properties": {
            "comment": {
              "description": "An optional free-text comment providing additional context.",
-         "description": "The source that owns the insight. Only 'public-api' insights can be managed via this endpoint.",
+         "description": "The source that owns the insight. Only 'public-api' insights can be managed via this endpoint; defaults to public-api.",
          "enum": [
            "public-api"
          ],
--- pinned/refine_cloudflow
+++ observed/refine_cloudflow
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow refined",
-   "description": "Use this when the user wants to refine or rebuild an existing CloudFlow automation using natural language. Streams real-time progress updates while the AI builds the flow, then returns the final result. Generated codeNode code is frequently broken in ways that pass validation and fail silently at run time. Always export_cloudflow_flow and test-run the result, and check the per-node output, before reporting success.",
+   "description": "Refines an existing CloudFlow using natural language. Streams progress and returns the answer and conversationId; normally no flowId is returned. A plan or clarification question may save nothing. Reusing conversationId continues that conversation. Generated codeNode code can pass validation and fail silently or error at run time, so a successful build shows only that a draft was saved. export_cloudflow_flow returns the saved code; a completed test run's per-node output shows whether it works. Test runs execute real actions, including on drafts.",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "conversationId": {
          "description": "Optional conversation ID for multi-turn sessions",
--- pinned/run_query
+++ observed/run_query
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Analytics results ready",
-   "description": "Use this when the user wants to analyze cloud costs, generate a cost breakdown, view spending trends, or run a custom analytics query across their cloud providers. Accepts a structured config with data source, metrics, dimensions, time range, and filters. Do NOT use this for listing saved reports (use list_reports), checking anomalies (use get_anomalies), or viewing budgets (use list_budgets).\n    Fields that are not populated will use their default values if needed.\n    To limit the number of rows returned per group, set the `limit.value` field inside each `config.group[]` entry (maximum 25).\n    If possible, use `timeRange` instead of `customTimeRange` when no specific dates are given.\n    Use \"includeCurrent\": true to include the current in-progress month. Use \"includeCurrent\": false only when asking about a fully completed past period.\n    Always use \"metrics\" (array) not the deprecated \"metric\" (object).\n\n    ALWAYS include a \"group\" with id \"service_description\" and type \"fixed\" unless the user explicitly asks to group by something else. This gives a per-service cost breakdown which is always the most useful default.\n\n    Common grouping dimension IDs (all type \"fixed\"):\n      \"service_description\" — cloud service (default)\n      \"project_id\"          — GCP project / AWS account / Azure subscription (use when user asks to group by project, account, or subscription)\n      \"cloud_provider\"      — cloud provider (AWS / GCP / Azure)\n\n    IMPORTANT — filter values are dimension IDs, never display names. Before filtering on any dimension\n    you are unsure about, call get_dimension({type, id}) to retrieve the exact valid values for this customer.\n    Known cloud provider IDs (cloud_provider, type \"fixed\"):\n      \"amazon-web-services\" = AWS, \"google-cloud\" = GCP, \"microsoft-azure\" = Azure\n\n    Example — top AWS services last month:\n    {\n      \"config\": {\n        \"dataSource\": \"billing\",\n        \"metrics\": [{\"type\": \"basic\", \"value\": \"cost\"}],\n        \"timeRange\": {\"mode\": \"last\", \"amount\": 1, \"unit\": \"month\", \"includeCurrent\": true},\n        \"filters\": [{\"id\": \"cloud_provider\", \"type\": \"fixed\", \"values\": [\"amazon-web-services\"]}],\n        \"group\": [{\"id\": \"service_description\", \"type\": \"fixed\", \"limit\": {\"metric\": {\"type\": \"basic\", \"value\": \"cost\"}, \"sort\": \"desc\", \"value\": 10}}]\n      }\n    }",
+   "description": "Use this when the user wants to analyze cloud costs, generate a cost breakdown, view spending trends, or run a custom analytics query across their cloud providers. Runs the config through the DoiT Cloud Analytics API query endpoint (https://developer.doit.com/reference/query) and returns the result rows. Accepts a structured config with data source, metrics, dimensions, time range, and filters. Do NOT use this for listing saved reports (use list_reports), checking anomalies (use get_anomalies), or viewing budgets (use list_budgets).\n    Unpopulated fields take API defaults: basic cost, last 7 days including today, daily time rows (year/month/day), and billing (or billing-datahub for customers with DataHub metrics).\n    Each `config.group[].limit.value` selects top/bottom N dimension values per parent group, ranked across the range; it does not cap result rows and has no tool-enforced maximum of 25. Time columns can produce multiple rows per group.\n    `timeRange` covers relative periods; explicit dates require `timeRange: {mode: \"custom\"}` and sibling `config.customTimeRange: {from, to}`, with no unit.\n    For mode \"last\", \"includeCurrent\": true includes the current partial period within amount; false selects fully completed periods. One month with true is current month-to-date.\n    \"metrics\" (array) supersedes the deprecated \"metric\" (object).\n\n    A \"group\" with id \"service_description\" and type \"fixed\" returns a per-service cost breakdown, the most common shape for cost questions.\n\n    Common grouping dimension IDs (all type \"fixed\"):\n      \"service_description\" — cloud service\n      \"project_id\"          — GCP project / AWS account / Azure subscription\n      \"cloud_provider\"      — cloud provider (AWS / GCP / Azure)\n\n    In default mode \"is\", filter values must exactly match stored dimension values (case-sensitive): cloud_provider uses provider IDs, while service_description uses service names. Common cloud-provider aliases such as aws/gcp/azure are normalized by run_query. get_dimension({type, id}) returns the valid values for a dimension for this customer.\n    Known cloud provider IDs (cloud_provider, type \"fixed\"):\n      \"amazon-web-services\" = AWS, \"google-cloud\" = GCP, \"microsoft-azure\" = Azure\n\n    Example — top AWS services last month:\n    {\n      \"config\": {\n        \"dataSource\": \"billing\",\n        \"metrics\": [{\"type\": \"basic\", \"value\": \"cost\"}],\n        \"timeRange\": {\"mode\": \"last\", \"amount\": 1, \"unit\": \"month\", \"includeCurrent\": false},\n        \"filters\": [{\"id\": \"cloud_provider\", \"type\": \"fixed\", \"values\": [\"amazon-web-services\"]}],\n        \"group\": [{\"id\": \"service_description\", \"type\": \"fixed\", \"limit\": {\"metric\": {\"type\": \"basic\", \"value\": \"cost\"}, \"sort\": \"desc\", \"value\": 10}}]\n      }\n    }",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Configuration for the query. Use the dimension tool to look up valid dimension IDs.",
+         "description": "Configuration for the query. Valid dimension IDs come from list_dimensions or get_dimension.",
          "properties": {
            "advancedAnalysis": {
              "additionalProperties": false,
-             "description": "Custom time range. Only use when timeRange mode is 'custom'.",
+             "description": "Explicit dates, alongside timeRange (not nested inside it). Required for new custom queries/reports and when switching a saved relative report to custom mode. On update, omitted dates can reuse valid stored custom dates; omitted timeRange requires a stored custom mode. The API uses inclusive UTC calendar days.",
              "properties": {
                "from": {
-                 "description": "Start timestamp in RFC3339 format. Example: '2024-03-10T23:00:00Z'.",
+                 "description": "Start timestamp in RFC3339 format, with Z or a UTC offset. The API uses the UTC calendar 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "type": "string"
                },
                "to": {
-                 "description": "End timestamp in RFC3339 format. Example: '2024-03-12T23:00:00Z'.",
+                 "description": "End timestamp in RFC3339 format, with Z or a UTC offset. The API includes this UTC calendar 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "type": "string"
                }
              },
-             "description": "Data source for the report. Accepted values: billing, bqlens, billing-datahub, kubernetes-utilization.",
+             "description": "Data source; defaults to billing, or billing-datahub when the customer has DataHub metrics. Accepted values: billing, bqlens, billing-datahub, kubernetes-utilization.",
              "enum": [
                "billing",
                "bqlens",
-                   "description": "Dimension identifier. Use the dimension tool to get valid IDs.",
+                   "description": "Dimension identifier. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "type": {
-                   "description": "The field to filter on. Use the dimension tool to get valid IDs.",
+                   "description": "The field to filter on. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "inverse": {
-                   "description": "Filter match mode. Accepted values: is, starts_with, ends_with, contains, regexp.",
+                   "description": "Filter match mode. Defaults to 'is' (exact match). Accepted values: is, starts_with, ends_with, contains, regexp.",
                    "enum": [
                      "is",
                      "starts_with",
-                   "description": "Values to filter on.",
+                   "description": "Stored dimension values to match exactly in 'is' mode (case-sensitive): provider IDs for cloud_provider, service names for service_description. get_dimension returns available values.",
                    "items": {
                      "type": "string"
                    },
-                 "type",
-                 "mode"
+                 "type"
                ],
                "type": "object"
              },
-                   "description": "Dimension ID for the group-by row. Use the dimension tool to get valid IDs.",
+                   "description": "Dimension ID for the group-by row. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "limit": {
-                   "description": "Limit to top/bottom N results.",
+                   "description": "Select top/bottom N values of this dimension per parent group, ranked across the query range. Time dimensions still split result rows.",
                    "properties": {
                      "metric": {
                        "additionalProperties": false,
-                       "description": "Number of items to show.",
+                       "description": "Number of dimension values to select per parent group, not a cap on returned rows; time dimensions can produce multiple rows per selected value.",
                        "maximum": 9007199254740991,
                        "minimum": -9007199254740991,
                        "type": "integer"
-             "description": "Report layout / visualization type. Accepted values: column_chart, stacked_column_chart, bar_chart, stacked_bar_chart, line_chart, spline_chart, area_chart, area_spline_chart, stacked_area_chart, treemap_chart, table, table_heatmap, table_row_heatmap, table_col_heatmap, csv_export, sheets_export.",
+             "description": "Report layout / visualization type. Accepted values: column_chart, stacked_column_chart, bar_chart, stacked_bar_chart, line_chart, spline_chart, area_chart, area_spline_chart, stacked_area_chart, treemap_chart, table, table_heatmap, table_row_heatmap, table_col_heatmap, sankey_chart, column_and_line_chart, trend_board, cumulative_comparison.",
              "enum": [
                "column_chart",
                "stacked_column_chart",
-               "csv_export",
-               "sheets_export"
+               "sankey_chart",
+               "column_and_line_chart",
+               "trend_board",
+               "cumulative_comparison"
              ],
              "type": "string"
            },
-             "description": "List of metrics to apply (max 4). Preferred over the deprecated 'metric' field.",
+             "description": "List of metrics to apply (max 4). Defaults to basic cost on new reports/queries. Non-empty arrays replace stored metrics on update; [] leaves metrics unchanged. Preferred over the deprecated 'metric' field.",
              "items": {
                "additionalProperties": false,
                "properties": {
-             "description": "Time interval for grouping data. Accepted values: hour, day, dayCumSum, week, isoweek, month, quarter, year, week_day.",
+             "description": "Time interval for grouping data (default day). On update, supplying this with dimensions omitted resets time columns to this interval. Accepted values: hour, day, dayCumSum, week, isoweek, month, quarter, year, week_day.",
              "enum": [
                "hour",
                "day",
-             "description": "Time range for the report. Preferred over customTimeRange.",
+             "description": "Time range; defaults to the last 7 days including today on new reports/queries. For custom dates use {mode: 'custom'} and sibling config.customTimeRange.",
              "properties": {
                "amount": {
-                 "description": "Number of time units (0–5000). Required when mode is 'last'.",
+                 "description": "Number of calendar periods (0–5000). Required for 'last'.",
                  "maximum": 5000,
                  "minimum": 0,
                  "type": "integer"
-               "customTimeRange": {
-                 "additionalProperties": false,
-                 "description": "Custom date range. Required when mode is 'custom'.",
-                 "properties": {
-                   "from": {
-                     "description": "Start date in RFC3339 format.",
-                     "type": "string"
-                   },
-                   "to": {
-                     "description": "End date in RFC3339 format.",
-                     "type": "string"
-                   }
-                 },
-                 "required": [
-                   "from",
-                   "to"
-                 ],
-                 "type": "object"
-               },
                "includeCurrent": {
-                 "description": "Whether to include the current (in-progress) period.",
+                 "description": "For 'last', true includes the current partial period in amount; false (default) selects completed periods. With amount 1 and unit month, true means month-to-date and false means the previous full month. Ignored for 'current' and 'custom'.",
                  "type": "boolean"
                },
                "mode": {
-                 "description": "Time range mode. Accepted values: last, current, custom. Use 'custom' with customTimeRange for specific dates.",
+                 "description": "Time range mode: 'last' selects N calendar periods; 'current' selects the current calendar period through its end; 'custom' requires dates in config.customTimeRange, alongside timeRange.",
                  "enum": [
                    "last",
                    "current",
-                 "description": "Time unit. Accepted values: day, week, month, quarter, year. Required when mode is 'last'.",
+                 "description": "Time unit. Accepted values: day, week, month, quarter, year. Required for 'last' and 'current'; forbidden for 'custom'.",
                  "enum": [
                    "day",
                    "week",
--- pinned/search_cloud_diagrams
+++ observed/search_cloud_diagrams
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagram search complete",
-   "description": "Use this when the user wants to search their cloud infrastructure diagrams and components by name or property. Returns matching diagram layers (scheme), components, and components matched by property value (prop). Optionally scope to a single layer with ss_id and page with from/size. Do NOT use this for cost analysis (use run_query) or incidents (use get_cloud_incidents).",
+   "description": "Use this when the user wants to search their cloud infrastructure diagrams and components by name or property. Returns matching diagram layers (scheme), components, and components matched by property value (prop). ss_id scopes only component and prop results, not scheme results. from/size page each category independently. Do NOT use this for cost analysis (use run_query) or incidents (use get_cloud_incidents).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Pagination offset (default 0).",
+         "description": "Pagination offset applied independently to each result category (default 0).",
          "maximum": 9007199254740991,
          "minimum": 0,
          "type": "integer"
-         "description": "Limit search to components within this layer (layer ID).",
+         "description": "Scope only the component and prop categories to this layer ID; scheme results remain unscoped.",
          "type": "string"
        }
      },
--- pinned/send_datahub_events
+++ observed/send_datahub_events
  {
    "_meta": {
      "openai/toolInvocation/invoked": "DataHub events sent",
-   "description": "Use this when the user wants to send DataHub events for ingestion (1–50,000 events per call). Each event requires a provider name and an RFC 3339 timestamp, and can optionally include dimensions and metrics. Ask the user to confirm the event count and provider details before executing. Data becomes available in Cloud Analytics within ~15 minutes. Do NOT use this for creating datasets (use create_datahub_dataset) or viewing datasets (use list_datahub_datasets).",
+   "description": "Use this when the user wants to send DataHub events for ingestion (1–50,000 events per call). Each event requires a provider name and an RFC 3339 timestamp, and can optionally include dimensions and metrics. The API validates the entire request atomically, including duplicate event IDs anywhere in the request; a validation failure rejects the whole request. Success means accepted for asynchronous processing, not that records are already queryable. No processing latency is guaranteed. Do NOT use this for creating datasets (use create_datahub_dataset) or viewing datasets (use list_datahub_datasets).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-                     "description": "The dimension key.",
+                     "description": "Dimension key. For fixed dimensions, allowed keys are billing_account_id, project_id, project_name, project_number, service_description, service_id, sku_description, sku_id, operation, resource_id, resource_global_id, country, region, zone, pricing_unit, cost_type, is_marketplace.",
                      "minLength": 1,
                      "type": "string"
                    },
-                     "description": "The dimension value. Can be a string or boolean.",
+                     "description": "String value, except fixed is_marketplace, which accepts a boolean or the exact string 'true' or 'false'. Boolean values are not accepted for other keys or dimension types.",
                      "type": [
                        "string",
                        "boolean"
-               "description": "A unique event ID within the dataset. If omitted, a UUIDv4 is auto-generated by the server.",
+               "description": "An event ID unique within the dataset. Supplied IDs must also be unique across the entire request, including across providers. If omitted, the server generates a UUIDv4.",
                "type": "string"
              },
              "metrics": {
-               "description": "Optional list of metrics associated with this event.",
+               "description": "Optional list of at most 255 metrics associated with this event.",
                "items": {
                  "additionalProperties": false,
                  "properties": {
-               "description": "The data provider identifier (required). Allowed characters: alphanumeric (0-9,a-z,A-Z), underscore (_), dash (-), and spaces between words. Example: 'Datadog'.",
+               "description": "The dataset name used as the provider (required). Allowed characters: alphanumeric (0-9,a-z,A-Z), underscore (_), dash (-), and spaces between words. Example: 'Datadog'.",
                "minLength": 1,
                "pattern": "^[a-zA-Z0-9_-]+( [a-zA-Z0-9_-]+)*$",
                "type": "string"
-               "description": "The event timestamp (required). Must be an RFC 3339 date-time string (e.g. '2024-03-10T23:00:00Z').",
+               "description": "The event timestamp (required). Use a UTC RFC 3339 timestamp ending in Z. The API requires a time within 730 days before or after its current time.",
                "format": "date-time",
                "minLength": 1,
                "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))$",
--- pinned/set_active_theme
+++ observed/set_active_theme
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Active theme set",
-   "description": "Use this when the user wants to change or activate a custom color theme for their Cloud Analytics reports. Accepts a theme ID or the sentinel \"default\" to revert to the built-in default. Ask the user to confirm the change before executing. Do NOT use this to retrieve the current active theme (use get_active_theme) or to update theme colors (use update_theme).",
+   "description": "Use this when the user wants to change the authenticated user’s active Cloud Analytics color theme. Accepts a custom theme ID or supported preset ID or the sentinel \"default\" to revert to the built-in default. Changes apply immediately. Requires Cloud Analytics edit permission. Create new themes with create_custom_theme. Do NOT use this to retrieve the current active theme (use get_active_theme) or to update theme colors (use update_theme).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "The ID of the theme to set as active, or the reserved sentinel \"default\" to revert to the built-in default (no custom theme).",
+         "description": "The ID of a custom theme or a supported preset theme to set as active for the authenticated user, or the reserved sentinel \"default\" to revert to the built-in default (no custom theme).",
          "minLength": 1,
          "type": "string"
        }
--- pinned/test_run_cloudflow_flow
+++ observed/test_run_cloudflow_flow
  {
    "annotations": {
      "destructiveHint": true,
-   "description": "Manage CloudFlow. Runs a flow once as a test, and **accepts an unpublished (draft) flow** — unlike\n`actions/trigger`, which requires the flow to be published. Use this to verify a newly\nauthored or edited flow before publishing it.\n\nExecution is identical to a production run: the same graph, the same bound connections,\nthe same credentials, and the same approval behaviour. An approval-gated node still parks\nthe run and its side effect still waits for a real approval — there is no request that\nskips one.\n\nThe run is recorded as a test, so it does not appear in run history, does not count\ntowards dashboard statistics, does not become a dashboard widget's data source, and does\nnot consume a scheduled-run budget. It does hold the flow's concurrency lock, so a `409`\nis returned while the flow is already running.\n\nThe flow's first node must be a webhook, scheduled, or manual trigger.\n\nBefore dispatching, the flow is validated with the same checks publish applies — a draft\nhas never been through them. A flow that fails returns `422` listing every offending node\nat once, so all of them can be fixed in one pass.\n\nPoll the `Location` URL to follow the run and read what each node produced.\n\nPass `?dryRun=true` to validate the flow without starting a run. Generated codeNode code is frequently broken in ways that pass validation and fail silently at run time. Always export_cloudflow_flow and test-run the result, and check the per-node output, before reporting success.",
+   "description": "Manage CloudFlow. Runs a flow once as a test, and **accepts an unpublished (draft) flow** — unlike\n`actions/trigger`, which requires the flow to be published. Use this to verify a newly\nauthored or edited flow before publishing it.\n\nExecution is identical to a production run: the same graph, the same bound connections,\nthe same credentials, and the same approval behaviour. An approval-gated node still parks\nthe run and its side effect still waits for a real approval — there is no request that\nskips one.\n\nThe run is recorded as a test, so it does not appear in run history, does not count\ntowards dashboard statistics, does not become a dashboard widget's data source, and does\nnot consume a scheduled-run budget. It does hold the flow's concurrency lock, so a `409`\nis returned while the flow is already running.\n\nThe flow's first node must be a webhook, scheduled, or manual trigger.\n\nBefore dispatching, the flow is validated with the same checks publish applies — a draft\nhas never been through them. A flow that fails returns `422` listing every offending node\nat once, so all of them can be fixed in one pass.\n\nPoll the `Location` URL to follow the run and read what each node produced.\n\nPass `?dryRun=true` to validate the flow without starting a run. Generated codeNode code may fail silently or error at run time despite passing validation. With dryRun this call shows only that the flow is well-formed; without dryRun it executes real actions even on drafts. A completed run's per-node output (get_cloudflow_flow_run) shows whether it works. The current generated MCP schema exposes no arbitrary trigger payload field; the API uses an empty payload when omitted. Idempotency-Key is required even with dryRun. Same key/request replays within 24 hours; different request fails with 422, an in-progress match with 409. Dry-runs validate existing fingerprints without storing a replay. The API fingerprints MCP tracking parameters; a changed client/server version can cause a same-key conflict. Keep the original request context and key. If an HTTP failure has only generic text, do not infer a status or retry automatically.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/trigger_cloud_flow
+++ observed/trigger_cloud_flow
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow triggered",
-   "description": "Use this when the user wants to trigger an automated CloudFlow workflow by its flow ID. This executes automation that may modify cloud resources externally. Ask the user to confirm the flow ID and any parameters before executing. Do NOT use this for viewing CloudFlow definitions or checking available flows.",
+   "description": "Triggers a published CloudFlow with a webhook trigger by flow ID or trigger URL. Executes real actions immediately and returns executionLink. Drafts fail with 403, flows without a webhook trigger with 400, and already-running flows with 409. Manual or scheduled flows use trigger_cloudflow_flow instead. This may modify external cloud resources.",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "flowID": {
-         "description": "The ID of the CloudFlow flow to trigger",
+         "description": "The ID or CloudFlow trigger URL of a published flow with a webhook trigger.",
          "type": "string"
        },
        "requestBodyJson": {
-         "description": "Optional JSON object to pass as the request body to the flow if the flow requires it",
+         "additionalProperties": {},
+         "description": "Webhook payload passed to the flow. Defaults to an empty object.",
+         "propertyNames": {
+           "type": "string"
+         },
          "type": "object"
        }
      },
--- pinned/trigger_cloudflow_flow
+++ observed/trigger_cloudflow_flow
  {
    "annotations": {
      "destructiveHint": true,
-   "description": "Manage CloudFlow. Starts a run of a **published** flow whose first node is a webhook, scheduled, or manual\ntrigger. A draft flow is rejected with `422` — use `actions/test-run` to run one.\n\nNo `Idempotency-Key` is required. This is a state transition, not a resource creation.\n\nThe response is a snapshot taken at dispatch, so `status` is always `pending` and the\ntiming fields are not yet populated. Read the run back through\n`GET /cloudflow/v1/flows/{flowId}/runs/{runId}` to follow its progress.\n\nA flow holds a concurrency lock while it runs, so triggering one that is already running\nreturns `409` with the active run embedded in the problem body — no second lookup needed.",
+   "description": "Manage CloudFlow. Starts a run of a **published** flow whose first node is a webhook, scheduled, or manual\ntrigger. A draft flow is rejected with `422` — use `actions/test-run` to run one.\n\nNo `Idempotency-Key` is required. This is a state transition, not a resource creation.\n\nThe response is a snapshot taken at dispatch, so `status` is always `pending` and the\ntiming fields are not yet populated. Read the run back through\n`GET /cloudflow/v1/flows/{flowId}/runs/{runId}` to follow its progress.\n\nA flow holds a concurrency lock while it runs, so triggering one that is already running\nreturns `409` with the active run embedded in the problem body — no second lookup needed. The current generated MCP schema exposes no arbitrary trigger payload field; the API uses an empty payload when omitted. trigger_cloud_flow accepts a webhook payload for published webhook flows.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/update_alert
+++ observed/update_alert
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Alert updated",
-   "description": "Use this when the user wants to modify an existing cost alert. Supports partial updates. Ask the user to confirm changes before executing. Do NOT use this for creating new alerts (use create_alert) or budgets (use create_budget).",
+   "description": "Use this when the user wants to modify an existing cost alert. Supports partial updates, including name-only, recipients-only, or individual config fields. Omitted fields are preserved; scopes: [] clears scopes. Changes apply immediately. Do NOT use this for creating new alerts (use create_alert) or budgets (use create_budget).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Parameters that define when and how the alert is evaluated (required).",
+         "description": "Only configuration fields to change. Omitted fields are preserved; a supplied metric requires both type and value.",
          "properties": {
            "condition": {
-             "description": "Condition type (e.g., 'value', 'forecasted', 'percentage').",
+             "description": "Condition type; defaults to percentage-change on create. Omitted on update means unchanged.",
+             "enum": [
+               "value",
+               "percentage-change",
+               "forecast"
+             ],
              "type": "string"
            },
            "currency": {
-             "description": "Currency code. Accepted values: USD, ILS, EUR, AUD, CAD, GBP, DKK, NOK, SEK, BRL, SGD, MXN, CHF, MYR, TWD, EGP, ZAR, JPY, IDR, AED, THB, COP.",
+             "description": "Currency code; defaults to the customer's currency on create, unchanged when omitted on update. Accepted values: USD, ILS, EUR, AUD, CAD, GBP, DKK, NOK, SEK, BRL, SGD, MXN, CHF, MYR, TWD, EGP, ZAR, JPY, IDR, AED, THB, COP.",
              "enum": [
                "USD",
                "ILS",
-             "description": "The data source for the alert (e.g., 'billing').",
+             "description": "Data source; defaults to billing on create. Omitted on update means unchanged.",
+             "enum": [
+               "billing",
+               "billing-datahub",
+               "kubernetes-utilization",
+               "tokenomics"
+             ],
              "type": "string"
            },
            "evaluateForEach": {
-             "description": "The metric to evaluate (required). Object with 'type' and 'value' fields.",
+             "description": "The metric to evaluate; required on create. Object with 'type' and 'value' fields.",
              "properties": {
                "type": {
                  "description": "Metric type identifier (e.g., 'basic', 'custom', 'extended').",
-             "description": "Filters that define the scope of the alert.",
+             "description": "Filters that define the scope of the alert. On update, omit to preserve; [] clears the scopes.",
              "items": {
                "additionalProperties": false,
                "properties": {
-                   "description": "Filter mode. Accepted values: is, starts_with, ends_with, contains, regexp.",
+                   "description": "Filter mode; defaults to 'is' at the API. Accepted values: is, starts_with, ends_with, contains, regexp.",
                    "enum": [
                      "is",
                      "starts_with",
-                 "type",
-                 "mode"
+                 "type"
                ],
                "type": "object"
              },
-             "description": "The time interval to evaluate the condition (required). Accepted values: hour, day, week, month, quarter, year.",
+             "description": "The time interval to evaluate the condition; required on create. Accepted values: day, week, month, quarter, year.",
              "enum": [
-               "hour",
                "day",
                "week",
                "month",
-             "description": "The alert threshold value (required).",
+             "description": "The alert threshold value; required on create.",
              "type": "number"
            }
          },
-         "required": [
-           "metric",
-           "timeInterval",
-           "value"
-         ],
          "type": "object"
        },
        "id": {
-         "description": "List of email addresses to notify when the alert is triggered.",
+         "description": "Email addresses to notify when triggered. On create, defaults to the caller's email; omitted on update preserves recipients. The API requires at least one email or existing Slack destination.",
          "items": {
            "format": "email",
            "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
-       "id",
-       "config"
+       "id"
      ],
      "type": "object"
    },
--- pinned/update_allocation
+++ observed/update_allocation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Allocation updated",
-   "description": "Use this when the user wants to modify an existing cost allocation. Ask the user to confirm changes before executing. Do NOT use this for creating new allocations (use create_allocation) or viewing allocations (use list_allocations).",
+   "description": "Use this when the user wants to modify an existing cost allocation. Omitted fields are preserved. Use rule for an existing single allocation and rules for an existing group; the type cannot change. A supplied rules list replaces the entire group membership. Changes apply immediately. Do NOT use this for creating new allocations (use create_allocation) or viewing allocations (use list_allocations).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "description": {
-         "description": "Description of the allocation's purpose",
+         "description": "Description of the allocation. On update omission or an empty string preserves the stored description; the API does not support clearing it",
          "type": "string"
        },
        "id": {
+         "minLength": 1,
          "type": "string"
        },
        "name": {
-         "description": "Human-readable name of the allocation",
+         "description": "New name; omit to keep the current name.",
+         "minLength": 1,
          "type": "string"
        },
        "rule": {
+         "additionalProperties": false,
          "description": "A single allocation rule that defines one grouping. Provide this for a single-rule allocation. Mutually exclusive with 'rules'",
          "properties": {
            "components": {
+               "additionalProperties": false,
                "properties": {
                  "include_null": {
                    "description": "If true, include resources with no value for this dimension",
-                   "description": "Key of an existing dimension, label, or tag key",
+                   "description": "Key of an existing dimension, label or tag. For type allocation_rule, use key allocation_rule and existing rule IDs as values",
                    "type": "string"
                  },
                  "mode": {
-                   "description": "The matching mode for values",
+                   "description": "Required matching mode; regexp requires exactly one pattern in values and a dimension that supports regular expressions",
                    "enum": [
                      "is",
                      "contains",
-                     "ends_with"
+                     "ends_with",
+                     "regexp"
                    ],
                    "type": "string"
                  },
-                     "attribution_group",
+                     "allocation_rule",
                      "gke",
                      "gke_label"
                    ],
-             "description": "Logical formula combining components (e.g., 'A AND B')",
+             "description": "Logical formula combining components by array order: A is the first component, B the second (e.g., 'A AND B')",
              "type": "string"
            }
          },
+         "required": [
+           "components",
+           "formula"
+         ],
          "type": "object"
        },
        "rules": {
-         "description": "Ordered list of allocation rules for a group allocation. Must include at least two rules. Mutually exclusive with 'rule'",
+         "description": "Ordered list of at least two group rules. create creates a rule, update edits a rule, select includes it unchanged. On update this replaces the entire list; include every rule to retain. Mutually exclusive with rule; allocation type cannot change",
          "items": {
-           "properties": {
-             "action": {
-               "description": "Required action for this rule (e.g., 'create', 'update', 'select')",
-               "enum": [
-                 "create",
-                 "update",
-                 "select"
-               ],
-               "type": "string"
-             },
-             "components": {
-               "description": "Array of allocation components that define this rule",
-               "items": {
-                 "properties": {
-                   "include_null": {
-                     "description": "If true, include resources with no value for this dimension",
-                     "type": "boolean"
-                   },
-                   "inverse_selection": {
-                     "description": "If true, exclude matching values instead of including them",
-                     "type": "boolean"
-                   },
-                   "key": {
-                     "description": "Key of an existing dimension, label, or tag key",
-                     "type": "string"
-                   },
-                   "mode": {
-                     "description": "The matching mode for values",
-                     "enum": [
-                       "is",
-                       "contains",
-                       "starts_with",
-                       "ends_with"
+           "oneOf": [
+             {
+               "additionalProperties": false,
+               "properties": {
+                 "action": {
+                   "const": "create",
+                   "description": "Create a new rule and include it in the group; omit id.",
+                   "type": "string"
+                 },
+                 "components": {
+                   "description": "Array of allocation components that define this rule",
+                   "items": {
+                     "additionalProperties": false,
+                     "properties": {
+                       "include_null": {
+                         "description": "If true, include resources with no value for this dimension",
+                         "type": "boolean"
+                       },
+                       "inverse_selection": {
+                         "description": "If true, exclude matching values instead of including them",
+                         "type": "boolean"
+                       },
+                       "key": {
+                         "description": "Key of an existing dimension, label or tag. For type allocation_rule, use key allocation_rule and existing rule IDs as values",
+                         "type": "string"
+                       },
+                       "mode": {
+                         "description": "Required matching mode; regexp requires exactly one pattern in values and a dimension that supports regular expressions",
+                         "enum": [
+                           "is",
+                           "contains",
+                           "starts_with",
+                           "ends_with",
+                           "regexp"
+                         ],
+                         "type": "string"
+                       },
+                       "type": {
+                         "description": "The type of the component",
+                         "enum": [
+                           "datetime",
+                           "fixed",
+                           "optional",
+                           "label",
+                           "tag",
+                           "project_label",
+                           "system_label",
+                           "attribution",
+                           "allocation_rule",
+                           "gke",
+                           "gke_label"
+                         ],
+                         "type": "string"
+                       },
+                       "values": {
+                         "description": "Values to match against",
+                         "items": {
+                           "type": "string"
+                         },
+                         "type": "array"
+                       }
+                     },
+                     "required": [
+                       "key",
+                       "type",
+                       "values",
+                       "mode"
                      ],
-                     "type": "string"
+                     "type": "object"
                    },
-                   "type": {
-                     "description": "The type of the component",
-                     "enum": [
-                       "datetime",
-                       "fixed",
-                       "optional",
-                       "label",
-                       "tag",
-                       "project_label",
-                       "system_label",
-                       "attribution",
-                       "attribution_group",
-                       "gke",
-                       "gke_label"
+                   "type": "array"
+                 },
+                 "description": {
+                   "description": "Description of the new rule.",
+                   "type": "string"
+                 },
+                 "formula": {
+                   "description": "Logical formula combining components by array order: A is the first component, B the second (e.g., 'A AND B')",
+                   "type": "string"
+                 },
+                 "id": {
+                   "description": "Must be absent for create.",
+                   "not": {}
+                 },
+                 "name": {
+                   "description": "Required name for the new rule.",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "components",
+                 "formula",
+                 "action",
+                 "name"
+               ],
+               "type": "object"
+             },
+             {
+               "additionalProperties": false,
+               "properties": {
+                 "action": {
+                   "const": "update",
+                   "description": "Update an existing rule and include it in the group.",
+                   "type": "string"
+                 },
+                 "components": {
+                   "description": "Array of allocation components that define this rule",
+                   "items": {
+                     "additionalProperties": false,
+                     "properties": {
+                       "include_null": {
+                         "description": "If true, include resources with no value for this dimension",
+                         "type": "boolean"
+                       },
+                       "inverse_selection": {
+                         "description": "If true, exclude matching values instead of including them",
+                         "type": "boolean"
+                       },
+                       "key": {
+                         "description": "Key of an existing dimension, label or tag. For type allocation_rule, use key allocation_rule and existing rule IDs as values",
+                         "type": "string"
+                       },
+                       "mode": {
+                         "description": "Required matching mode; regexp requires exactly one pattern in values and a dimension that supports regular expressions",
+                         "enum": [
+                           "is",
+                           "contains",
+                           "starts_with",
+                           "ends_with",
+                           "regexp"
+                         ],
+                         "type": "string"
+                       },
+                       "type": {
+                         "description": "The type of the component",
+                         "enum": [
+                           "datetime",
+                           "fixed",
+                           "optional",
+                           "label",
+                           "tag",
+                           "project_label",
+                           "system_label",
+                           "attribution",
+                           "allocation_rule",
+                           "gke",
+                           "gke_label"
+                         ],
+                         "type": "string"
+                       },
+                       "values": {
+                         "description": "Values to match against",
+                         "items": {
+                           "type": "string"
+                         },
+                         "type": "array"
+                       }
+                     },
+                     "required": [
+                       "key",
+                       "type",
+                       "values",
+                       "mode"
                      ],
-                     "type": "string"
+                     "type": "object"
                    },
-                   "values": {
-                     "description": "Values to match against",
-                     "items": {
-                       "type": "string"
-                     },
-                     "type": "array"
-                   }
+                   "type": "array"
                  },
-                 "required": [
-                   "key",
-                   "type",
-                   "values",
-                   "mode"
-                 ],
-                 "type": "object"
+                 "description": {
+                   "description": "Description of the updated rule.",
+                   "type": "string"
+                 },
+                 "formula": {
+                   "description": "Logical formula combining components by array order: A is the first component, B the second (e.g., 'A AND B')",
+                   "type": "string"
+                 },
+                 "id": {
+                   "description": "Required ID of the existing rule to update.",
+                   "minLength": 1,
+                   "type": "string"
+                 },
+                 "name": {
+                   "description": "New name for the updated rule; omit to preserve its name.",
+                   "minLength": 1,
+                   "type": "string"
+                 }
                },
-               "type": "array"
-             },
-             "description": {
-               "description": "Description of the rule",
-               "type": "string"
-             },
-             "formula": {
-               "description": "Logical formula combining components (e.g., 'A AND B')",
-               "type": "string"
-             },
-             "id": {
-               "description": "Rule ID (for existing rules), required for 'update' and 'select' actions",
-               "type": "string"
+               "required": [
+                 "components",
+                 "formula",
+                 "action",
+                 "id"
+               ],
+               "type": "object"
              },
-             "name": {
-               "description": "Name of the rule",
-               "type": "string"
+             {
+               "additionalProperties": false,
+               "properties": {
+                 "action": {
+                   "const": "select",
+                   "description": "Include an existing rule unchanged; only id is needed.",
+                   "type": "string"
+                 },
+                 "id": {
+                   "description": "Required ID of the existing rule to select.",
+                   "minLength": 1,
+                   "type": "string"
+                 }
+               },
+               "required": [
+                 "action",
+                 "id"
+               ],
+               "type": "object"
              }
-           },
-           "type": "object"
+           ]
          },
+         "minItems": 2,
          "type": "array"
        },
        "unallocatedCosts": {
-         "description": "Custom label for values that do not fit into any allocation rule (required when using 'rules' for group allocations)",
+         "description": "Group-only label for unmatched costs. On update omission or null preserves the stored label; a string updates it independently of rules",
          "type": [
            "string",
            "null"
--- pinned/update_annotation
+++ observed/update_annotation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Annotation updated",
-   "description": "Use this when the user wants to modify an existing annotation. Ask the user to confirm changes before executing. Do NOT use this for creating new annotations (use create_annotation) or labels (use update_label).",
+   "description": "Use this when the user wants to modify an existing annotation. Nonempty content is required on every update. Omitted or null timestamp/reports/labels remain unchanged; reports and labels replace their lists, and [] clears them. Changes apply immediately. Do NOT use this for creating new annotations (use create_annotation) or labels (use update_label).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "anyOf": [
-           {
-             "minLength": 1,
-             "type": "string"
-           },
-           {
-             "type": "null"
-           }
-         ],
-         "description": "The content of the annotation. Set to null to clear. Must be non-empty if provided as a string."
+         "description": "Required nonempty content on every update, even when only changing associations or timestamp.",
+         "minLength": 1,
+         "type": "string"
        },
        "id": {
          "description": "The ID of the annotation to update (required).",
-         "description": "List of label IDs to associate with the annotation. Set to null to clear. Labels must already exist."
+         "description": "Replacement list of existing console label IDs. Omission or null leaves unchanged; [] clears all labels."
        },
        "reports": {
          "anyOf": [
-         "description": "List of report IDs to associate with the annotation. Set to null to clear."
+         "description": "Replacement list of report IDs. Omission or null leaves unchanged; [] clears all report associations."
        },
        "timestamp": {
          "anyOf": [
-             "format": "date-time",
+             "allOf": [
+               {
+                 "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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
+               },
+               {
+                 "pattern": "T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|[+-]\\d{2}:\\d{2})$"
+               }
+             ],
              "minLength": 1,
-             "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"
            },
            {
-         "description": "The date associated with the annotation in ISO 8601 date-time format. Set to null to clear."
+         "description": "RFC 3339 timestamp with seconds and Z or ±HH:MM timezone; fractional seconds are supported. Omit or set null to leave unchanged."
        }
      },
      "required": [
-       "id"
+       "id",
+       "content"
      ],
      "type": "object"
    },
--- pinned/update_budget
+++ observed/update_budget
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Budget updated",
-   "description": "Use this when the user wants to modify an existing budget. Supports partial updates. Ask the user to confirm the changes before executing. Do NOT use this for viewing budgets (use list_budgets) or creating new budgets (use create_budget).",
+   "description": "Use this when the user wants to modify an existing budget. Supports partial updates; omitted fields retain their current values. Setting type to fixed requires endPeriod; setting type to recurring requires timeInterval and forbids endPeriod; setting usePrevSpend to false requires amount. Changes apply immediately. Do NOT use this for viewing budgets (use list_budgets) or creating new budgets (use create_budget).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Budget period amount.",
+         "description": "Budget period amount; required when usePrevSpend is explicitly false. Omitted means unchanged.",
          "exclusiveMinimum": 0,
          "type": "number"
        },
-         "description": "Fixed budget end date as a UNIX timestamp in milliseconds. Must not be set for recurring budgets.",
+         "description": "Fixed budget end date as a UNIX timestamp in milliseconds. Required when setting type to fixed; must not be set for recurring budgets.",
          "maximum": 9007199254740991,
          "minimum": -9007199254740991,
          "type": "integer"
-         "description": "Periodical growth percentage in recurring budgets. Must be >= 0. Defaults to 0.",
+         "description": "Periodical growth percentage (>= 0); omitted means unchanged.",
          "minimum": 0,
          "type": "number"
        },
-         "description": "Budget metric. Accepted values: cost, amortized_cost. Defaults to cost.",
+         "description": "Budget metric: cost or amortized_cost; omitted means unchanged.",
          "enum": [
            "cost",
            "amortized_cost"
-         "description": "Budget start date as a UNIX timestamp in milliseconds.",
+         "description": "Budget start date as a UNIX timestamp in milliseconds, on or after 2018-01-01 UTC. Omitted means unchanged.",
          "maximum": 9007199254740991,
-         "minimum": -9007199254740991,
+         "minimum": 1514764800000,
          "type": "integer"
        },
        "timeInterval": {
-         "description": "Recurring budget interval. Accepted values: day, week, month, quarter, year.",
+         "description": "Recurring budget interval; required when setting type to recurring, ignored for fixed. Accepted values: day, week, month, quarter, year.",
          "enum": [
            "day",
            "week",
-         "description": "Budget type. Accepted values: fixed, recurring.",
+         "description": "Budget type. If supplied, fixed requires endPeriod and recurring requires timeInterval. Accepted values: fixed, recurring.",
          "enum": [
            "fixed",
            "recurring"
-         "description": "Use the last period's spend as the target amount for recurring budgets. Defaults to false.",
+         "description": "Use previous spend; omitted means unchanged. If false, also supply a positive amount.",
          "type": "boolean"
        }
      },
--- pinned/update_cloudflow_connection
+++ observed/update_cloudflow_connection
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow connection updated",
-   "description": "Use this when the user wants to update an existing CloudFlow cloud provider connection — rename it, change its description, enable/disable it, update its GCP/AWS configuration, or change collaborators. All fields except connectionId are optional; at most one of gcpConfig or awsConfig may be set per request. Ask the user to confirm the changes before executing. Do NOT use this to create a new connection (use create_cloudflow_connection) or to trigger a flow (use trigger_cloud_flow).",
+   "description": "Updates a CloudFlow connection immediately using connectionId and the last observed ETag (ifMatch). A stale ETag fails with 412. Other fields are optional; supplied gcpConfig/awsConfig and collaborators replace their stored values wholesale. Retain exactly one owner when replacing collaborators. At most one provider config may be supplied. Serialize updates because the API version check is not atomic with the write. If an HTTP failure has only generic text, do not infer its status or retry automatically.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Updated AWS configuration. At most one of gcpConfig or awsConfig may be set per request.",
+         "description": "Full replacement AWS configuration, not a merge. At most one of gcpConfig or awsConfig may be set per request.",
          "properties": {
            "context": {
              "description": "Per-account AWS context (account ID and regions).",
-         "description": "Updated list of collaborators and their roles on the connection.",
+         "description": "Full replacement list of collaborators and roles; retain exactly one owner. Omitted leaves unchanged; an empty list is invalid.",
          "items": {
            "additionalProperties": false,
            "properties": {
-         "description": "Updated GCP configuration. At most one of gcpConfig or awsConfig may be set per request.",
+         "description": "Full replacement GCP configuration, not a merge. At most one of gcpConfig or awsConfig may be set per request.",
          "properties": {
            "customRole": {
              "additionalProperties": false,
+       "ifMatch": {
+         "description": "ETag from the connection's last read or write response (etag), including quotes. Sent as If-Match; a stale version fails with 412. Wildcards are rejected. The API checks before writing; simultaneous updates can still race. Serialize updates and read the result before another change.",
+         "pattern": "^(?:W\\/)?\"[\\x21\\x23-\\x7e]+\"$",
+         "type": "string"
+       },
        "name": {
          "description": "New connection name.",
          "minLength": 1,
+       "ifMatch",
        "connectionId"
      ],
      "type": "object"
--- pinned/update_datahub_dataset
+++ observed/update_datahub_dataset
  {
    "_meta": {
      "openai/toolInvocation/invoked": "DataHub dataset updated",
-   "description": "Use this when the user wants to modify an existing DataHub dataset's description. The dataset name is required to identify the dataset; only the description can be changed. Ask the user to confirm the changes before executing. Do NOT use this for creating datasets (use create_datahub_dataset) or listing datasets (use list_datahub_datasets).",
+   "description": "Use this when the user wants to modify an existing DataHub dataset's description, displayName, or logoName. The dataset name identifies the dataset and cannot be changed. Omitted fields are kept; empty strings clear the supplied fields. At least one updatable field is required. Changes apply immediately. Do NOT use this for creating datasets (use create_datahub_dataset) or listing datasets (use list_datahub_datasets).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "The new description for the dataset. At least one updatable field (description) must be provided.",
+         "description": "New description. Omit to keep the stored value; an empty string clears it.",
          "type": "string"
        },
+       "displayName": {
+         "description": "Display name (up to 64 characters after trimming, no control characters). Omit to keep; an empty string clears it. Does not rename the dataset.",
+         "type": "string"
+       },
+       "logoName": {
+         "description": "Preset logo name: anthropic, atlassian, aws, azure, bifrost, chatgpt, cloudflare, copilot, figma, gcp, github, gitlab, hotjar, jira, litellm, miro, notion, slack, wordpress. Omit to keep; an empty string clears it.",
+         "type": "string"
+       },
        "name": {
          "description": "The name of the dataset to update (required). Used for identification; the name cannot be changed.",
          "type": "string"
--- pinned/update_folder
+++ observed/update_folder
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Folder updated",
-   "description": "Use this when the user wants to rename, re-describe, or move (reparent) an existing Cloud Analytics folder. Ask the user to confirm changes before executing. Note: if a sibling folder at the target parent already has the same name, the folder will be auto-renamed by the API. Do NOT use this for creating new folders (use create_folder) or updating reports (use update_report).",
+   "description": "Use this when the user wants to rename, re-describe, or move (reparent) an existing Cloud Analytics folder. Changes apply immediately. Auto-renaming on collision applies only when moving to another parent; a rename that collides with a sibling is rejected. Invalid parents and moves into self or a descendant are rejected. Do NOT use this for creating new folders (use create_folder) or updating reports (use update_report).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "New description for the folder. Set to null to clear.",
+         "description": "New description for the folder. Empty string clears; omission or null leaves unchanged.",
          "type": [
            "string",
            "null"
--- pinned/update_insight_status
+++ observed/update_insight_status
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insight status updated",
-   "description": "Use this when the user wants to change the display status of an existing insight (e.g. mark it acknowledged, in progress, optimized, or dismissed). Only insights owned by the 'public-api' source can be managed. When dismissing, an optional reason and comment can be supplied. Do NOT use this to edit an insight's title/description or create one (use post_insight_result).",
+   "description": "Use this when the user wants to change the display status of an existing insight (e.g. mark it acknowledged, in progress, optimized, or dismissed). This endpoint is deprecated but remains the safe choice for status-only changes because it preserves optional insight metadata; post_insight_result replaces it. Only insights owned by the 'public-api' source can be managed. When dismissing, dismissalDetails.reason is required; comment is optional. Do NOT use this to edit an insight's title/description or create one (use post_insight_result).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Details for why the insight was dismissed (only relevant when status is 'dismissed').",
+         "description": "Details for why the insight was dismissed; reason is required when status is 'dismissed'.",
          "properties": {
            "comment": {
              "description": "An optional free-text comment providing additional context.",
-         "description": "The source that owns the insight. Only 'public-api' insights can be managed via this endpoint.",
+         "description": "The source that owns the insight. Only 'public-api' insights can be managed via this endpoint; defaults to public-api.",
          "enum": [
            "public-api"
          ],
-         "description": "The new display status of the insight. Possible values: actionable, acknowledged, optimized, dismissed, in progress, upgrade needed, permissions needed.",
+         "description": "The new display status of the insight. Possible values: actionable, acknowledged, optimized, dismissed, in progress.",
          "enum": [
            "actionable",
            "acknowledged",
-           "optimized",
-           "dismissed",
            "in progress",
-           "upgrade needed",
-           "permissions needed"
+           "optimized",
+           "dismissed"
          ],
          "type": "string"
        }
--- pinned/update_label
+++ observed/update_label
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Label updated",
-   "description": "Use this when the user wants to modify an existing label. Supports partial updates. Ask the user to confirm changes before executing. Do NOT use this for creating new labels (use create_label) or annotations (use update_annotation).",
+   "description": "Use this when the user wants to modify an existing custom DoiT console label. Requires Cloud Analytics Admin; preset labels cannot be edited. Supports partial updates; null leaves a field unchanged. Changes apply immediately. Do NOT use this for creating new labels (use create_label) or annotations (use update_annotation).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-             "description": "The color of the label (required). Accepted values: blue, skyBlue, teal, mint, lime, softYellow, apricot, lavender, purple, rosePink, slateGrey.",
              "enum": [
                "blue",
                "skyBlue",
-         "description": "The color of the label. Accepted values: blue, skyBlue, teal, mint, lime, softYellow, apricot, lavender, purple, rosePink, slateGrey, or null to clear."
+         "description": "The color of the label. Accepted values: blue, skyBlue, teal, mint, lime, softYellow, apricot, lavender, purple, rosePink, slateGrey. Omission or null leaves unchanged."
        },
        "id": {
          "description": "The ID of the label to update (required).",
-             "description": "The name of the label (required, non-empty).",
              "minLength": 1,
              "type": "string"
            },
-         "description": "The name of the label. Must be non-empty if provided, or null to clear."
+         "description": "The name of the label. Must be non-empty and unique if provided; omission or null leaves unchanged."
        }
      },
      "required": [
--- pinned/update_report
+++ observed/update_report
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Report updated",
-   "description": "Use this when the user wants to modify an existing saved Cloud Analytics report. Supports partial updates. Ask the user to confirm changes before executing. Do NOT use this for running ad-hoc queries (use run_query).",
+   "description": "Use this when the user wants to modify an existing saved Cloud Analytics report. Only custom reports the caller can edit are supported. Supports partial updates with array replacement and config reset semantics described on config. Omitted top-level fields are unchanged; labels replaces non-system labels. Changes apply immediately. Do NOT use this for running ad-hoc queries (use run_query).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-         "description": "Configuration for the report. Only specified fields will be updated. Use the dimension tool to look up valid dimension IDs.",
+         "description": "Partial configuration. Supplied filters, group, dimensions, and splits arrays replace stored arrays ([] clears); non-empty metrics replaces metrics ([] leaves it unchanged). Any config without dataSource resets the source to billing or billing-datahub according to customer defaults. timeInterval with dimensions omitted resets time columns. Switching to custom mode requires explicit or valid stored custom dates. A date-only patch requires a stored custom mode. Valid dimension IDs come from list_dimensions or get_dimension.",
          "properties": {
            "advancedAnalysis": {
              "additionalProperties": false,
-             "description": "Custom time range. Only use when timeRange mode is 'custom'.",
+             "description": "Explicit dates, alongside timeRange (not nested inside it). Required for new custom queries/reports and when switching a saved relative report to custom mode. On update, omitted dates can reuse valid stored custom dates; omitted timeRange requires a stored custom mode. The API uses inclusive UTC calendar days.",
              "properties": {
                "from": {
-                 "description": "Start timestamp in RFC3339 format. Example: '2024-03-10T23:00:00Z'.",
+                 "description": "Start timestamp in RFC3339 format, with Z or a UTC offset. The API uses the UTC calendar 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "type": "string"
                },
                "to": {
-                 "description": "End timestamp in RFC3339 format. Example: '2024-03-12T23:00:00Z'.",
+                 "description": "End timestamp in RFC3339 format, with Z or a UTC offset. The API includes this UTC calendar 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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
                  "type": "string"
                }
              },
-             "description": "Data source for the report. Accepted values: billing, bqlens, billing-datahub, kubernetes-utilization.",
+             "description": "Data source; defaults to billing, or billing-datahub when the customer has DataHub metrics. Accepted values: billing, bqlens, billing-datahub, kubernetes-utilization.",
              "enum": [
                "billing",
                "bqlens",
-                   "description": "Dimension identifier. Use the dimension tool to get valid IDs.",
+                   "description": "Dimension identifier. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "type": {
-                   "description": "The field to filter on. Use the dimension tool to get valid IDs.",
+                   "description": "The field to filter on. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "inverse": {
-                   "description": "Filter match mode. Accepted values: is, starts_with, ends_with, contains, regexp.",
+                   "description": "Filter match mode. Defaults to 'is' (exact match). Accepted values: is, starts_with, ends_with, contains, regexp.",
                    "enum": [
                      "is",
                      "starts_with",
-                   "description": "Values to filter on.",
+                   "description": "Stored dimension values to match exactly in 'is' mode (case-sensitive): provider IDs for cloud_provider, service names for service_description. get_dimension returns available values.",
                    "items": {
                      "type": "string"
                    },
-                 "type",
-                 "mode"
+                 "type"
                ],
                "type": "object"
              },
-                   "description": "Dimension ID for the group-by row. Use the dimension tool to get valid IDs.",
+                   "description": "Dimension ID for the group-by row. Valid IDs come from list_dimensions or get_dimension.",
                    "type": "string"
                  },
                  "limit": {
-                   "description": "Limit to top/bottom N results.",
+                   "description": "Select top/bottom N values of this dimension per parent group, ranked across the query range. Time dimensions still split result rows.",
                    "properties": {
                      "metric": {
                        "additionalProperties": false,
-                       "description": "Number of items to show.",
+                       "description": "Number of dimension values to select per parent group, not a cap on returned rows; time dimensions can produce multiple rows per selected value.",
                        "maximum": 9007199254740991,
                        "minimum": -9007199254740991,
                        "type": "integer"
-             "description": "Report layout / visualization type. Accepted values: column_chart, stacked_column_chart, bar_chart, stacked_bar_chart, line_chart, spline_chart, area_chart, area_spline_chart, stacked_area_chart, treemap_chart, table, table_heatmap, table_row_heatmap, table_col_heatmap, csv_export, sheets_export.",
+             "description": "Report layout / visualization type. Accepted values: column_chart, stacked_column_chart, bar_chart, stacked_bar_chart, line_chart, spline_chart, area_chart, area_spline_chart, stacked_area_chart, treemap_chart, table, table_heatmap, table_row_heatmap, table_col_heatmap, sankey_chart, column_and_line_chart, trend_board, cumulative_comparison.",
              "enum": [
                "column_chart",
                "stacked_column_chart",
-               "csv_export",
-               "sheets_export"
+               "sankey_chart",
+               "column_and_line_chart",
+               "trend_board",
+               "cumulative_comparison"
              ],
              "type": "string"
            },
-             "description": "List of metrics to apply (max 4). Preferred over the deprecated 'metric' field.",
+             "description": "List of metrics to apply (max 4). Defaults to basic cost on new reports/queries. Non-empty arrays replace stored metrics on update; [] leaves metrics unchanged. Preferred over the deprecated 'metric' field.",
              "items": {
                "additionalProperties": false,
                "properties": {
-             "description": "Time interval for grouping data. Accepted values: hour, day, dayCumSum, week, isoweek, month, quarter, year, week_day.",
+             "description": "Time interval for grouping data (default day). On update, supplying this with dimensions omitted resets time columns to this interval. Accepted values: hour, day, dayCumSum, week, isoweek, month, quarter, year, week_day.",
              "enum": [
                "hour",
                "day",
-             "description": "Time range for the report. Preferred over customTimeRange.",
+             "description": "Time range; defaults to the last 7 days including today on new reports/queries. For custom dates use {mode: 'custom'} and sibling config.customTimeRange.",
              "properties": {
                "amount": {
-                 "description": "Number of time units (0–5000). Required when mode is 'last'.",
+                 "description": "Number of calendar periods (0–5000). Required for 'last'.",
                  "maximum": 5000,
                  "minimum": 0,
                  "type": "integer"
-               "customTimeRange": {
-                 "additionalProperties": false,
-                 "description": "Custom date range. Required when mode is 'custom'.",
-                 "properties": {
-                   "from": {
-                     "description": "Start date in RFC3339 format.",
-                     "type": "string"
-                   },
-                   "to": {
-                     "description": "End date in RFC3339 format.",
-                     "type": "string"
-                   }
-                 },
-                 "required": [
-                   "from",
-                   "to"
-                 ],
-                 "type": "object"
-               },
                "includeCurrent": {
-                 "description": "Whether to include the current (in-progress) period.",
+                 "description": "For 'last', true includes the current partial period in amount; false (default) selects completed periods. With amount 1 and unit month, true means month-to-date and false means the previous full month. Ignored for 'current' and 'custom'.",
                  "type": "boolean"
                },
                "mode": {
-                 "description": "Time range mode. Accepted values: last, current, custom. Use 'custom' with customTimeRange for specific dates.",
+                 "description": "Time range mode: 'last' selects N calendar periods; 'current' selects the current calendar period through its end; 'custom' requires dates in config.customTimeRange, alongside timeRange.",
                  "enum": [
                    "last",
                    "current",
-                 "description": "Time unit. Accepted values: day, week, month, quarter, year. Required when mode is 'last'.",
+                 "description": "Time unit. Accepted values: day, week, month, quarter, year. Required for 'last' and 'current'; forbidden for 'custom'.",
                  "enum": [
                    "day",
                    "week",
-         "description": "Array of label IDs to assign to the report.",
+         "description": "Replaces non-system DoiT console labels; [] clears them, omission preserves them. System labels are rejected.",
          "items": {
            "type": "string"
          },
--- pinned/update_resource_permissions
+++ observed/update_resource_permissions
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Resource permissions updated",
-   "description": "Use this when the user wants to change who a Cloud Analytics resource is shared with or update access levels. Updates the sharing settings (per-user roles and/or public visibility) for a specific alert, budget, report, or allocation. Requires resourceType and resourceId; at least one of permissions or public should be provided. Do NOT use this to view current permissions (use get_resource_permissions).",
+   "description": "Use this when the user wants to change who a Cloud Analytics resource is shared with or update access levels. Replaces sharing settings with PUT for a specific alert, budget, custom report, or allocation. Requires resourceType, resourceId and a nonempty permissions list with exactly one owner. Read current permissions first and retain all intended entries. Only the current owner or a user with Ownership assignment permission may transfer ownership. Omitted public makes reports, alerts and budgets private; allocations reject omitted/null public. Do NOT use this to view current permissions (use get_resource_permissions).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {
        "permissions": {
-         "description": "List of per-user permission entries to set. Each entry has a user (email) and a role (owner, editor, or viewer).",
+         "description": "Required nonempty replacement list, not a merge. Include every permission to retain and exactly one owner.",
          "items": {
+           "additionalProperties": false,
            "properties": {
              "role": {
                "description": "Role to grant: owner, editor, or viewer.",
-               "description": "Email address of the user.",
+               "description": "Email in an organization or DoiT domain; Slack/Teams addresses may only be viewers.",
                "type": "string"
              }
            },
+         "minItems": 1,
          "type": "array"
        },
        "public": {
-         "description": "Public visibility level. Set to 'editor' or 'viewer' to share with all users, or null to make private.",
-         "enum": [
-           "editor",
-           "viewer",
-           null
+         "anyOf": [
+           {
+             "enum": [
+               "editor",
+               "viewer"
+             ],
+             "type": "string"
+           },
+           {
+             "type": "null"
+           }
          ],
-         "type": [
-           "string",
-           "null"
-         ]
+         "description": "Public visibility: editor or viewer shares with all users in the organization. For reports, alerts and budgets, omission or null makes the resource private; omission does not preserve prior public access. Allocations require editor or viewer and reject omission/null."
        },
        "resourceId": {
          "description": "The ID of the resource (alert, budget, report, or allocation) to update permissions for.",
-       "resourceId"
+       "resourceId",
+       "permissions"
      ],
      "type": "object"
    },
--- pinned/update_theme
+++ observed/update_theme
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Theme updated",
-   "description": "Use this when the user wants to modify an existing custom color theme — rename it, change its primary color, or update its color palette. Accepts either the theme ID or a partial name match. Ask the user to confirm changes before executing. Do NOT use this for creating a new theme or changing which theme is active (use set_active_theme).",
+   "description": "Use this when the user wants to modify an existing custom color theme — rename it, change its primary color, or update its color palette. Accepts either the theme ID or a partial name match across all custom themes; ambiguous matches return an error, and id takes precedence. Requires Cloud Analytics Admin; preset themes cannot be updated. Changes apply immediately to all users who have this theme active. Omitted fields are preserved; colors replaces both palettes. Create new themes with create_custom_theme; change the current user's active theme with set_active_theme.",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
-             "description": "Array of hex color values for dark mode.",
+             "description": "Replacement dark palette: 1-32 colors in #RGB, #RRGGBB or #RRGGBBAA format.",
              "items": {
+               "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
                "type": "string"
              },
+             "maxItems": 32,
+             "minItems": 1,
              "type": "array"
            },
            "light": {
-             "description": "Array of hex color values for light mode.",
+             "description": "Replacement light palette: 1-32 colors in #RGB, #RRGGBB or #RRGGBBAA format.",
              "items": {
+               "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
                "type": "string"
              },
+             "maxItems": 32,
+             "minItems": 1,
              "type": "array"
            }
          },
-         "description": "Partial name match (case-insensitive) used to find the theme when ID is unknown.",
+         "description": "Case-insensitive substring search across all custom themes. Multiple matches return an ambiguity error listing names; id takes precedence.",
          "type": "string"
        },
        "newName": {
-         "description": "New display name for the theme.",
+         "description": "New display name for the theme (1-200 characters). Omit to preserve.",
+         "maxLength": 200,
          "minLength": 1,
          "type": "string"
        },
-         "description": "New primary hex color for the theme (e.g. #1A73E8).",
+         "description": "New primary color: #RGB, #RRGGBB or #RRGGBBAA. Omit to preserve.",
+         "pattern": "^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$",
          "type": "string"
        }
      },
--- pinned/update_user
+++ observed/update_user
  {
    "_meta": {
      "openai/toolInvocation/invoked": "User updated",
-   "description": "Use this when the user wants to update a user's information such as name, job function, phone, language, or role. Ask the user to confirm the changes before executing. Do NOT use this for inviting new users (use invite_user) or listing users (use list_users).",
+   "description": "Use this when the user wants to update a user's information such as name, job function, phone, language, or role. Changes apply immediately. Do NOT use this for inviting new users (use invite_user) or listing users (use list_users).",
    "inputSchema": {
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
--- pinned/validate_user
+++ observed/validate_user
  {
    "_meta": {
      "openai/toolInvocation/invoked": "User validated",
-   "description": "Use this ONLY when the user explicitly asks to verify their account connection or check who they are logged in as. Do NOT call this proactively before other tool calls — the OAuth token already guarantees the user is authenticated. Do NOT use this for listing users in the organization (use list_users).",
+   "description": "Use this when the user asks to verify their account connection or check who they are logged in as. Returns the authenticated user's email and the primary domain of the customer the session is scoped to. Authentication is already established by the connection, so other tools do not depend on this call. Do NOT use this for listing users in the organization (use list_users).",
    "inputSchema": {
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
+     "additionalProperties": false,
      "properties": {},
      "type": "object"
    },

tool removed: search_customers

Changed 2026-10-05 14:22 UTC

6 descriptions rewritten, 182 schema or annotation changes with the description left byte-identical, 51 tools added.

--- pinned/accept_budget_suggestion
+++ observed/accept_budget_suggestion
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "budgetId": {
-   ]
+   ],
+   "title": "Accept a budget suggestion"
  }
--- pinned/add_ticket_tags
+++ observed/add_ticket_tags
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Add tags to a support request"
  }
--- pinned/ask_ava_sync
+++ observed/ask_ava_sync
  {
    "_meta": {
      "openai/toolInvocation/invoked": "AVA responded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "conversationId": {
-   ]
+   ],
+   "title": "Ask Ava"
  }

+ tool added: assign_contract_template

+ tool added: assign_customer_group_user

--- pinned/assign_objects_to_label
+++ observed/assign_objects_to_label
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Assignments updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "add": {
-               "allOf": [
-                 {
-                   "type": "string"
-                 },
-                 {
-                   "minLength": 1,
-                   "type": "string"
-                 }
-               ],
-               "description": "The ID of the object."
+               "description": "The ID of the object.",
+               "type": "string"
              },
              "objectType": {
                "description": "The type of the object. Accepted values: alert, allocation, budget, metric, report, annotation.",
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the label to assign or unassign objects to."
+         "description": "The ID of the label to assign or unassign objects to.",
+         "type": "string"
        },
        "remove": {
          "description": "Array of objects to unassign from the label. Each object must have objectId and objectType.",
-           "$ref": "#/properties/add/items"
+           "additionalProperties": false,
+           "properties": {
+             "objectId": {
+               "description": "The ID of the object.",
+               "type": "string"
+             },
+             "objectType": {
+               "description": "The type of the object. Accepted values: alert, allocation, budget, metric, report, annotation.",
+               "enum": [
+                 "alert",
+                 "allocation",
+                 "budget",
+                 "metric",
+                 "report",
+                 "annotation"
+               ],
+               "type": "string"
+             }
+           },
+           "required": [
+             "objectId",
+             "objectType"
+           ],
+           "type": "object"
          },
          "type": "array"
        }
-   ]
+   ],
+   "title": "Assign objects to label"
  }
--- pinned/async_run_inline
+++ observed/async_run_inline
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "Idempotency-Key": {
-             ],
-             "description": "Forecast configuration. On PATCH, omit to preserve existing settings; send null to clear/disable forecasting."
+             ]
            },
            "group": {
              "description": "The rows that appear in the tabular format of the report. See [Group by](https://help.doit.com/docs/cloud-analytics/reports/editing-your-cloud-report#group-by).",
-                   "description": "To limit the number of results based on ranking. See [Limit by top/bottom](https://help.doit.com/docs/cloud-analytics/reports/editing-your-cloud-report#limit-by-topbottom).",
+                   "description": "To limit the number of results based on ranking. See [Limit by rank](https://help.doit.com/docs/cloud-analytics/reports/editing-your-cloud-report#limit-by-topbottom).",
                    "properties": {
                      "metric": {
                        "additionalProperties": false,
-             "description": "Type of visualization or output format.",
+             "description": "Type of visualization or output format. cumulative_comparison requires daily datetime dimensions (year, month, day), total aggregation, one metric, a secondary time range, and no comparative or forecast.",
              "enum": [
                "column_chart",
                "stacked_column_chart",
+               "sankey_chart",
                "table",
                "table_heatmap",
                "table_row_heatmap",
-               "csv_export",
-               "sheets_export"
+               "column_and_line_chart",
+               "trend_board",
+               "cumulative_comparison"
              ],
              "type": "string"
            },
-             "description": "Limit by change filter. A report may configure at most two of\n`metricFilter`, `limitByChange`, and top/bottom `group` limits — not all three.",
+             "description": "Limit by change filter. A report may configure at most two of\n`metricFilter`, `limitByChange`, and rank `group` limits — not all three.",
              "properties": {
                "changeType": {
                  "enum": [
-                 "description": "Comparison operator for period-over-period deltas.",
+                 "description": "Comparison operator for period-over-period deltas: `gt` (Greater Than), `gte`\n(Greater Than or Equals), `lt` (Less Than), `lte` (Less Than or Equals), `b`\n(Between), `nb` (Not Between).",
                  "enum": [
-                   ">",
-                   ">=",
-                   "<",
-                   "<=",
-                   "between",
-                   "not_between"
+                   "gt",
+                   "gte",
+                   "lt",
+                   "lte",
+                   "b",
+                   "nb"
                  ],
                  "type": "string"
                },
-                 "description": "Threshold value(s). Unary operators use one entry; `between` and `not_between`\nrequire two ordered entries.",
+                 "description": "Threshold value(s). Unary operators (`gt`, `gte`, `lt`, `lte`) use one entry; the range\noperators (`b`, `nb`) require two ordered entries.",
                  "items": {
                    "type": "number"
                  },
-           "metric": {
-             "additionalProperties": false,
-             "description": "Deprecated: Use 'metrics' instead.",
-             "properties": {
-               "type": {
-                 "description": "Type of metric to use.",
-                 "enum": [
-                   "basic",
-                   "custom",
-                   "extended"
-                 ],
-                 "type": "string"
-               },
-               "value": {
-                 "description": "For basic metrics, the value can be one of: [\"cost\", \"usage\", \"savings\"]\nIf using custom metrics, the value must refer to an existing custom metric ID.",
-                 "type": "string"
-               }
-             },
-             "required": [
-               "type",
-               "value"
-             ],
-             "type": "object"
-           },
            "metricFilter": {
              "additionalProperties": false,
              "description": "Metric filter to limit report rows by metric value.",
-                 "description": "Comparison operator for filtering metric values. Uses short names (`gt`, `gte`, …).\n`limitByChange.operator` uses SQL-style symbols (`>`, `>=`, …) instead.",
+                 "description": "Comparison operator for filtering metric values: `gt` (Greater Than), `lt` (Less\nThan), `lte` (Less Than or Equals), `gte` (Greater Than or Equals), `b` (Between),\n`nb` (Not Between), `e` (Equals), `ne` (Not Equals).",
                  "enum": [
                    "gt",
                    "lt",
-   ]
+   ],
+   "title": "Run a report asynchronously"
  }
--- pinned/async_run_report_by_id
+++ observed/async_run_report_by_id
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "Idempotency-Key": {
-   ]
+   ],
+   "title": "Run a saved report asynchronously"
  }
--- pinned/ava_feedback
+++ observed/ava_feedback
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "answerId": {
-   ]
+   ],
+   "title": "Submit feedback"
  }
--- pinned/build_cloud_flow
+++ observed/build_cloud_flow
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow built",
-     "destructiveHint": false,
+     "destructiveHint": true,
      "openWorldHint": true,
      "readOnlyHint": false
    },
-   "description": "Use this when the user wants to build a brand-new CloudFlow automation from scratch using natural language. Streams real-time progress while the AI builds the flow, then returns the newly created flow's ID, the builder's answer, and the build steps that ran. Use refine_cloudflow to change an existing flow; use this only to create a new one.",
+   "description": "Use this when the user wants to build a brand-new CloudFlow automation from scratch using natural language. Streams real-time progress while the AI builds the flow, then returns the newly created flow's ID, the builder's answer, and the build steps that ran. Use refine_cloudflow to change an existing flow; use this only to create a new one. Generated codeNode code is frequently broken in ways that pass validation and fail silently at run time. Always export_cloudflow_flow and test-run the result, and check the per-node output, before reporting success.",
    "inputSchema": {
      "properties": {
        "conversationId": {
-   ]
+   ],
+   "title": "Build CloudFlow flow"
  }
--- pinned/cancel_async_operation
+++ observed/cancel_async_operation
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "Idempotency-Key": {
-   ]
+   ],
+   "title": "Cancel an async report run operation"
  }
--- pinned/cancel_invite
+++ observed/cancel_invite
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "Idempotency-Key": {
-   ]
+   ],
+   "title": "Cancel invite"
  }
--- pinned/compare_spend
+++ observed/compare_spend
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Spend comparison ready",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "cloud": {
-   ]
+   ],
+   "title": "Compare spend"
  }
--- pinned/confirm_action
+++ observed/confirm_action
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Action confirmed",
-     "destructiveHint": false,
+     "destructiveHint": true,
      "openWorldHint": true,
      "readOnlyHint": false
    },
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "token": {
-   ]
+   ],
+   "title": "Confirm pending action"
  }
--- pinned/cost_breakdown
+++ observed/cost_breakdown
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Cost breakdown ready",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "cloud": {
-   ]
+   ],
+   "title": "Cost breakdown"
  }
--- pinned/cost_trend
+++ observed/cost_trend
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Cost trend ready",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "cloud": {
-   ]
+   ],
+   "title": "Cost trend"
  }
--- pinned/create_account_role
+++ observed/create_account_role
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "accountID": {
-   ]
+   ],
+   "title": "Create or update an AWS account role"
  }
--- pinned/create_alert
+++ observed/create_alert
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Alert created",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "config": {
+           "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "type": "string"
          },
          "type": "array"
-   ]
+   ],
+   "title": "Create alert"
  }
--- pinned/create_allocation
+++ observed/create_allocation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Allocation created",
-   ]
+   ],
+   "title": "Create allocation"
  }
--- pinned/create_annotation
+++ observed/create_annotation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Annotation created",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "content": {
+         "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"
        }
      },
-   ]
+   ],
+   "title": "Create annotation"
  }
--- pinned/create_asset
+++ observed/create_asset
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "accountName": {
-   ]
+   ],
+   "title": "Create an asset"
  }
--- pinned/create_budget
+++ observed/create_budget
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Budget created",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "alerts": {
+               "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
                "type": "string"
              },
              "role": {
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "growthPerPeriod": {
+           "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "type": "string"
          },
          "type": "array"
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "timeInterval": {
-   ]
+   ],
+   "title": "Create budget"
  }
--- pinned/create_cloudflow_connection
+++ observed/create_cloudflow_connection
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow connection created",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "awsConfig": {
+             "propertyNames": {
+               "type": "string"
+             },
              "type": "object"
            },
            "roleName": {
+               "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
                "type": "string"
              },
              "role": {
-   ]
+   ],
+   "title": "Create CloudFlow connection"
  }
--- pinned/create_custom_theme
+++ observed/create_custom_theme
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "colors": {
-   ]
+   ],
+   "title": "Create a custom theme"
  }

+ tool added: create_customer_group

--- pinned/create_datahub_dataset
+++ observed/create_datahub_dataset
  {
    "_meta": {
      "openai/toolInvocation/invoked": "DataHub dataset created",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "description": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "pattern": "^[a-zA-Z0-9_-]+( [a-zA-Z0-9_-]+)*$",
-             "type": "string"
-           }
-         ],
-         "description": "The name of the dataset (required). Allowed characters: alphanumeric (0-9,a-z,A-Z), underscore (_), dash (-), and spaces between words."
+         "description": "The name of the dataset (required). Allowed characters: alphanumeric (0-9,a-z,A-Z), underscore (_), dash (-), and spaces between words.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Create DataHub dataset"
  }
--- pinned/create_folder
+++ observed/create_folder
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Folder created",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "description": {
-   ]
+   ],
+   "title": "Create folder"
  }
--- pinned/create_geographic_access_custom_region
+++ observed/create_geographic_access_custom_region
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Create a custom region"
  }
--- pinned/create_label
+++ observed/create_label
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Label created",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "color": {
-   ]
+   ],
+   "title": "Create label"
  }
--- pinned/create_report
+++ observed/create_report
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Report created",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "config": {
-                           "$ref": "#/properties/config/properties/metrics/items/properties/type"
+                           "description": "Metric type. Accepted values: basic, custom, extended.",
+                           "enum": [
+                             "basic",
+                             "custom",
+                             "extended"
+                           ],
+                           "type": "string"
                          },
                          "value": {
-                           "$ref": "#/properties/config/properties/metrics/items/properties/value"
+                           "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                           "type": "string"
                          }
                        },
                        "required": [
+                       "maximum": 9007199254740991,
+                       "minimum": -9007199254740991,
                        "type": "integer"
                      }
                    },
-             "$ref": "#/properties/config/properties/metrics/items",
-             "description": "Deprecated: use 'metrics' instead."
+             "additionalProperties": false,
+             "description": "Deprecated: use 'metrics' instead.",
+             "properties": {
+               "type": {
+                 "description": "Metric type. Accepted values: basic, custom, extended.",
+                 "enum": [
+                   "basic",
+                   "custom",
+                   "extended"
+                 ],
+                 "type": "string"
+               },
+               "value": {
+                 "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                 "type": "string"
+               }
+             },
+             "required": [
+               "type",
+               "value"
+             ],
+             "type": "object"
            },
            "metricFilter": {
              "additionalProperties": false,
-                     "$ref": "#/properties/config/properties/metrics/items/properties/type"
+                     "description": "Metric type. Accepted values: basic, custom, extended.",
+                     "enum": [
+                       "basic",
+                       "custom",
+                       "extended"
+                     ],
+                     "type": "string"
                    },
                    "value": {
-                     "$ref": "#/properties/config/properties/metrics/items/properties/value"
+                     "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                     "type": "string"
                    }
                  },
                  "required": [
+                 "maximum": 9007199254740991,
                  "minimum": 0,
                  "type": "integer"
                },
-   ]
+   ],
+   "title": "Create report"
  }

+ tool added: create_role

+ tool added: create_service_account

+ tool added: create_service_account_token

+ tool added: create_signup_request

+ tool added: create_signup_session

--- pinned/create_ticket
+++ observed/create_ticket
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Ticket created",
-   ]
+   ],
+   "title": "Create support ticket"
  }
--- pinned/create_ticket_comment
+++ observed/create_ticket_comment
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Comment added",
-     "destructiveHint": false,
+     "destructiveHint": true,
      "openWorldHint": true,
      "readOnlyHint": false
    },
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "body": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The text content of the comment (required, must be non-empty)."
+         "description": "The text content of the comment (required, must be non-empty).",
+         "type": "string"
        },
        "private": {
          "description": "If true, creates a private internal note. Only honored for DoiT employees; ignored for customers.",
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "pattern": "^\\d+$",
-             "type": "string"
-           }
-         ],
-         "description": "The numeric ID of the support ticket to add a comment to."
+         "description": "The numeric ID of the support ticket to add a comment to.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Add ticket comment"
  }
--- pinned/datahub_events_csv_file
+++ observed/datahub_events_csv_file
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
+       "periodEnd": {
+         "description": "Inclusive last day of the report period (YYYY-MM-DD). Events are booked on this day.",
+         "type": "string"
+       },
+       "periodStart": {
+         "description": "Inclusive first day of the report period (YYYY-MM-DD). Required for template uploads whose filename does not carry the period; when both are present they must agree.",
+         "type": "string"
+       },
        "provider": {
          "description": "The identifier of the data provider. Allowed characters: alphanumeric (0-9,a-z,A-Z), underscore (_), space, dash (-).",
          "type": "string"
+       },
+       "replace": {
+         "description": "Template uploads only. When `true`, active batches whose report period overlaps this upload are soft-deleted before the new file is ingested, and their ids are returned in `replacedBatches`. Refused with `409` when an overlapping batch extends outside the requested period (so a one-day replacement can never remove a wider upload) or was ingested less than 90 minutes ago (`Retry-After` header set). Without `replace`, any overlap is rejected with `409`.",
+         "type": "boolean"
+       },
+       "schemaTemplate": {
+         "description": "Versioned schema template of the file. Defaults to the dataset's template (`default@1` for datasets created without one). Provider-native templates such as `anthropic-spend-report@1` and `codex-usage-report@1` validate the vendor's own columns and normalize them into DataHub events. Must match the template stored on the dataset.",
+         "type": "string"
        }
      },
      "type": "object"
-   ]
+   ],
+   "title": "Ingest CSV file"
  }

+ tool added: datahub_import_provider_records

--- pinned/delete_account_role
+++ observed/delete_account_role
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "accountID": {
-   ]
+   ],
+   "title": "Delete an AWS account role"
  }
--- pinned/delete_alert
+++ observed/delete_alert
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete an alert"
  }
--- pinned/delete_allocation
+++ observed/delete_allocation
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete an allocation"
  }
--- pinned/delete_annotation
+++ observed/delete_annotation
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete an annotation"
  }
--- pinned/delete_ava_conversation
+++ observed/delete_ava_conversation
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "conversationId": {
-   ]
+   ],
+   "title": "Delete a conversation"
  }
--- pinned/delete_budget
+++ observed/delete_budget
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete a budget"
  }
--- pinned/delete_cloudflow_connection
+++ observed/delete_cloudflow_connection
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "connectionId": {
-   ]
+   ],
+   "title": "Delete a connection"
  }
--- pinned/delete_custom_theme
+++ observed/delete_custom_theme
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete a custom theme"
  }
--- pinned/delete_customer_geographic_access_scope
+++ observed/delete_customer_geographic_access_scope
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Clear a customer's geographic scope"
  }

+ tool added: delete_customer_group

--- pinned/delete_datahub_dataset
+++ observed/delete_datahub_dataset
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete a dataset"
  }
--- pinned/delete_datahub_datasets
+++ observed/delete_datahub_datasets
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete datasets"
  }
--- pinned/delete_datahub_events_by_filter
+++ observed/delete_datahub_events_by_filter
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete specific events"
  }
--- pinned/delete_folder
+++ observed/delete_folder
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete a folder"
  }
--- pinned/delete_geographic_access_custom_region
+++ observed/delete_geographic_access_custom_region
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Delete a custom region"
  }
--- pinned/delete_insight_result
+++ observed/delete_insight_result
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete an insight"
  }
--- pinned/delete_insight_results
+++ observed/delete_insight_results
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete insights (batch)"
  }
--- pinned/delete_label
+++ observed/delete_label
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete a label"
  }
--- pinned/delete_report
+++ observed/delete_report
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete a report"
  }

+ tool added: delete_role

+ tool added: delete_service_account

+ tool added: delete_service_account_token

--- pinned/delete_user
+++ observed/delete_user
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Delete user"
  }
--- pinned/delete_user_geographic_access_scope
+++ observed/delete_user_geographic_access_scope
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Clear a user's geographic scope"
  }
--- pinned/dismiss_budget_suggestion
+++ observed/dismiss_budget_suggestion
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Dismiss a budget suggestion"
  }
--- pinned/export_cloud_diagram_json
+++ observed/export_cloud_diagram_json
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Export diagram as JSON"
  }
--- pinned/export_cloudflow_flow
+++ observed/export_cloudflow_flow
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Manage CloudFlow. Serializes the flow — plus every flow it references through subflow nodes — into a\ntenant-neutral, credential-free JSON bundle that can be imported into any tenant with\nthe import operation. Tenant-scoped references (connections, Datastore tables, global\nvariables) are declared as named requirements and rebound at import time; policy and\nSlack-channel references cannot travel and are recorded as unsupported references.\nThe bundle never contains credentials, tenant identifiers, schedules, or execution state.",
+   "description": "Manage CloudFlow. Serializes the flow — plus every flow it references through subflow nodes — into a\ntenant-neutral, credential-free JSON bundle that can be imported into any tenant with\nthe import operation. Tenant-scoped references (connections, Datastore tables, global\nvariables) are declared as named requirements and rebound at import time; policy and\nSlack-channel references cannot travel and are recorded as unsupported references.\nThe bundle never contains credentials, tenant identifiers, schedules, or execution state. codeNode contract: upstream data comes only from `nodes[\"<node name>\"]` (a dict of lists); the code body must end in a top-level `return`; `schema` is required. Code that defines an uncalled function, reads a bare `input`, or assigns `output` completes with `{message: null}` — no error, no result.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Export a flow as a portable bundle"
  }

+ tool added: export_datahub_dataset_records

--- pinned/find_cloud_diagrams
+++ observed/find_cloud_diagrams
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagrams found",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "resources": {
-   ]
+   ],
+   "title": "Find cloud diagrams"
  }
--- pinned/get_active_theme
+++ observed/get_active_theme
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Active theme loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {},
      "type": "object"
-   ]
+   ],
+   "title": "Get active theme"
  }
--- pinned/get_alert
+++ observed/get_alert
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Alert details loaded",
-   ]
+   ],
+   "title": "Get alert"
  }
--- pinned/get_allocation
+++ observed/get_allocation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Allocation loaded",
-   ]
+   ],
+   "title": "Get allocation"
  }
--- pinned/get_annotation
+++ observed/get_annotation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Annotation loaded",
-   ]
+   ],
+   "title": "Get annotation"
  }
--- pinned/get_anomalies
+++ observed/get_anomalies
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Anomaly check complete",
-   ]
+   ],
+   "title": "List cost anomalies"
  }
--- pinned/get_anomaly
+++ observed/get_anomaly
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Anomaly details loaded",
-   ]
+   ],
+   "title": "Get cost anomaly"
  }

+ tool added: get_anomaly_explanation

--- pinned/get_asset
+++ observed/get_asset
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Asset details loaded",
-   ]
+   ],
+   "title": "Get asset"
  }
--- pinned/get_async_operation
+++ observed/get_async_operation
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Poll an async report run operation"
  }
--- pinned/get_async_operation_results
+++ observed/get_async_operation_results
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
+       "fileOutput": {
+         "enum": [
+           "pdf",
+           "png"
+         ],
+         "type": "string"
+       },
        "operationId": {
          "type": "string"
        }
-   ]
+   ],
+   "title": "Get results of an async report run operation"
  }
--- pinned/get_aws_account
+++ observed/get_aws_account
  {
    "_meta": {
      "openai/toolInvocation/invoked": "AWS account loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "accountID": {
-   ]
+   ],
+   "title": "Get AWS account"
  }
--- pinned/get_aws_member_account
+++ observed/get_aws_member_account
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Get a member account"
  }
--- pinned/get_aws_organization
+++ observed/get_aws_organization
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Get an AWS organization"
  }
--- pinned/get_aws_recommendation
+++ observed/get_aws_recommendation
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Get an AWS recommendation"
  }
--- pinned/get_billing_explainer_per_payer
+++ observed/get_billing_explainer_per_payer
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Retrieve a per-payer billing explainer"
  }
--- pinned/get_billing_transfer_program_management_accounts_status
+++ observed/get_billing_transfer_program_management_accounts_status
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Get program management account status"
  }
--- pinned/get_budget
+++ observed/get_budget
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Budget details loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "id": {
-   ]
+   ],
+   "title": "Get budget"
  }
--- pinned/get_cloud_connect_supported_features
+++ observed/get_cloud_connect_supported_features
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Supported features loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "accountID": {
-   ]
+   ],
+   "title": "Get Cloud Connect supported features"
  }
--- pinned/get_cloud_diagram_components
+++ observed/get_cloud_diagram_components
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagram components retrieved",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "include_components": {
-   ]
+   ],
+   "title": "Get cloud diagram components"
  }
--- pinned/get_cloud_diagram_cost_snapshot
+++ observed/get_cloud_diagram_cost_snapshot
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagram cost snapshot retrieved",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "endDate": {
-   ]
+   ],
+   "title": "Get cloud diagram cost snapshot"
  }
--- pinned/get_cloud_diagram_layer_snapshot
+++ observed/get_cloud_diagram_layer_snapshot
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Get a layer snapshot"
  }
--- pinned/get_cloud_diagram_resource_relationships
+++ observed/get_cloud_diagram_resource_relationships
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Resource relationships retrieved",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "depth": {
-   ]
+   ],
+   "title": "Get cloud diagram resource relationships"
  }
--- pinned/get_cloud_diagrams_stats
+++ observed/get_cloud_diagrams_stats
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagram stats retrieved",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "end": {
-   ]
+   ],
+   "title": "Get cloud diagram statistics"
  }
--- pinned/get_cloud_incident
+++ observed/get_cloud_incident
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Incident details loaded",
-   ]
+   ],
+   "title": "Get cloud incident"
  }
--- pinned/get_cloud_incidents
+++ observed/get_cloud_incidents
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Incidents loaded",
-   ]
+   ],
+   "title": "List cloud incidents"
  }
--- pinned/get_cloud_overview
+++ observed/get_cloud_overview
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Cloud overview ready",
-   ]
+   ],
+   "title": "Get cloud overview"
  }
--- pinned/get_cloudflow_connection
+++ observed/get_cloudflow_connection
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow connection loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "connectionId": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the CloudFlow connection to retrieve."
+         "description": "The ID of the CloudFlow connection to retrieve.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Get CloudFlow connection"
  }
--- pinned/get_cloudflow_flow_run
+++ observed/get_cloudflow_flow_run
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Read a flow run, node by node"
  }
--- pinned/get_cloudflow_template
+++ observed/get_cloudflow_template
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow template loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "templateId": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the CloudFlow template to retrieve."
+         "description": "The ID of the CloudFlow template to retrieve.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Get CloudFlow template"
  }
--- pinned/get_commitment
+++ observed/get_commitment
  {
+   "annotations": {
+     "destructiveHint": false,
+     "openWorldHint": true,
+     "readOnlyHint": true
+   },
    "coversEndpoint": "get:/analytics/v1/commitment-manager/{id}",
    "description": "Returns details of a specific Enterprise Discount Program (EDP) commitment contract, identified by its ID. Includes the full breakdown of commitment periods, per-period contracted values, and current spend attainment against the committed amount.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "id": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the commitment to retrieve."
+         "description": "The ID of the commitment to retrieve.",
+         "type": "string"
        }
      },
      "required": [
-   "name": "get_commitment"
+   "name": "get_commitment",
+   "title": "Get commitment"
  }

+ tool added: get_commitment_policy

--- pinned/get_contract
+++ observed/get_contract
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "contractID": {
-   ]
+   ],
+   "title": "Retrieve a contract"
  }
--- pinned/get_contract_template
+++ observed/get_contract_template
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Get contract template"
  }
--- pinned/get_customer
+++ observed/get_customer
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Get customer"
  }
--- pinned/get_customer_geographic_access_scope
+++ observed/get_customer_geographic_access_scope
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Get a customer's geographic scope"
  }

+ tool added: get_customer_group

--- pinned/get_datahub_dataset
+++ observed/get_datahub_dataset
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Dataset loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "name": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The name of the dataset to retrieve."
+         "description": "The name of the dataset to retrieve.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Get DataHub dataset"
  }
--- pinned/get_dimension
+++ observed/get_dimension
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Dimension loaded",
-   ]
+   ],
+   "title": "Get dimension values"
  }
--- pinned/get_entity_invoice_explainer
+++ observed/get_entity_invoice_explainer
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Retrieve an entity invoice explainer"
  }
--- pinned/get_folder
+++ observed/get_folder
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Folder loaded",
-   ]
+   ],
+   "title": "Get folder"
  }

+ tool added: get_gcp_billing_account

+ tool added: get_gcp_recommendation

--- pinned/get_geographic_access_custom_region
+++ observed/get_geographic_access_custom_region
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Get a custom region"
  }
--- pinned/get_insight
+++ observed/get_insight
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insight ready",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "key": {
-   ]
+   ],
+   "title": "Get insight"
  }
--- pinned/get_insight_resources
+++ observed/get_insight_resources
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insight resources ready",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "key": {
-   ]
+   ],
+   "title": "Get insight resources"
  }
--- pinned/get_invoice
+++ observed/get_invoice
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Invoice details loaded",
-   ]
+   ],
+   "title": "Get invoice"
  }
--- pinned/get_label
+++ observed/get_label
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Label loaded",
-   ]
+   ],
+   "title": "Get label"
  }
--- pinned/get_label_assignments
+++ observed/get_label_assignments
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Assignments loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "id": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the label to retrieve assignments for."
+         "description": "The ID of the label to retrieve assignments for.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Get label assignments"
  }
--- pinned/get_report_config
+++ observed/get_report_config
  {
+   "annotations": {
+     "destructiveHint": false,
+     "openWorldHint": true,
+     "readOnlyHint": true
+   },
    "coversEndpoint": "get:/analytics/v1/reports/{id}/config",
    "description": "Get the configuration of a specific Cloud Analytics report by ID. Returns the stored report object including name, type, and a nested 'config' field containing data source, metrics, dimensions, time range, filters, and visualization settings.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "id": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the report to retrieve the configuration for."
+         "description": "The ID of the report to retrieve the configuration for.",
+         "type": "string"
        }
      },
      "required": [
-   "name": "get_report_config"
+   "name": "get_report_config",
+   "title": "Get report configuration"
  }
--- pinned/get_report_results
+++ observed/get_report_results
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Report data ready",
-   ]
+   ],
+   "title": "Get report results"
  }
--- pinned/get_resource_permissions
+++ observed/get_resource_permissions
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Resource permissions loaded",
-   ]
+   ],
+   "title": "Get resource permissions"
  }

+ tool added: get_role

+ tool added: get_service_account

+ tool added: get_service_account_token

+ tool added: get_signup_request

--- pinned/get_statussheet_components
+++ observed/get_statussheet_components
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "attachment": {
-   ]
+   ],
+   "title": "Get layer components"
  }
--- pinned/get_theme
+++ observed/get_theme
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Theme loaded",
-   ]
+   ],
+   "title": "Get theme"
  }
--- pinned/get_ticket
+++ observed/get_ticket
  {
+   "annotations": {
+     "destructiveHint": false,
+     "openWorldHint": true,
+     "readOnlyHint": true
+   },
    "coversEndpoint": "get:/support/v1/tickets/{ticketId}",
    "description": "Returns details of a specific support ticket from the DoiT API by its ID.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "id": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "pattern": "^\\d+$",
-             "type": "string"
-           }
-         ],
-         "description": "The numeric ID of the support ticket to retrieve."
+         "description": "The numeric ID of the support ticket to retrieve.",
+         "type": "string"
        }
      },
      "required": [
-   "name": "get_ticket"
+   "name": "get_ticket",
+   "title": "Get support ticket"
  }
--- pinned/get_user_geographic_access_scope
+++ observed/get_user_geographic_access_scope
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Get a user's geographic scope"
  }

+ tool added: get_widget

--- pinned/id_of_asset
+++ observed/id_of_asset
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Update an asset"
  }
--- pinned/import_cloudflow_flow
+++ observed/import_cloudflow_flow
  {
    "annotations": {
      "destructiveHint": true,
-   "description": "Manage CloudFlow. Creates every flow of a previously exported bundle in the authenticated tenant.\nImports are create-only: each call creates new draft flows with new IDs — nothing is\npublished and no schedule is activated until the target tenant publishes.\n\nRequirements declared by the bundle are resolved through `bindings` (requirement key →\ntarget-tenant resource ID). Unbound connections and Datastore tables leave the\nreferencing nodes flagged incomplete; unbound global variables are auto-created. Pass\n`options.createMissingTables: true` to create missing Datastore tables from the schemas\nembedded in the bundle (structure only, never row data).\n\n**Dry-run**: pass `?dryRun=true` to validate without writing. The response is an import\nplan: per-requirement resolutions with candidate bindings in the target tenant, the\nflows that would be created, and every validation issue at once.",
+   "description": "Manage CloudFlow. Creates every flow of a previously exported bundle in the authenticated tenant.\nImports are create-only: each call creates new draft flows with new IDs — nothing is\npublished and no schedule is activated until the target tenant publishes.\n\nRequirements declared by the bundle are resolved through `bindings` (requirement key →\ntarget-tenant resource ID). Unbound connections and Datastore tables leave the\nreferencing nodes flagged incomplete; unbound global variables are auto-created. Pass\n`options.createMissingTables: true` to create missing Datastore tables from the schemas\nembedded in the bundle (structure only, never row data).\n\n**Dry-run**: pass `?dryRun=true` to validate without writing. The response is an import\nplan: per-requirement resolutions with candidate bindings in the target tenant, the\nflows that would be created, and every validation issue at once. codeNode contract: upstream data comes only from `nodes[\"<node name>\"]` (a dict of lists); the code body must end in a top-level `return`; `schema` is required. Code that defines an uncalled function, reads a bare `input`, or assigns `output` completes with `{message: null}` — no error, no result.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "Idempotency-Key": {
+             "propertyNames": {
+               "type": "string"
+             },
              "type": "object"
            },
            "datastoreTables": {
+             "propertyNames": {
+               "type": "string"
+             },
              "type": "object"
            },
            "globalVariables": {
+             "propertyNames": {
+               "type": "string"
+             },
              "type": "object"
            }
          },
-             "description": "Informational export timestamp; ignored on import.",
-             "type": [
-               "string",
-               "null"
+             "anyOf": [
+               {
+                 "description": "Informational export timestamp; ignored on import.",
+                 "type": "string"
+               },
+               {
+                 "type": "null"
+               }
              ]
            },
            "flows": {
+                         "propertyNames": {
+                           "type": "string"
+                         },
                          "type": "object"
                        },
                        "transitions": {
+                   "propertyNames": {
+                     "type": "string"
+                   },
                    "type": "object"
                  },
                  "triggerType": {
-   ]
+   ],
+   "title": "Import a flow bundle"
  }
--- pinned/invite_user
+++ observed/invite_user
  {
    "_meta": {
      "openai/toolInvocation/invoked": "User invited",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "email": {
+         "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
          "type": "string"
        },
        "organizationId": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the organization to assign the invited user to."
+         "description": "The ID of the organization to assign the invited user to.",
+         "type": "string"
        },
        "roleId": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the role to assign to the invited user."
+         "description": "The ID of the role to assign to the invited user.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Invite user"
  }
--- pinned/list_account_team
+++ observed/list_account_team
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Account team loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {},
      "type": "object"
-   ]
+   ],
+   "title": "List account team"
  }

+ tool added: list_alert_slack_channels

--- pinned/list_alerts
+++ observed/list_alerts
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Alerts loaded",
-   ]
+   ],
+   "title": "List alerts"
  }
--- pinned/list_allocations
+++ observed/list_allocations
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Allocations loaded",
-   ]
+   ],
+   "title": "List allocations"
  }
--- pinned/list_annotations
+++ observed/list_annotations
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Annotations loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "filter": {
-   ]
+   ],
+   "title": "List annotations"
  }
--- pinned/list_assets
+++ observed/list_assets
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Assets loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "filter": {
-   ]
+   ],
+   "title": "List assets"
  }
--- pinned/list_aws_member_accounts
+++ observed/list_aws_member_accounts
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List member accounts under an AWS organization"
  }
--- pinned/list_aws_organizations
+++ observed/list_aws_organizations
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List AWS organizations"
  }
--- pinned/list_aws_organizations_settings
+++ observed/list_aws_organizations_settings
  {
    "annotations": {
      "destructiveHint": false,
-   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns one item per onboarded AWS organization. Each item includes that AWS organization's commitments purchasing account (`purchaseAccountId`) and commitment settings for each commitment type activated on that AWS organization (`compute`, `database`).\n\nCommitment settings cover recommendation and automation preferences (policy, term, payment option, automation mode, commitment limits, and related fields). They are stored at the customer level per commitment type and therefore have the same values on every AWS organization item. Only `purchaseAccountId` and which commitment types appear differ per AWS organization.\n\nIn the DoiT Console, commitment settings are edited on an account's Settings tab but apply across all AWS organizations for that commitment type; the purchasing account is set per AWS organization on Accounts Settings. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
+   "description": "Evaluate current AWS commitments, plan and automate purchases, and optimize cloud costs with PerfectScale for Commitments. Returns one item per onboarded AWS organization. Each item includes that AWS organization's commitments purchasing account (`purchaseAccountId`) and commitment settings for each commitment type activated on that AWS organization (`compute`, `database`).\n\nCommitment settings cover recommendation and automation preferences (policy, term, payment option, automation mode, commitment limits, and related fields). They are stored independently for each AWS organization and commitment type. Each item includes that organization's `purchaseAccountId` and activated commitment types.\n\nIn the DoiT Console, commitment settings are edited on an account's Settings tab and apply only to that AWS organization and commitment type; the purchasing account is set per AWS organization on Accounts Settings. This endpoint is paginated: to fetch the next page, call again passing the response's `pageToken` value as the `pageToken` parameter. Stop once the response has no `pageToken` — that means there are no more pages.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List account and commitment settings per AWS organization"
  }
--- pinned/list_aws_planned_purchases
+++ observed/list_aws_planned_purchases
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List AWS planned purchases"
  }
--- pinned/list_aws_recommendations
+++ observed/list_aws_recommendations
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List AWS recommendations"
  }
--- pinned/list_aws_reserved_instances
+++ observed/list_aws_reserved_instances
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List AWS Reserved Instances"
  }
--- pinned/list_aws_savings_plans
+++ observed/list_aws_savings_plans
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List AWS Savings Plans"
  }
--- pinned/list_billing_transfer_end_customers
+++ observed/list_billing_transfer_end_customers
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List end-customers under a reseller PMA"
  }
--- pinned/list_billing_transfer_end_customers_by_reseller
+++ observed/list_billing_transfer_end_customers_by_reseller
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List end-customers under a reseller PMA, by reseller PMA alone"
  }
--- pinned/list_billing_transfer_program_management_accounts
+++ observed/list_billing_transfer_program_management_accounts
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List program management accounts"
  }
--- pinned/list_billing_transfer_reseller_accounts
+++ observed/list_billing_transfer_reseller_accounts
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List the caller's reseller PMA nodes"
  }
--- pinned/list_billing_transfer_reseller_accounts_with_tenants
+++ observed/list_billing_transfer_reseller_accounts_with_tenants
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List the caller's reseller PMA nodes with their end-customer tenants"
  }
--- pinned/list_budget_suggestions
+++ observed/list_budget_suggestions
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "List budget suggestions"
  }
--- pinned/list_budgets
+++ observed/list_budgets
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Budgets loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "filter": {
-   ]
+   ],
+   "title": "List budgets"
  }
--- pinned/list_cloud_diagram_activity_groups
+++ observed/list_cloud_diagram_activity_groups
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Activity groups retrieved",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "limit": {
+         "maximum": 9007199254740991,
          "minimum": 1,
          "type": "integer"
        },
+         "maximum": 9007199254740991,
          "minimum": 0,
          "type": "integer"
        },
-   ]
+   ],
+   "title": "List cloud diagram activity groups"
  }
--- pinned/list_cloud_diagram_layer_snapshots
+++ observed/list_cloud_diagram_layer_snapshots
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "List layer snapshots"
  }
--- pinned/list_cloud_diagram_node_activities
+++ observed/list_cloud_diagram_node_activities
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Node activities retrieved",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "limit": {
+         "maximum": 9007199254740991,
          "minimum": 1,
          "type": "integer"
        },
+         "maximum": 9007199254740991,
          "minimum": 0,
          "type": "integer"
        },
-   ]
+   ],
+   "title": "List cloud diagram node activities"
  }
--- pinned/list_cloudflow_connections
+++ observed/list_cloudflow_connections
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow connections loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "maxResults": {
-   ]
+   ],
+   "title": "List CloudFlow connections"
  }
--- pinned/list_cloudflow_flow_runs
+++ observed/list_cloudflow_flow_runs
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "List a flow's runs"
  }
--- pinned/list_cloudflow_templates
+++ observed/list_cloudflow_templates
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow templates loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "maxResults": {
-   ]
+   ],
+   "title": "List CloudFlow templates"
  }
--- pinned/list_cloudflows
+++ observed/list_cloudflows
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlows loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "maxResults": {
-   ]
+   ],
+   "title": "List CloudFlow flows"
  }

+ tool added: list_commitment_policies

--- pinned/list_commitments
+++ observed/list_commitments
  {
+   "annotations": {
+     "destructiveHint": false,
+     "openWorldHint": true,
+     "readOnlyHint": true
+   },
    "coversEndpoint": "get:/analytics/v1/commitment-manager",
    "description": "Returns a list of commitment contracts from the DoiT Commitment Manager. These are Enterprise Discount Program (EDP) agreements — negotiated minimum spend or usage commitments between the customer and a cloud provider (Google Cloud, AWS, or Azure) .",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "filter": {
-   "name": "list_commitments"
+   "name": "list_commitments",
+   "title": "List commitments"
  }
--- pinned/list_contract_templates
+++ observed/list_contract_templates
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "List contract templates"
  }
--- pinned/list_contracts
+++ observed/list_contracts
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "List contracts"
  }

+ tool added: list_customer_group_users

+ tool added: list_customer_groups

--- pinned/list_datahub_datasets
+++ observed/list_datahub_datasets
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Datasets loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {},
      "type": "object"
-   ]
+   ],
+   "title": "List DataHub datasets"
  }
--- pinned/list_dimensions
+++ observed/list_dimensions
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Dimensions loaded",
-   ]
+   ],
+   "title": "List dimensions"
  }
--- pinned/list_folders
+++ observed/list_folders
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Folders loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "maxResults": {
-   ]
+   ],
+   "title": "List folders"
  }

+ tool added: list_gcp_billing_accounts

+ tool added: list_gcp_billing_accounts_settings

+ tool added: list_gcp_planned_purchases

+ tool added: list_gcp_recommendations

+ tool added: list_gcp_resource_cuds

+ tool added: list_gcp_spend_cuds

--- pinned/list_geographic_access_countries
+++ observed/list_geographic_access_countries
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List countries available for geographic access"
  }
--- pinned/list_geographic_access_custom_regions
+++ observed/list_geographic_access_custom_regions
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "List custom regions"
  }
--- pinned/list_invoices
+++ observed/list_invoices
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Invoices loaded",
-   ]
+   ],
+   "title": "List invoices"
  }
--- pinned/list_labels
+++ observed/list_labels
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Labels loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "filter": {
-   ]
+   ],
+   "title": "List labels"
  }
--- pinned/list_optimization_recommendations
+++ observed/list_optimization_recommendations
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insights ready",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "category": {
-   ]
+   ],
+   "title": "List optimization recommendations"
  }
--- pinned/list_organizations
+++ observed/list_organizations
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Organizations loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {},
      "type": "object"
-   ]
+   ],
+   "title": "List organizations"
  }
--- pinned/list_platforms
+++ observed/list_platforms
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Platforms loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {},
      "type": "object"
-   ]
+   ],
+   "title": "List platforms"
  }
--- pinned/list_products
+++ observed/list_products
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Products loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "platform": {
-   ]
+   ],
+   "title": "List products"
  }
--- pinned/list_reports
+++ observed/list_reports
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Reports loaded",
-   ]
+   ],
+   "title": "List reports"
  }
--- pinned/list_roles
+++ observed/list_roles
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Roles loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {},
      "type": "object"
-   ]
+   ],
+   "title": "List roles"
  }

+ tool added: list_service_account_tokens

+ tool added: list_service_accounts

--- pinned/list_service_quotas
+++ observed/list_service_quotas
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "cloudProvider": {
-   ]
+   ],
+   "title": "List service quotas"
  }

+ tool added: list_shared_payer_account_mappings

+ tool added: list_shared_payer_management_accounts

+ tool added: list_shared_payers

--- pinned/list_themes
+++ observed/list_themes
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Themes loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {},
      "type": "object"
-   ]
+   ],
+   "title": "List themes"
  }
--- pinned/list_ticket_comments
+++ observed/list_ticket_comments
  {
+   "annotations": {
+     "destructiveHint": false,
+     "openWorldHint": true,
+     "readOnlyHint": true
+   },
    "coversEndpoint": "get:/support/v1/tickets/{ticketId}/comments",
    "description": "Returns all comments on a support ticket. For customers, only public comments are returned. For DoiT employees, both public and private comments are returned.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "ticketId": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "pattern": "^\\d+$",
-             "type": "string"
-           }
-         ],
-         "description": "The numeric ID of the support ticket whose comments to retrieve."
+         "description": "The numeric ID of the support ticket whose comments to retrieve.",
+         "type": "string"
        }
      },
      "required": [
-   "name": "list_ticket_comments"
+   "name": "list_ticket_comments",
+   "title": "List ticket comments"
  }
--- pinned/list_ticket_tags
+++ observed/list_ticket_tags
  {
    "annotations": {
      "destructiveHint": false,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "List tags on a support request"
  }
--- pinned/list_tickets
+++ observed/list_tickets
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Tickets loaded",
-   ]
+   ],
+   "title": "List support tickets"
  }
--- pinned/list_users
+++ observed/list_users
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Users loaded",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {},
      "type": "object"
-   ]
+   ],
+   "title": "List users"
  }

+ tool added: list_widgets

+ tool added: patch_anomaly

--- pinned/post_insight_resource_results
+++ observed/post_insight_resource_results
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
+               "propertyNames": {
+                 "type": "string"
+               },
                "type": "object"
              },
              "resourceId": {
-   ]
+   ],
+   "title": "Replace resource results for an insight"
  }
--- pinned/post_insight_result
+++ observed/post_insight_result
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insight saved",
-     "destructiveHint": false,
+     "destructiveHint": true,
      "openWorldHint": true,
      "readOnlyHint": false
    },
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "categories": {
-   ]
+   ],
+   "title": "Post insight result"
  }
--- pinned/post_insight_results
+++ observed/post_insight_results
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
+                     "propertyNames": {
+                       "type": "string"
+                     },
                      "type": "object"
                    },
                    "resourceId": {
-   ]
+   ],
+   "title": "Create insights (batch)"
  }

+ tool added: reassign_shared_payer_account

--- pinned/refine_cloudflow
+++ observed/refine_cloudflow
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow refined",
-     "destructiveHint": false,
+     "destructiveHint": true,
      "openWorldHint": true,
      "readOnlyHint": false
    },
-   "description": "Use this when the user wants to refine or rebuild an existing CloudFlow automation using natural language. Streams real-time progress updates while the AI builds the flow, then returns the final result.",
+   "description": "Use this when the user wants to refine or rebuild an existing CloudFlow automation using natural language. Streams real-time progress updates while the AI builds the flow, then returns the final result. Generated codeNode code is frequently broken in ways that pass validation and fail silently at run time. Always export_cloudflow_flow and test-run the result, and check the per-node output, before reporting success.",
    "inputSchema": {
      "properties": {
        "conversationId": {
-   ]
+   ],
+   "title": "Refine CloudFlow flow"
  }
--- pinned/remove_ticket_tags
+++ observed/remove_ticket_tags
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "customerContext": {
-   ]
+   ],
+   "title": "Remove tags from a support request"
  }
--- pinned/resend_invite
+++ observed/resend_invite
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "Idempotency-Key": {
-   ]
+   ],
+   "title": "Resend invite"
  }

+ tool added: resend_signup_verification

--- pinned/run_query
+++ observed/run_query
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Analytics results ready",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "config": {
-                           "$ref": "#/properties/config/properties/metrics/items/properties/type"
+                           "description": "Metric type. Accepted values: basic, custom, extended.",
+                           "enum": [
+                             "basic",
+                             "custom",
+                             "extended"
+                           ],
+                           "type": "string"
                          },
                          "value": {
-                           "$ref": "#/properties/config/properties/metrics/items/properties/value"
+                           "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                           "type": "string"
                          }
                        },
                        "required": [
+                       "maximum": 9007199254740991,
+                       "minimum": -9007199254740991,
                        "type": "integer"
                      }
                    },
-             "$ref": "#/properties/config/properties/metrics/items",
-             "description": "Deprecated: use 'metrics' instead."
+             "additionalProperties": false,
+             "description": "Deprecated: use 'metrics' instead.",
+             "properties": {
+               "type": {
+                 "description": "Metric type. Accepted values: basic, custom, extended.",
+                 "enum": [
+                   "basic",
+                   "custom",
+                   "extended"
+                 ],
+                 "type": "string"
+               },
+               "value": {
+                 "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                 "type": "string"
+               }
+             },
+             "required": [
+               "type",
+               "value"
+             ],
+             "type": "object"
            },
            "metricFilter": {
              "additionalProperties": false,
-                     "$ref": "#/properties/config/properties/metrics/items/properties/type"
+                     "description": "Metric type. Accepted values: basic, custom, extended.",
+                     "enum": [
+                       "basic",
+                       "custom",
+                       "extended"
+                     ],
+                     "type": "string"
                    },
                    "value": {
-                     "$ref": "#/properties/config/properties/metrics/items/properties/value"
+                     "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                     "type": "string"
                    }
                  },
                  "required": [
+                 "maximum": 9007199254740991,
                  "minimum": 0,
                  "type": "integer"
                },
-   ]
+   ],
+   "title": "Run Cloud Analytics query"
  }
--- pinned/search_cloud_diagrams
+++ observed/search_cloud_diagrams
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Diagram search complete",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "from": {
+         "maximum": 9007199254740991,
          "minimum": 0,
          "type": "integer"
        },
+         "maximum": 9007199254740991,
          "minimum": 1,
          "type": "integer"
        },
-   ]
+   ],
+   "title": "Search cloud diagrams"
  }
--- pinned/search_customers
+++ observed/search_customers
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Customer search complete",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "assetPlatforms": {
-   ]
+   ],
+   "title": "Search customers"
  }
--- pinned/send_datahub_events
+++ observed/send_datahub_events
  {
    "_meta": {
      "openai/toolInvocation/invoked": "DataHub events sent",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "events": {
+               "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"
              }
            },
-   ]
+   ],
+   "title": "Send DataHub events"
  }
--- pinned/set_active_theme
+++ observed/set_active_theme
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Active theme set",
-     "destructiveHint": false,
+     "destructiveHint": true,
      "openWorldHint": true,
      "readOnlyHint": false
    },
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "themeId": {
-   ]
+   ],
+   "title": "Set active theme"
  }

+ tool added: stop_cloudflow_flow

--- pinned/test_run_cloudflow_flow
+++ observed/test_run_cloudflow_flow
  {
    "annotations": {
      "destructiveHint": true,
-   "description": "Manage CloudFlow. Runs a flow once as a test, and **accepts an unpublished (draft) flow** — unlike\n`actions/trigger`, which requires the flow to be published. Use this to verify a newly\nauthored or edited flow before publishing it.\n\nExecution is identical to a production run: the same graph, the same bound connections,\nthe same credentials, and the same approval behaviour. An approval-gated node still parks\nthe run and its side effect still waits for a real approval — there is no request that\nskips one.\n\nThe run is recorded as a test, so it does not appear in run history, does not count\ntowards dashboard statistics, does not become a dashboard widget's data source, and does\nnot consume a scheduled-run budget. It does hold the flow's concurrency lock, so a `409`\nis returned while the flow is already running.\n\nThe flow's first node must be a webhook, scheduled, or manual trigger.\n\nBefore dispatching, the flow is validated with the same checks publish applies — a draft\nhas never been through them. A flow that fails returns `422` listing every offending node\nat once, so all of them can be fixed in one pass.\n\nPoll the `Location` URL to follow the run and read what each node produced.\n\nPass `?dryRun=true` to validate the flow without starting a run.",
+   "description": "Manage CloudFlow. Runs a flow once as a test, and **accepts an unpublished (draft) flow** — unlike\n`actions/trigger`, which requires the flow to be published. Use this to verify a newly\nauthored or edited flow before publishing it.\n\nExecution is identical to a production run: the same graph, the same bound connections,\nthe same credentials, and the same approval behaviour. An approval-gated node still parks\nthe run and its side effect still waits for a real approval — there is no request that\nskips one.\n\nThe run is recorded as a test, so it does not appear in run history, does not count\ntowards dashboard statistics, does not become a dashboard widget's data source, and does\nnot consume a scheduled-run budget. It does hold the flow's concurrency lock, so a `409`\nis returned while the flow is already running.\n\nThe flow's first node must be a webhook, scheduled, or manual trigger.\n\nBefore dispatching, the flow is validated with the same checks publish applies — a draft\nhas never been through them. A flow that fails returns `422` listing every offending node\nat once, so all of them can be fixed in one pass.\n\nPoll the `Location` URL to follow the run and read what each node produced.\n\nPass `?dryRun=true` to validate the flow without starting a run. Generated codeNode code is frequently broken in ways that pass validation and fail silently at run time. Always export_cloudflow_flow and test-run the result, and check the per-node output, before reporting success.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "Idempotency-Key": {
-   ]
+   ],
+   "title": "Test-run a flow"
  }
--- pinned/trigger_cloud_flow
+++ observed/trigger_cloud_flow
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow triggered",
-   ]
+   ],
+   "title": "Trigger CloudFlow flow"
  }

+ tool added: trigger_cloudflow_flow

+ tool added: unassign_customer_group_user

--- pinned/update_alert
+++ observed/update_alert
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Alert updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "config": {
+           "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "type": "string"
          },
          "type": "array"
-   ]
+   ],
+   "title": "Update alert"
  }
--- pinned/update_allocation
+++ observed/update_allocation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Allocation updated",
-   ]
+   ],
+   "title": "Update allocation"
  }
--- pinned/update_annotation
+++ observed/update_annotation
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Annotation updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "content": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the annotation to update (required)."
+         "description": "The ID of the annotation to update (required).",
+         "type": "string"
        },
        "labels": {
          "anyOf": [
+             "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"
            },
            {
-   ]
+   ],
+   "title": "Update annotation"
  }
--- pinned/update_aws_feature
+++ observed/update_aws_feature
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "accountID": {
-   ]
+   ],
+   "title": "Update an AWS feature"
  }
--- pinned/update_budget
+++ observed/update_budget
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Budget updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "alerts": {
+               "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
                "type": "string"
              },
              "role": {
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "growthPerPeriod": {
+           "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
            "type": "string"
          },
          "type": "array"
+         "maximum": 9007199254740991,
+         "minimum": -9007199254740991,
          "type": "integer"
        },
        "timeInterval": {
-   ]
+   ],
+   "title": "Update budget"
  }
--- pinned/update_cloudflow_connection
+++ observed/update_cloudflow_connection
  {
    "_meta": {
      "openai/toolInvocation/invoked": "CloudFlow connection updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "awsConfig": {
+             "propertyNames": {
+               "type": "string"
+             },
              "type": "object"
            },
            "roleName": {
+               "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$",
                "type": "string"
              },
              "role": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the CloudFlow connection to update (required)."
+         "description": "The ID of the CloudFlow connection to update (required).",
+         "type": "string"
        },
        "description": {
          "description": "New description for the connection.",
-   ]
+   ],
+   "title": "Update CloudFlow connection"
  }
--- pinned/update_customer
+++ observed/update_customer
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "contact": {
-   ]
+   ],
+   "title": "Update customer"
  }
--- pinned/update_customer_geographic_access_scope
+++ observed/update_customer_geographic_access_scope
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Replace a customer's geographic scope"
  }

+ tool added: update_customer_group

--- pinned/update_datahub_dataset
+++ observed/update_datahub_dataset
  {
    "_meta": {
      "openai/toolInvocation/invoked": "DataHub dataset updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "description": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The name of the dataset to update (required). Used for identification; the name cannot be changed."
+         "description": "The name of the dataset to update (required). Used for identification; the name cannot be changed.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Update DataHub dataset"
  }
--- pinned/update_folder
+++ observed/update_folder
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Folder updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "description": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the folder to update (required)."
+         "description": "The ID of the folder to update (required).",
+         "type": "string"
        },
        "name": {
          "description": "New name for the folder.",
-   ]
+   ],
+   "title": "Update folder"
  }
--- pinned/update_geographic_access_custom_region
+++ observed/update_geographic_access_custom_region
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Update a custom region"
  }
--- pinned/update_insight_status
+++ observed/update_insight_status
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Insight status updated",
-     "destructiveHint": false,
+     "destructiveHint": true,
      "openWorldHint": true,
      "readOnlyHint": false
    },
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "dismissalDetails": {
-   ]
+   ],
+   "title": "Update insight status"
  }
--- pinned/update_label
+++ observed/update_label
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Label updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "color": {
-             "anyOf": [
-               {
-                 "not": {}
-               },
-               {
-                 "description": "The color of the label (required). Accepted values: blue, skyBlue, teal, mint, lime, softYellow, apricot, lavender, purple, rosePink, slateGrey.",
-                 "enum": [
-                   "blue",
-                   "skyBlue",
-                   "teal",
-                   "mint",
-                   "lime",
-                   "softYellow",
-                   "apricot",
-                   "lavender",
-                   "purple",
-                   "rosePink",
-                   "slateGrey"
-                 ],
-                 "type": "string"
-               }
+             "description": "The color of the label (required). Accepted values: blue, skyBlue, teal, mint, lime, softYellow, apricot, lavender, purple, rosePink, slateGrey.",
+             "enum": [
+               "blue",
+               "skyBlue",
+               "teal",
+               "mint",
+               "lime",
+               "softYellow",
+               "apricot",
+               "lavender",
+               "purple",
+               "rosePink",
+               "slateGrey"
              ],
-             "description": "The color of the label (required). Accepted values: blue, skyBlue, teal, mint, lime, softYellow, apricot, lavender, purple, rosePink, slateGrey."
+             "type": "string"
            },
            {
              "type": "null"
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the label to update (required)."
+         "description": "The ID of the label to update (required).",
+         "type": "string"
        },
        "name": {
          "anyOf": [
-             "anyOf": [
-               {
-                 "not": {}
-               },
-               {
-                 "description": "The name of the label (required, non-empty).",
-                 "minLength": 1,
-                 "type": "string"
-               }
-             ],
-             "description": "The name of the label (required, non-empty)."
+             "description": "The name of the label (required, non-empty).",
+             "minLength": 1,
+             "type": "string"
            },
            {
              "type": "null"
-   ]
+   ],
+   "title": "Update label"
  }
--- pinned/update_report
+++ observed/update_report
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Report updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "config": {
-                           "$ref": "#/properties/config/properties/metrics/items/properties/type"
+                           "description": "Metric type. Accepted values: basic, custom, extended.",
+                           "enum": [
+                             "basic",
+                             "custom",
+                             "extended"
+                           ],
+                           "type": "string"
                          },
                          "value": {
-                           "$ref": "#/properties/config/properties/metrics/items/properties/value"
+                           "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                           "type": "string"
                          }
                        },
                        "required": [
+                       "maximum": 9007199254740991,
+                       "minimum": -9007199254740991,
                        "type": "integer"
                      }
                    },
-             "$ref": "#/properties/config/properties/metrics/items",
-             "description": "Deprecated: use 'metrics' instead."
+             "additionalProperties": false,
+             "description": "Deprecated: use 'metrics' instead.",
+             "properties": {
+               "type": {
+                 "description": "Metric type. Accepted values: basic, custom, extended.",
+                 "enum": [
+                   "basic",
+                   "custom",
+                   "extended"
+                 ],
+                 "type": "string"
+               },
+               "value": {
+                 "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                 "type": "string"
+               }
+             },
+             "required": [
+               "type",
+               "value"
+             ],
+             "type": "object"
            },
            "metricFilter": {
              "additionalProperties": false,
-                     "$ref": "#/properties/config/properties/metrics/items/properties/type"
+                     "description": "Metric type. Accepted values: basic, custom, extended.",
+                     "enum": [
+                       "basic",
+                       "custom",
+                       "extended"
+                     ],
+                     "type": "string"
                    },
                    "value": {
-                     "$ref": "#/properties/config/properties/metrics/items/properties/value"
+                     "description": "For basic metrics: 'cost', 'usage', or 'savings'. For extended metrics: e.g. 'amortized_cost'. For custom metrics: the custom metric ID.",
+                     "type": "string"
                    }
                  },
                  "required": [
+                 "maximum": 9007199254740991,
                  "minimum": 0,
                  "type": "integer"
                },
-   ]
+   ],
+   "title": "Update report"
  }
--- pinned/update_resource_permissions
+++ observed/update_resource_permissions
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Resource permissions updated",
-   ]
+   ],
+   "title": "Update resource permissions"
  }

+ tool added: update_role

+ tool added: update_service_account

+ tool added: update_service_account_token

--- pinned/update_theme
+++ observed/update_theme
  {
    "_meta": {
      "openai/toolInvocation/invoked": "Theme updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "colors": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the theme to update."
+         "description": "The ID of the theme to update.",
+         "type": "string"
        },
        "name": {
          "description": "Partial name match (case-insensitive) used to find the theme when ID is unknown.",
-   ]
+   ],
+   "title": "Update theme"
  }
--- pinned/update_ticket
+++ observed/update_ticket
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "assignee": {
-   ]
+   ],
+   "title": "Update a request"
  }
--- pinned/update_user
+++ observed/update_user
  {
    "_meta": {
      "openai/toolInvocation/invoked": "User updated",
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "firstName": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The user's first name."
+         "description": "The user's first name.",
+         "type": "string"
        },
        "id": {
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The unique ID of the user to update."
+         "description": "The unique ID of the user to update.",
+         "type": "string"
        },
        "jobFunction": {
          "description": "The user's job function. Accepted values: Data Engineer / Data Analysts, Executive Team, Finance / Accounting, Founder, Legal / Purchasing, Management, Sales / Marketing, Software / Ops Engineer.",
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The user's last name."
+         "description": "The user's last name.",
+         "type": "string"
        },
        "phone": {
          "description": "The user's phone number including country calling code (e.g. +14155551234, +447911123456). Must start with a valid country calling code such as +1, +44, or +91.",
-         "allOf": [
-           {
-             "type": "string"
-           },
-           {
-             "minLength": 1,
-             "type": "string"
-           }
-         ],
-         "description": "The ID of the role to assign to the user."
+         "description": "The ID of the role to assign to the user.",
+         "type": "string"
        }
      },
      "required": [
-   ]
+   ],
+   "title": "Update user"
  }
--- pinned/update_user_geographic_access_scope
+++ observed/update_user_geographic_access_scope
  {
    "annotations": {
      "destructiveHint": true,
-     "$schema": "http://json-schema.org/draft-07/schema#",
+     "$schema": "https://json-schema.org/draft/2020-12/schema",
      "additionalProperties": false,
      "properties": {
        "X-Tenant-Id": {
-   ]
+   ],
+   "title": "Replace a user's geographic scope"
  }
--- pinned/validate_user
+++ observed/validate_user
  {
    "_meta": {
      "openai/toolInvocation/invoked": "User validated",
-   ]
+   ],
+   "title": "Validate user"
  }

+ tool added: verify_signup_request

Changed 2026-09-04 10:22 UTC

1 description rewritten, 1 schema or annotation change with the description left byte-identical, 20 tools added, 1 tool removed.

+ tool added: async_run_inline

+ tool added: async_run_report_by_id

--- pinned/build_cloud_flow
+++ observed/build_cloud_flow
  {
+   "_meta": {
+     "openai/toolInvocation/invoked": "CloudFlow built",
+     "openai/toolInvocation/invoking": "Building CloudFlow..."
+   },
    "annotations": {
-     "destructiveHint": true,
+     "destructiveHint": false,
      "openWorldHint": true,
      "readOnlyHint": false
    },
-   "description": "Manage CloudFlow. Creates a new CloudFlow and generates its nodes and connections based on the provided natural language intent. The operation streams incremental build events, including the ID of the newly created flow, as they are produced.",
+   "coversEndpoint": "post:/cloudflow/v1/flows/actions/build",
+   "description": "Use this when the user wants to build a brand-new CloudFlow automation from scratch using natural language. Streams real-time progress while the AI builds the flow, then returns the newly created flow's ID, the builder's answer, and the build steps that ran. Use refine_cloudflow to change an existing flow; use this only to create a new one.",
    "inputSchema": {
-     "$schema": "http://json-schema.org/draft-07/schema#",
-     "additionalProperties": false,
      "properties": {
        "conversationId": {
-         "description": "ID of an existing conversation to continue. When omitted, a new conversation is started.",
-         "type": "string"
-       },
-       "customerContext": {
-         "description": "Scope the request to a specific customer by ID. Required for DoiT employees (whose token isn't tied to a single customer); omit for direct customer users.",
+         "description": "Optional conversation ID to continue an existing build session.",
          "type": "string"
        },
        "question": {

+ tool added: cancel_async_operation

+ tool added: create_geographic_access_custom_region

+ tool added: delete_customer_geographic_access_scope

+ tool added: delete_geographic_access_custom_region

+ tool added: delete_user_geographic_access_scope

+ tool added: get_async_operation

+ tool added: get_async_operation_results

+ tool added: get_cloudflow_flow_run

+ tool added: get_customer_geographic_access_scope

+ tool added: get_geographic_access_custom_region

+ tool added: get_user_geographic_access_scope

--- pinned/import_cloudflow_flow
+++ observed/import_cloudflow_flow
  {
    "annotations": {
      "destructiveHint": true,
-                         "description": "Present unless the export stripped variable values. Connection-typed values are `$req:connections/<key>` tokens."
+                         "description": "Present unless the export stripped variable values. Connection-typed values are `$req:connections/<key>` tokens.",
+                         "type": "string"
                        }
                      },
                      "required": [
-                           "message": {},
+                           "message": {
+                             "type": "string"
+                           },
                            "rejectApprovalAfterTime": {
                              "type": "boolean"
                            },
-                       "description": "Present unless the export stripped variable values."
+                       "description": "Present unless the export stripped variable values.",
+                       "type": "string"
                      }
                    },
                    "required": [

+ tool added: list_cloudflow_flow_runs

+ tool added: list_geographic_access_countries

+ tool added: list_geographic_access_custom_regions

+ tool added: test_run_cloudflow_flow

+ tool added: update_customer_geographic_access_scope

+ tool added: update_geographic_access_custom_region

+ tool added: update_user_geographic_access_scope

tool removed: ask_ava_streaming

Changed 2026-09-03 10:35 UTC

1 tool added.

+ tool added: confirm_action

Current tools

Show all 241 tool fingerprints
accept_budget_suggestion
a3b598c321f2677d
add_ticket_tags
40c27f9482c070c4
ask_ava_sync
b465058a0e14b77d
assign_contract_template
143c591bb2372bd7
assign_customer_group_user
f335342ed89e2631
assign_customer_group_user_group
7079ba0613d2f678
assign_objects_to_label
193d186bb6ec027c
async_run_inline
b15d372cd4f4c481
async_run_report_by_id
c2f208d43ef25e96
ava_feedback
f653d6bbc81c9aed
build_cloud_flow
65606beb06df7984
cancel_async_operation
a779a845e860a733
cancel_invite
2e06386ee3657c92
compare_spend
0b4ccfa0cfc1246e
confirm_action
085abef481b67239
cost_breakdown
cac28c7ca9daa898
cost_trend
7714492b7b03d3b9
create_account_role
14dea84eff936615
create_alert
51b74302ee359f64
create_allocation
4d33d6c87976ec68
create_annotation
1f2c5598915e56c8
create_asset
d884a3c12c8a3575
create_budget
24b8c5ebbda00697
create_cloudflow_connection
c50467b5fdd8bb2c
create_custom_theme
0a3134b55bdc9c31
create_customer_group
68b4af5e1ad1e5aa
create_datahub_dataset
96a6e1a4071846f1
create_folder
8b772354c6ef379c
create_geographic_access_custom_region
2bd139bd090f5a4a
create_label
4da420e8d3961a44
create_report
9a63b3d65dfd7de1
create_role
45688d1203d1231d
create_service_account
8d4941ef4346afd0
create_service_account_token
e217be185df9a29b
create_signup_request
baaa83afd3bdf28a
create_signup_session
8889b417e8c85002
create_ticket
dd0cf5357f5bc08c
create_ticket_comment
734850f96428673f
datahub_events_csv_file
c62da642d168c311
datahub_import_provider_records
4d9ba17dd00cb074
delete_account_role
01fea984c14e5211
delete_alert
a741145b3f61869e
delete_allocation
7334d269fc0061c1
delete_annotation
0d10bbd56620195f
delete_ava_conversation
f7b0835c95b90659
delete_budget
2c1fd40ca91c5c4d
delete_cloudflow_connection
06ab0b6a764eae6a
delete_custom_theme
4a0a22d9246b88c7
delete_customer_geographic_access_scope
83c8906f070f29d7
delete_customer_group
4f3824655e63d551
delete_datahub_dataset
0f05305a8cb4515a
delete_datahub_datasets
74efe71561052625
delete_datahub_events_by_filter
c2aa03ab2816d1a5
delete_folder
cab56c836f5be2fe
delete_geographic_access_custom_region
c7777cf420e89414
delete_insight_result
1f0b52775a5c84cb
delete_insight_results
8ce886589806235a
delete_label
d824bfd17e21dd92
delete_report
9f6c73e43a037c52
delete_role
f214dd05b0c362ca
delete_service_account
1001ebcb5b8bf916
delete_service_account_token
87acbc8c5fb95f88
delete_user
c2111afdc73d366a
delete_user_geographic_access_scope
e0fadc7b42c1f0a4
dismiss_budget_suggestion
6eba53eea8c855d7
export_cloud_diagram_json
d6c53e956b83180b
export_cloudflow_flow
d97a929b6118f995
export_datahub_dataset_records
2753fd85b0e156f6
find_cloud_diagrams
73e776cb77fc266d
get_active_theme
149b7954b49e31f3
get_alert
f1aa09897fe2496c
get_allocation
16424449179e818a
get_annotation
f10c43b1046426c1
get_anomalies
c5181c667ef87dc3
get_anomaly
677d496dafa9aeef
get_anomaly_explanation
d3f0f6a55ac830f6
get_asset
d4972c98cc7d9937
get_async_operation
853c7d55ae5a3e20
get_async_operation_results
8c0b02bfd045f453
get_aws_account
f9520b9cd82a2c31
get_aws_member_account
d24306706dd6e68f
get_aws_organization
559a4e070861709f
get_aws_recommendation
6b5c9d21f0339493
get_billing_explainer_per_payer
9decce9cad9ef830
get_billing_transfer_program_management_accounts_status
6a06149d374ab69f
get_budget
3e6562ed6304b501
get_cloud_connect_supported_features
e2c186ff96e2cda8
get_cloud_diagram_components
eb9eb5dfe96f7b04
get_cloud_diagram_cost_snapshot
d35bf6b62592e283
get_cloud_diagram_layer_snapshot
14488638cf971ba9
get_cloud_diagram_resource_relationships
3e85a969c6d5ae5a
get_cloud_diagrams_stats
24da2769c6c16319
get_cloud_incident
c0ba517066bac429
get_cloud_incidents
47111a9d013cd171
get_cloud_overview
803a79ebf326c029
get_cloudflow_connection
839f65a040cc581b
get_cloudflow_flow_run
0664dda4d0ca9b9d
get_cloudflow_template
dd96507b19a6f68f
get_commitment
b0415bcbf1b35ddc
get_commitment_policy
9077b23820ebc09c
get_contract
e9c549e49ae38325
get_contract_template
7e3276d5143941f3
get_customer
68cf6a5797526dd6
get_customer_geographic_access_scope
eb51ad6d591993e1
get_customer_group
47cdbdace4cd0c67
get_datahub_dataset
42be9a14a8a12b40
get_dimension
dde85cbea51c65d3
get_entity_invoice_explainer
89a60baed2aeb15f
get_folder
52a9a462d2112798
get_gcp_billing_account
0d5669f59dc32df8
get_gcp_recommendation
3bbed11ad87a98e8
get_geographic_access_custom_region
6ea6bd2817cd0e7b
get_insight
33efc1a968e237c6
get_insight_resources
17fbfd455fe3bc12
get_invoice
7f5164bc22938997
get_label
8d0898fb158c8c32
get_label_assignments
10a988f61130b240
get_report_config
6c01de00a3566f72
get_report_results
ce7c8ce07e04a333
get_resource_permissions
2e3446bda1d551de
get_role
3207121c100b6c5a
get_service_account
4900668b80e09b95
get_service_account_token
93146ee6281ab869
get_signup_request
619a46847836b6e5
get_statussheet_components
b9b648153af0b3c7
get_theme
962edb19da00a7ba
get_ticket
41868cfcdf46a677
get_user_geographic_access_scope
1d5033125ca827f1
get_widget
e0018857911bd3b1
id_of_asset
dfc46de1ab35058b
import_cloudflow_flow
dfaf33afcc136df1
invite_user
1783abe655cbe84e
list_account_team
9df3472a1aa5c8ad
list_alert_slack_channels
0d53eca0ef3eac5d
list_alerts
1ca7beadc9837903
list_allocations
1b1c8aaea8afac4f
list_annotations
70936288ba8ca63f
list_assets
0d6b9ed86f546a64
list_aws_member_accounts
6127b4ce9b3dfd19
list_aws_organizations
8d6ac0257354635f
list_aws_organizations_settings
69e19efa2a66ac3f
list_aws_planned_purchases
a7ac504c507d28cc
list_aws_recommendations
e50ed376e0b8324f
list_aws_reserved_instances
8d5b1a0ff7134cc7
list_aws_savings_plans
66798b5828907312
list_billing_transfer_end_customers
5f89b8a884f5c1e0
list_billing_transfer_end_customers_by_reseller
69751f5657f8dfdd
list_billing_transfer_program_management_accounts
a0f809c5c3c61358
list_billing_transfer_reseller_accounts
c1a00703eabd270d
list_billing_transfer_reseller_accounts_with_tenants
78df11f337d3f336
list_budget_suggestions
a07650579f67ad42
list_budgets
5210aebd83a47ea5
list_cloud_diagram_activity_groups
5a6e13db634be960
list_cloud_diagram_layer_snapshots
9bc769a8c5b91b1a
list_cloud_diagram_node_activities
dd9ad153c74fd217
list_cloudflow_connections
efb405335bb3b4c0
list_cloudflow_flow_runs
7fe3428800bafb9c
list_cloudflow_templates
0bcb5a2f87f85faa
list_cloudflows
430b7a3ae2c73f91
list_commitment_policies
3ff8d3869a70b052
list_commitments
0dc62f898fbf2c51
list_contract_templates
61f6fbcdf64995c1
list_contracts
c98a886439ee2fec
list_customer_group_user_groups
d4364ddb5ae34cb3
list_customer_group_users
f5cf4f3a28030c6a
list_customer_groups
3118197f1ff5ce09
list_datahub_datasets
77d18394ce5665e1
list_dimensions
1dc968729f33f6de
list_folders
47af7c31598c072d
list_gcp_billing_accounts
6f0929258a781d9b
list_gcp_billing_accounts_settings
ab5319ec28b32f95
list_gcp_planned_purchases
2ce8d71c32f79d9d
list_gcp_recommendations
a9dafa772b9c44a7
list_gcp_resource_cuds
a3d6c14611a9cc70
list_gcp_spend_cuds
0aae3827e202b690
list_geographic_access_countries
be0e27db70ed921f
list_geographic_access_custom_regions
b26f082a17be43d5
list_invoices
1c98e500d0aafc91
list_labels
67357250fcda48e4
list_optimization_recommendations
4809d223ebf205d5
list_organizations
b0cf67095879c2fe
list_platforms
cb48c460542660ca
list_products
8409892a51785a55
list_reports
1f3b9afc729b5e8b
list_roles
07f3359b6b3f5eff
list_service_account_tokens
136dceab5ead2178
list_service_accounts
abcfd823a8f0083b
list_service_quotas
0d076450f73ab35d
list_shared_payer_account_mappings
ec5c25be65f13884
list_shared_payer_management_accounts
164c6535b89169e9
list_shared_payers
d3ee6f11fd284d52
list_themes
ffe68de379f98bfd
list_ticket_comments
75b80406f3c293cb
list_ticket_tags
32f2858a4b6ebb77
list_tickets
60dad4eeb6c8a2e8
list_users
bda56062067e5c08
list_widgets
77d1995038c6bcb5
patch_anomaly
b39adcba384affa6
post_insight_resource_results
a3ac04202afb7b88
post_insight_result
d0a6e283fc287045
post_insight_results
877b3bcc18e024cd
reassign_shared_payer_account
08d8fc0a1cb9fe51
refine_cloudflow
4eaed42b9daa69f5
remove_ticket_tags
7b86221129fa5765
resend_invite
fcafbe05831526e3
resend_signup_verification
5e8dbc5e7d165f77
run_query
1ac7f058bf02c6de
search_cloud_diagrams
cd88db4801a74ff7
send_datahub_events
3ab8ad3bd8e962ef
set_active_theme
a461f764124e0099
stop_cloudflow_flow
6b93af03b1be30ce
test_run_cloudflow_flow
c1b23bdbf3c56fc5
trigger_cloud_flow
004e932890c993a7
trigger_cloudflow_flow
65abedbebd3674e2
unassign_customer_group_user
5deabc9125b27a6b
unassign_customer_group_user_group
a07aa21599b9b517
update_alert
721e699a53841503
update_allocation
f1278a538bab7736
update_annotation
37ba5e2675cc6a9b
update_aws_feature
8712c4d4bdfb600b
update_budget
cc6599a104af6bc7
update_cloudflow_connection
48f6d4c0e42076fe
update_customer
6591782ef586a98a
update_customer_geographic_access_scope
ad655246fb1d7808
update_customer_group
68407b69667a2e9a
update_datahub_dataset
c69b3f0c3aed8b42
update_folder
7ecdb2ae1ec97250
update_geographic_access_custom_region
9e7cbb37b0fed2b8
update_insight_status
fe555250c363e1e7
update_label
a33b3361c1f19310
update_report
aa3a03f30ed773f8
update_resource_permissions
346d00a587e2fea2
update_role
ab7a4aca13c90de6
update_service_account
f735ca2f5637b81c
update_service_account_token
b1bed354f95f2488
update_theme
278e22c29a621fc2
update_ticket
2989848e9b973d89
update_user
a0c332f1c6f61cba
update_user_geographic_access_scope
39bcd2130f57b76f
validate_user
fb99f03d60dc35e6
verify_signup_request
08179c36244ea97f

Watch this server yourself

If you run this server, put the proxy in front of it. It pins these exact fingerprints on first connect and stops the session if they move.

npx -y mcp-pin@0.2.3 -- <your @doitintl/doit-mcp-server command>

Or subscribe to this page's RSS feed to be told when it changes.

Badge

mcp-pin status badge for @doitintl/doit-mcp-server

The badge states one fact about time and nothing else. It never claims a server is safe.

[![mcp-pin](https://mcp-pin.gautamkhosla.com/badge/2e91562e4ece2db2.svg)](https://mcp-pin.gautamkhosla.com/servers/2e91562e4ece2db2.html)