Skip to main content
Glama

SEO GSC Wizard MCP

Find decaying content

find_decaying_content
Read-only

Use this when the user asks which pages or queries are losing clicks. Finds queries or pages losing traffic between a baseline (earlier) period and a recent period. startDate/endDate is the RECENT period; comparisonStartDate/comparisonEndDate is the BASELINE period. Not for a period-by-period matrix (clicks/impressions/position per month or week, like the app's Query Decay / Content Decay pages): use get_decay_overview; for position movers, get_ranking_changes. A key is considered when its baseline has at least minImpressions impressions (default 100; when you leave it out and nothing qualifies, the tool retries once at 10 and reports minImpressionsAutoRelaxed; a value you pass is always applied as given) and at least minBaselineClicks clicks (default 5; decliners under it are counted in belowClickFloor). Each row has clicksLost (baseline minus recent) and a severity that needs both a share and an absolute loss: severe = over 50% AND at least 5 clicks lost, moderate = over 20% AND at least 2, otherwise mild. lowConfidence: true marks a loss under 2 Poisson standard deviations ((baseline - recent) / sqrt(baseline + recent) < 2), which chance alone produces. pattern is the LIKELY cause read from the key's own totals (proving a query-mix shift needs a page x query read); first match wins: lost_from_search (no recent impressions), ranking_loss (position 3+ worse), long_tail_pruned (position 3+ better AND impressions down 30%+: low-ranked impressions dropped away, which lifts the average position), demand_drop (position steady, impressions down 20%+), low_volume (under 10 baseline clicks), ctr_loss (position and impressions steady, CTR down), else unclear. positionDelta is recentPosition - baselinePosition, so POSITIVE means WORSE; it is 0 for a key with no recent row. Returns at most limit rows (default 100, max 1000), ordered by sortBy: clicksLost (default, largest loss first) or clickChangePct (most negative first); sortedBy/sortOrder state it. With dimension query only the queries Google lists can appear: on most properties a large share of clicks has no query row (analyze_sampling_impact measures it). The baseline is scanned for its top scanLimit keys by clicks (warehouse: max(limit*10, 1000), capped at 50000; live API: 25000 rows per period). On the warehouse every scanned key's recent figure is exact. On the live API the recent period is its own top 25000, so a key missing from a full recent read is not known to be at zero: its recent clicks are at most the smallest count that read kept. When that ceiling is still below the key's baseline, the row is reported with recentIsUpperBound: true: recentClicks is the ceiling, the real loss is AT LEAST |clickChangePct| (and clicksLost), severity is a floor, and its recent impressions and position are unknown (0). When the ceiling shows no loss, the key is left out and counted in unresolvedKeys. When the two windows differ in length the comparison is per day: baseline clicks are scaled to the recent window (windowNormalization says so; each row adds baselineClicksScaled, which clickChangePct, clicksLost and minBaselineClicks use, and baselineClicks stays the raw total). truncated: true means a read hit its cap, so counts are measured within the scan, not across the whole property. Served from the GSC Wizard ClickHouse warehouse when available, otherwise the live Search Console API (see dataSource). Date range is optional: omit startDate/endDate to analyze the last 28 settled days (data lags ~2-3 days).

Input Schema

NameRequiredDescriptionDefault
limitNoMaximum decaying rows to return (1-1000).
sortByNoRow order: clicksLost (largest absolute loss first, the default) or clickChangePct (most negative first).clicksLost
endDateNoOptional. Window end as YYYY-MM-DD (e.g. 2026-05-31). You do NOT need to know today's date or the latest available date: omit this and the server uses the latest settled Search Console date (data lags ~2-3 days behind today). Never pass null or the string "null".
siteUrlYes
dimensionNopage
startDateNoOptional. Window start as YYYY-MM-DD (e.g. 2026-05-03). You do NOT need to know today's date. Omit BOTH startDate and endDate to analyze the last 28 settled days automatically (Search Console data lags ~2-3 days). Never pass null or the string "null".
searchTypeNoSearch type: web (default), image, video, news (the News tab), discover, googleNews (news.google.com), or all (web + image + video + news + discover combined, position impression-weighted, like the app's "All" filter). Discover and googleNews carry no query dimension, so query-level results for them are empty, and no position: it reads null, not 0.web
minImpressionsNoMinimum baseline impressions per key (default 100). When left out and nothing qualifies, the tool retries once at 10 and reports `minImpressionsAutoRelaxed`; a value you pass, including 100, is always applied as given.
comparisonEndDateNoOptional. End of the baseline / comparison period as YYYY-MM-DD. Omit both comparison dates to use the same-length period immediately before the current window; give only this one to end a baseline of the same length here.
minBaselineClicksNoMinimum baseline clicks per key (default 5). Decliners under it are left out and counted in `belowClickFloor`; 1 lists every decliner.
comparisonStartDateNoOptional. Start of the baseline / comparison period as YYYY-MM-DD. Omit both comparison dates to use the same-length period immediately before the current window; give only this one to start a baseline of the same length here.

Output Schema

NameRequiredDescriptionDefault
noteNo
countsNo
recentNo
thenByNo
listKeyNoName of the top-level field that holds the rows sortedBy describes.
siteUrlNo
warningNo
baselineNo
decayingNo
nextStepNo
orderingNo
sortedByNo
dimensionNo
scanLimitNo
sortOrderNo
thenOrderNo
truncatedNo
dataSourceNo
partialDaysNo
dataMaturityNo
emptyBecauseNo
methodLimitsNo
minImpressionsNo
settledThroughNo
unresolvedKeysNo
belowClickFloorNo
minBaselineClicksNo
warehouseLatestDateNo
windowNormalizationNo
minImpressionsAutoRelaxedNo

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed14 schema fields changed
    • addedInput schema / properties / minBaselineClicks
      Added value: +{
      +  "default": 5,
      +  "description": "Minimum baseline clicks per key (default 5). Decliners under it are left out and counted in `belowClickFloor`; 1 lists every decliner.",
      +  "minimum": 0,
      +  "type": "integer"
      +}
    • removedInput schema / properties / minImpressions / default
      Removed value: -100
    • addedInput schema / properties / minImpressions / description
      Added value: +"Minimum baseline impressions per key (default 100). When left out and nothing qualifies, the tool retries once at 10 and reports `minImpressionsAutoRelaxed`; a value you pass, including 100, is always applied as given."
    • addedInput schema / properties / sortBy
      Added value: +{
      +  "default": "clicksLost",
      +  "description": "Row order: clicksLost (largest absolute loss first, the default) or clickChangePct (most negative first).",
      +  "enum": [
      +    "clicksLost",
      +    "clickChangePct"
      +  ],
      +  "type": "string"
      +}
    • addedOutput schema / properties / belowClickFloor
      Added value: +{
      +  "$ref": "#/properties/recent/anyOf/0/properties/days"
      +}
    • addedOutput schema / properties / decaying / items / properties / clicksLost
      Added value: +{
      +  "$ref": "#/properties/recent/anyOf/0/properties/days"
      +}
    • addedOutput schema / properties / decaying / items / properties / lowConfidence
      Added value: +{
      +  "type": [
      +    "boolean",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / decaying / items / properties / pattern
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / decaying / items / properties / recentIsUpperBound / $ref
      Added value: +"#/properties/decaying/items/properties/lowConfidence"
    • removedOutput schema / properties / decaying / items / properties / recentIsUpperBound / type
      Removed value: -[
      -  "boolean",
      -  "null"
      -]
    • addedOutput schema / properties / listKey
      Added value: +{
      +  "$ref": "#/properties/siteUrl",
      +  "description": "Name of the top-level field that holds the rows sortedBy describes."
      +}
    • addedOutput schema / properties / minBaselineClicks
      Added value: +{
      +  "$ref": "#/properties/recent/anyOf/0/properties/days"
      +}
    • addedOutput schema / properties / minImpressionsAutoRelaxed
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": true,
      +      "properties": {
      +        "from": {
      +          "$ref": "#/properties/recent/anyOf/0/properties/days"
      +        },
      +        "to": {
      +          "$ref": "#/properties/recent/anyOf/0/properties/days"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / truncated / $ref
      Previous value: -"#/properties/decaying/items/properties/recentIsUpperBound"New value: +"#/properties/decaying/items/properties/lowConfidence"
  2. Changed1 schema field changed
    • changedInput schema / properties / searchType / description
      Previous value: -"Search type: web (default), image, video, news (the News tab), discover, googleNews (news.google.com), or all (web + image + video + news + discover combined, position impression-weighted, like the app's \"All\" filter). Discover and googleNews carry no query dimension, so query-level results for them are empty."New value: +"Search type: web (default), image, video, news (the News tab), discover, googleNews (news.google.com), or all (web + image + video + news + discover combined, position impression-weighted, like the app's \"All\" filter). Discover and googleNews carry no query dimension, so query-level results for them are empty, and no position: it reads null, not 0."
  3. Changed2 schema fields changed
    • addedInput schema / properties / searchType / description
      Added value: +"Search type: web (default), image, video, news (the News tab), discover, googleNews (news.google.com), or all (web + image + video + news + discover combined, position impression-weighted, like the app's \"All\" filter). Discover and googleNews carry no query dimension, so query-level results for them are empty."
    • changedInput schema / properties / searchType / enum
      Previous value: -[
      -  "web",
      -  "image",
      -  "video",
      -  "news"
      -]New value: +[
      +  "web",
      +  "image",
      +  "video",
      +  "news",
      +  "discover",
      +  "googleNews",
      +  "all"
      +]
  4. Changed16 schema fields changed
    • changedOutput schema / additionalProperties
      Previous value: -falseNew value: +true
    • changedOutput schema / properties / counts / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "mild": {
      -        "$ref": "#/properties/recent/anyOf/0/properties/days"
      -      },
      -      "moderate": {
      -        "$ref": "#/properties/recent/anyOf/0/properties/days"
      -      },
      -      "severe": {
      -        "$ref": "#/properties/recent/anyOf/0/properties/days"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "properties": {
      +      "mild": {
      +        "$ref": "#/properties/recent/anyOf/0/properties/days"
      +      },
      +      "moderate": {
      +        "$ref": "#/properties/recent/anyOf/0/properties/days"
      +      },
      +      "severe": {
      +        "$ref": "#/properties/recent/anyOf/0/properties/days"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / dataMaturity / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "dateBasis": {
      -        "$ref": "#/properties/siteUrl"
      -      },
      -      "firstIncompleteDate": {
      -        "$ref": "#/properties/siteUrl"
      -      },
      -      "note": {
      -        "$ref": "#/properties/siteUrl"
      -      },
      -      "probe": {
      -        "anyOf": [
      -          {
      -            "additionalProperties": false,
      -            "properties": {
      -              "dataState": {
      -                "$ref": "#/properties/siteUrl"
      -              },
      -              "endDate": {
      -                "$ref": "#/properties/siteUrl"
      -              },
      -              "searchType": {
      -                "$ref": "#/properties/siteUrl"
      -              },
      -              "startDate": {
      -                "$ref": "#/properties/siteUrl"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          {
      -            "type": "null"
      -          }
      -        ]
      -      },
      -      "settledThrough": {
      -        "$ref": "#/properties/siteUrl"
      -      },
      -      "source": {
      -        "$ref": "#/properties/siteUrl"
      -      },
      -      "warehouseCutoff": {
      -        "$ref": "#/properties/siteUrl"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "properties": {
      +      "dateBasis": {
      +        "$ref": "#/properties/siteUrl"
      +      },
      +      "firstIncompleteDate": {
      +        "$ref": "#/properties/siteUrl"
      +      },
      +      "note": {
      +        "$ref": "#/properties/siteUrl"
      +      },
      +      "probe": {
      +        "anyOf": [
      +          {
      +            "additionalProperties": true,
      +            "properties": {
      +              "dataState": {
      +                "$ref": "#/properties/siteUrl"
      +              },
      +              "endDate": {
      +                "$ref": "#/properties/siteUrl"
      +              },
      +              "searchType": {
      +                "$ref": "#/properties/siteUrl"
      +              },
      +              "startDate": {
      +                "$ref": "#/properties/siteUrl"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          {
      +            "type": "null"
      +          }
      +        ]
      +      },
      +      "settledThrough": {
      +        "$ref": "#/properties/siteUrl"
      +      },
      +      "source": {
      +        "$ref": "#/properties/siteUrl"
      +      },
      +      "warehouseCutoff": {
      +        "$ref": "#/properties/siteUrl"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedOutput schema / properties / decaying / items / additionalProperties
      Previous value: -falseNew value: +true
    • addedOutput schema / properties / emptyBecause
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / methodLimits
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / nextStep
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / ordering
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": {
      +        "additionalProperties": true,
      +        "properties": {
      +          "sortOrder": {
      +            "$ref": "#/properties/siteUrl"
      +          },
      +          "sortedBy": {
      +            "$ref": "#/properties/siteUrl"
      +          },
      +          "thenBy": {
      +            "$ref": "#/properties/siteUrl"
      +          },
      +          "thenOrder": {
      +            "$ref": "#/properties/siteUrl"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • addedOutput schema / properties / partialDays
      Added value: +{
      +  "anyOf": [
      +    {
      +      "items": {
      +        "type": "string"
      +      },
      +      "type": "array"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
    • changedOutput schema / properties / recent / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "days": {
      -        "type": [
      -          "number",
      -          "null"
      -        ]
      -      },
      -      "endDate": {
      -        "$ref": "#/properties/siteUrl"
      -      },
      -      "startDate": {
      -        "$ref": "#/properties/siteUrl"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "properties": {
      +      "days": {
      +        "type": [
      +          "number",
      +          "null"
      +        ]
      +      },
      +      "endDate": {
      +        "$ref": "#/properties/siteUrl"
      +      },
      +      "startDate": {
      +        "$ref": "#/properties/siteUrl"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • addedOutput schema / properties / sortOrder
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / sortedBy
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / thenBy
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / thenOrder
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / warning
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • changedOutput schema / properties / windowNormalization / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "comparisonDays": {
      -        "$ref": "#/properties/recent/anyOf/0/properties/days"
      -      },
      -      "currentDays": {
      -        "$ref": "#/properties/recent/anyOf/0/properties/days"
      -      },
      -      "note": {
      -        "$ref": "#/properties/siteUrl"
      -      },
      -      "scale": {
      -        "$ref": "#/properties/recent/anyOf/0/properties/days"
      -      }
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": true,
      +    "properties": {
      +      "comparisonDays": {
      +        "$ref": "#/properties/recent/anyOf/0/properties/days"
      +      },
      +      "currentDays": {
      +        "$ref": "#/properties/recent/anyOf/0/properties/days"
      +      },
      +      "note": {
      +        "$ref": "#/properties/siteUrl"
      +      },
      +      "scale": {
      +        "$ref": "#/properties/recent/anyOf/0/properties/days"
      +      }
      +    },
      +    "type": "object"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
  5. Changed5 schema fields changed
    • changedInput schema / properties / comparisonEndDate / description
      Previous value: -"Optional. End of the baseline / comparison period as YYYY-MM-DD. Omit both comparison dates to use the same-length period immediately before the current window."New value: +"Optional. End of the baseline / comparison period as YYYY-MM-DD. Omit both comparison dates to use the same-length period immediately before the current window; give only this one to end a baseline of the same length here."
    • changedInput schema / properties / comparisonStartDate / description
      Previous value: -"Optional. Start of the baseline / comparison period as YYYY-MM-DD. Omit both comparison dates to use the same-length period immediately before the current window."New value: +"Optional. Start of the baseline / comparison period as YYYY-MM-DD. Omit both comparison dates to use the same-length period immediately before the current window; give only this one to start a baseline of the same length here."
    • addedOutput schema / properties / decaying / items / properties / baselineClicksScaled
      Added value: +{
      +  "$ref": "#/properties/recent/anyOf/0/properties/days"
      +}
    • addedOutput schema / properties / warehouseLatestDate
      Added value: +{
      +  "$ref": "#/properties/siteUrl"
      +}
    • addedOutput schema / properties / windowNormalization
      Added value: +{
      +  "anyOf": [
      +    {
      +      "additionalProperties": false,
      +      "properties": {
      +        "comparisonDays": {
      +          "$ref": "#/properties/recent/anyOf/0/properties/days"
      +        },
      +        "currentDays": {
      +          "$ref": "#/properties/recent/anyOf/0/properties/days"
      +        },
      +        "note": {
      +          "$ref": "#/properties/siteUrl"
      +        },
      +        "scale": {
      +          "$ref": "#/properties/recent/anyOf/0/properties/days"
      +        }
      +      },
      +      "type": "object"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ]
      +}
  6. First observed

TDQS

A4.8/5.0
Behavior5/5

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

Annotations only declare read-only/non-destructive; the description adds substantial behavior: default minImpression auto-relax to 10 with the minImpressionsAutoRelaxed flag, severity rules requiring both share and absolute loss, lowConfidence Poisson threshold, deterministic pattern-classification order, warehouse vs live-API scan caps, recentIsUpperBound semantics, windowNormalization, and truncated counts. This is exactly the kind of context annotations cannot carry.

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

Conciseness4/5

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

Front-loaded correctly: the selection cue and date-role explanation come first. It is long and dense, though, and some implementation detail (the exact Poisson formula, warehouse row caps) is heavier than an agent needs for selection, so a little trimming would help.

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

Completeness5/5

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

For an 11-parameter tool that switches between a warehouse and the live API and has an output schema, the description covers the traps that would cause wrong calls or wrong interpretation: upper-bound rows, unresolved keys, per-day normalization, and truncation. Nothing material to correct invocation is missing.

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

Parameters4/5

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

Schema coverage is already 82%, so the baseline is 3; the description still adds real meaning beyond the schema — which date pair is recent vs baseline, that a passed minImpressions is never auto-relaxed, that minBaselineClicks decliners land in belowClickFloor, and that sortBy ordering is largest-loss or most-negative-percentage first. Remaining gaps are minor (siteUrl and searchType behavior are left to the schema).

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

Purpose5/5

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

Opens with a specific verb+resource+user intent ('which pages or queries are losing clicks') and immediately names the baseline-vs-recent comparison model. It explicitly distinguishes itself from get_decay_overview (period matrix) and get_ranking_changes (position movers), so the agent can select it without opening any schema.

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

Usage Guidelines5/5

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

Gives explicit when-to-use ('when the user asks which pages or queries are losing clicks'), explicit when-not-to-use, and names two concrete alternatives with the conditions that select each. It also flags the query-dimension sampling caveat and points to analyze_sampling_impact.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources