
CTR change, click decomposition and known Search Console data anomalies for numbers you provide.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Lists the known Google Search Console reporting issues, taken from Google's own notices, that overlap the dates you give, with the affected metrics, the sources they apply to and the source link. Without dates it lists every known issue. compare_ctr_periods runs the same check on its own periods; this tool is for dates you compare elsewhere.
Where the numbers come from: gsc_ui_export (Search Console Performance report or its export), bulk_export (BigQuery bulk export), api (Search Console API) or other. Some reporting issues apply to one source only.
Up to four date ranges to check. Leave out to list every known issue.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http mcp-server https://clickdecay.com/mcp
Lists the known Google Search Console reporting issues, taken from Google's own notices, that overlap the dates you give, with the affected metrics, the sources they apply to and the source link. Without dates it lists every known issue. compare_ctr_periods runs the same check on its own periods; this tool is for dates you compare elsewhere.
| Argument | Type | Description |
|---|---|---|
| source | string | Where the numbers come from: gsc_ui_export (Search Console Performance report or its export), bulk_export (BigQuery bulk export), api (Search Console API) or other. Some reporting issues apply to one source only. |
| periods | array | Up to four date ranges to check. Leave out to list every known issue. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"source": {
"enum": [
"gsc_ui_export",
"bulk_export",
"api",
"other"
],
"type": "string",
"description": "Where the numbers come from: gsc_ui_export (Search Console Performance report or its export), bulk_export (BigQuery bulk export), api (Search Console API) or other. Some reporting issues apply to one source only."
},
"periods": {
"type": "array",
"items": {
"type": "object",
"required": [
"start",
"end"
],
"properties": {
"end": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Last day, YYYY-MM-DD, inclusive."
},
"start": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "First day, YYYY-MM-DD, inclusive."
}
},
"additionalProperties": false
},
"maxItems": 4,
"minItems": 1,
"description": "Up to four date ranges to check. Leave out to list every known issue."
}
},
"additionalProperties": false
}Compares clicks, impressions and CTR of two equal-length, non-overlapping periods whose totals you provide, for example from Google Search Console. It splits the click change into an impressions component and a CTR component and checks the dates against known Search Console reporting issues, withholding impression-based figures for affected dates. Use it when you have totals for two periods; for a single what-if, project_clicks_at_ctr and impressions_needed_for_clicks fit better. The result does not establish why CTR changed; the warning NO_AI_CAUSATION is always included.
| Argument | Type | Description |
|---|---|---|
| prior* | object | Totals of the earlier period, for example from the Search Console Performance report. |
| source | string | Where the numbers come from: gsc_ui_export (Search Console Performance report or its export), bulk_export (BigQuery bulk export), api (Search Console API) or other. Some reporting issues apply to one source only. |
| current* | object | Totals of the later period, for example from the Search Console Performance report. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"prior",
"current"
],
"properties": {
"prior": {
"type": "object",
"required": [
"start",
"end",
"clicks",
"impressions"
],
"properties": {
"end": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Last day of the earlier period, YYYY-MM-DD, inclusive."
},
"start": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "First day of the earlier period, YYYY-MM-DD, inclusive."
},
"clicks": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Total clicks in the earlier period, a whole number."
},
"impressions": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Total impressions in the earlier period, a whole number, at least the clicks."
}
},
"description": "Totals of the earlier period, for example from the Search Console Performance report.",
"additionalProperties": false
},
"source": {
"enum": [
"gsc_ui_export",
"bulk_export",
"api",
"other"
],
"type": "string",
"description": "Where the numbers come from: gsc_ui_export (Search Console Performance report or its export), bulk_export (BigQuery bulk export), api (Search Console API) or other. Some reporting issues apply to one source only."
},
"current": {
"type": "object",
"required": [
"start",
"end",
"clicks",
"impressions"
],
"properties": {
"end": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "Last day of the later period, YYYY-MM-DD, inclusive."
},
"start": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"description": "First day of the later period, YYYY-MM-DD, inclusive."
},
"clicks": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Total clicks in the later period, a whole number."
},
"impressions": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Total impressions in the later period, a whole number, at least the clicks."
}
},
"description": "Totals of the later period, for example from the Search Console Performance report.",
"additionalProperties": false
}
},
"additionalProperties": false
}Calculates how many impressions a click target needs at a CTR you choose (clicks ÷ CTR). Use it to size a goal; project_clicks_at_ctr goes the other way. The result is a modelled value. With a CTR of 0 there is no answer, and the result gives the reason instead of a number.
| Argument | Type | Description |
|---|---|---|
| clicks* | integer | The click target, a whole number. |
| ctrPercent* | number | CTR as a percentage from 0 to 100: 3 means 3%, 0.5 means 0.5%. Not a fraction. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"clicks",
"ctrPercent"
],
"properties": {
"clicks": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "The click target, a whole number."
},
"ctrPercent": {
"type": "number",
"maximum": 100,
"minimum": 0,
"description": "CTR as a percentage from 0 to 100: 3 means 3%, 0.5 means 0.5%. Not a fraction."
}
},
"additionalProperties": false
}Calculates the clicks a number of impressions would earn at a CTR you choose (impressions × CTR). Use it for a what-if on one period; compare_ctr_periods is for two observed periods and impressions_needed_for_clicks for the opposite direction. The result is a modelled value and may be fractional.
| Argument | Type | Description |
|---|---|---|
| ctrPercent* | number | CTR as a percentage from 0 to 100: 3 means 3%, 0.5 means 0.5%. Not a fraction. |
| impressions* | integer | Impressions of the period, a whole number. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"impressions",
"ctrPercent"
],
"properties": {
"ctrPercent": {
"type": "number",
"maximum": 100,
"minimum": 0,
"description": "CTR as a percentage from 0 to 100: 3 means 3%, 0.5 means 0.5%. Not a fraction."
},
"impressions": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Impressions of the period, a whole number."
}
},
"additionalProperties": false
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 12, 2026.