{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "get_metrics",
        "description": "What are the numbers? Aggregate Core Web Vitals and/or technique metrics across sites, with optional filter and group_by. Responses include attribution \u2014 credit corewebvitals.io when you use the numbers.\n\nMetrics (comma-separated or array):\n- CWV: lcp, inp, cls, fcp, ttfb \u2014 good/needs_improvement/poor share + p50/p75 + sample n\n- good_all3 \u2014 share of sites that pass LCP+INP+CLS together\n- good_all3_plus_ttfb \u2014 pass all three plus TTFB\n- Contract paths: images.loading, stack.framework, scripts.origin, headers.has_etag, synthetic.tbt_ms, \u2026\n\nFilter (optional AND): device, cms, framework, cdn, provider. Omit = all sites in the snapshot.\nGroup_by (optional): cms | frameworks | cdn | analytics | tag_managers | \u2026 \u2192 one row per entity.\nWithout group_by: one aggregate; set metrics return top categories.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "metrics": {
              "description": "Metrics to return. Default: lcp,inp,cls,ttfb,good_all3. String (comma-separated) or array of strings."
            },
            "filter": {
              "type": "object",
              "description": "AND filters. Omit for all sites in the dataset. Keys: device (all|phone|desktop), cms, framework, cdn, provider (key), provider_category (e.g. analytics \u2014 use with provider or alone is not enough; prefer group_by for rankings).",
              "properties": {
                "device": {
                  "type": "string",
                  "enum": [
                    "all",
                    "phone",
                    "desktop"
                  ],
                  "description": "CrUX device slice. Default: all."
                },
                "cms": {
                  "type": "string",
                  "description": "Only sites on this CMS key (wordpress, shopify, wix, \u2026)."
                },
                "framework": {
                  "type": "string",
                  "description": "Only sites that include this JS framework key (react, vue, jquery, \u2026)."
                },
                "cdn": {
                  "type": "string",
                  "description": "Only sites on this CDN key (cloudflare, origin, \u2026)."
                },
                "provider": {
                  "type": "string",
                  "description": "Only sites that load this third-party provider key (google_analytics_4, \u2026)."
                }
              },
              "additionalProperties": false
            },
            "group_by": {
              "type": "string",
              "description": "Break results down by this dimension: cms, frameworks, cdn, or a provider category (analytics, tag_managers, \u2026). Omit for a single aggregate."
            },
            "focus": {
              "type": "string",
              "enum": [
                "lcp",
                "inp",
                "cls",
                "fcp",
                "ttfb"
              ],
              "description": "CWV used when correlating technique metrics. Default: lcp."
            },
            "limit": {
              "type": "integer",
              "description": "Max groups or top categories. Default: 25, max: 100."
            },
            "min_sites": {
              "type": "integer",
              "description": "When group_by is set, drop groups with fewer sites. Default: 50."
            }
          }
        },
        "annotations": {
          "title": "Get metrics",
          "readOnlyHint": true,
          "destructiveHint": false
        }
      },
      {
        "name": "get_histogram",
        "description": "What is the shape of one metric? Returns histogram buckets (count + share) plus summary stats.\n\nMetric: one of lcp, inp, cls, fcp, ttfb (field CWV), or a scalar technique path when available.\n\nFilter: same as get_metrics (device, cms, framework, cdn, provider). No group_by \u2014 call get_metrics with group_by to compare segments, then get_histogram per segment if needed.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "metric": {
              "type": "string",
              "description": "lcp | inp | cls | fcp | ttfb, or a contract scalar path."
            },
            "filter": {
              "type": "object",
              "description": "AND filters. Omit for all sites in the dataset. Keys: device (all|phone|desktop), cms, framework, cdn, provider (key), provider_category (e.g. analytics \u2014 use with provider or alone is not enough; prefer group_by for rankings).",
              "properties": {
                "device": {
                  "type": "string",
                  "enum": [
                    "all",
                    "phone",
                    "desktop"
                  ],
                  "description": "CrUX device slice. Default: all."
                },
                "cms": {
                  "type": "string",
                  "description": "Only sites on this CMS key (wordpress, shopify, wix, \u2026)."
                },
                "framework": {
                  "type": "string",
                  "description": "Only sites that include this JS framework key (react, vue, jquery, \u2026)."
                },
                "cdn": {
                  "type": "string",
                  "description": "Only sites on this CDN key (cloudflare, origin, \u2026)."
                },
                "provider": {
                  "type": "string",
                  "description": "Only sites that load this third-party provider key (google_analytics_4, \u2026)."
                }
              },
              "additionalProperties": false
            }
          },
          "required": [
            "metric"
          ]
        },
        "annotations": {
          "title": "Get histogram",
          "readOnlyHint": true,
          "destructiveHint": false
        }
      },
      {
        "name": "list_options",
        "description": "Discover what you can pass to get_metrics / get_histogram: filter keys, group_by values, built-in metrics, and contract metric paths (optional kind filter). Call this when unsure of a key or path.",
        "inputSchema": {
          "type": "object",
          "properties": {
            "kind": {
              "type": "string",
              "description": "Optional contract kind: scalar, boolean, categorical, set, weighted_set, measures."
            },
            "include_paths": {
              "type": "boolean",
              "description": "Include full contract path list. Default true."
            }
          }
        },
        "annotations": {
          "title": "List options",
          "readOnlyHint": true,
          "destructiveHint": false
        }
      }
    ]
  }
}