LeaderboardBack to leaderboard — loading return destination
Opening report…
Loading report overview
M
MCP server
server.example.com/mcp
Tools and resources for your MCP client, with a public quality report and detailed checks.
Protocol
MCP 2025-11-25
Server version
1.0.0
Website
server.example.com
Supports
Tools · Resources
Overall score
90 /100
How is this score calculated?
Server metadata
Loading server metadata
Reviewed90/100
Discoverability
Loading discoverability
Reviewed90/100
Protocol
Loading protocol
Reviewed90/100
Tools
Loading tools
Reviewed90/100
MCP Apps
Loading mcp apps
Reviewed90/100
Tool documentation quality
Loading tool documentation quality
Reviewed90/100
LeaderboardBack to leaderboard — loading return destination
H
HYPD AI for SEO & GEO
seo.hypd.ai/mcp
HYPD's SEO and GEO workspace: Search Console performance, keyword and SERP research with AI summaries, AI answer visibility, competitor and backlink analysis, page audits, and optional GA4 landing-page traffic
HYPD's SEO and GEO workspace: Search Console performance, keyword and SERP research with AI summaries, AI answer visibility, competitor and backlink analysis, page audits, and optional GA4 landing-page traffic
HYPD SEO & GEO: how a site is found in Google's organic results, its AI Overviews and ChatGPT's answers. seo_gsc_* read the user's own Search Console, seo_ga4_* their GA4 (optional), and the research tools work for any site or keyword without a connection. Call `init` at the start of a new conversation and follow the guide it returns. Pass location and language from what the user said or ask them; never assume worldwide. Search Console and GA4 are the user's own measured data; research figures are third-party estimates, so say which is which. Each research lookup uses the user's plan allowance; paging a stored result with result_id is free. Report tool errors as errors — never invent rankings, volumes or citations a tool did not return.
Discoverability
2 pass · 1 partial2 passed · 1 partial42/100
Client listings and public setup information.
mcp.json or server-card.json
Either mcp.json or an MCP Server Card declaring this endpoint passes.
The MCP Server Card declares this server's exact endpoint.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Returns the SEO & GEO guide — call it first in a new conversation. It explains which seo_* tool answers which question, workflows for an organic traffic drop, a content brief, a competitor gap and an AI visibility check, which data is the user's own and which is a third-party estimate, how lookups use the plan allowance, and starter prompts.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No input fields.
Annotations100/100
All four behavior hints are declared.
{
"title": "Load the SEO & GEO guide",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
Output schema80/100
The output schema explains the structured result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"skill"
],
"properties": {
"skill": {
"type": "object",
"required": [
"name",
"title",
"description",
"updatedAt",
"content"
],
"properties": {
"name": {
"type": "string",
"description": "The guide's id."
},
"title": {
"type": "string",
"description": "The guide's title."
},
"content": {
"type": "string",
"description": "The guide itself, in Markdown."
},
"updatedAt": {
"type": [
"string",
"null"
],
"description": "When the guide last changed (ISO 8601), if known."
},
"description": {
"type": "string",
"description": "What the guide covers."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "init",
"title": "Load the SEO & GEO guide",
"description": "Returns the SEO & GEO guide — call it first in a new conversation. It explains which seo_* tool answers which question, workflows for an organic traffic drop, a content brief, a competitor gap and an AI visibility check, which data is the user's own and which is a third-party estimate, how lookups use the plan allowance, and starter prompts.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"skill"
],
"properties": {
"skill": {
"type": "object",
"required": [
"name",
"title",
"description",
"updatedAt",
"content"
],
"properties": {
"name": {
"type": "string",
"description": "The guide's id."
},
"title": {
"type": "string",
"description": "The guide's title."
},
"content": {
"type": "string",
"description": "The guide itself, in Markdown."
},
"updatedAt": {
"type": [
"string",
"null"
],
"description": "When the guide last changed (ISO 8601), if known."
},
"description": {
"type": "string",
"description": "What the guide covers."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Load the SEO & GEO guide",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
The Search Console properties the user has selected in HYPD, each with its permission level: the site_url every other seo_gsc_* tool takes. Call it first for any question about the user's own organic performance and copy site_url exactly as returned ('sc-domain:example.com' is a domain property, 'https://example.com/' a URL-prefix one; never turn one into the other). Takes no arguments. An empty list means Search Console isn't connected yet or no property is selected: the research tools still work without it, so offer those and hypd_show_getting_started. A property added in Google lately appears once the user refreshes Search Console in HYPD.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"sites"
],
"properties": {
"sites": {
"type": "array",
"items": {
"type": "object",
"properties": {
"siteUrl": {
"type": "string",
"description": "The property identity to pass as site_url, verbatim."
},
"permissionLevel": {
"type": "string",
"description": "The user's access, e.g. siteOwner or siteFullUser."
}
},
"additionalProperties": {}
},
"description": "Properties the user selected for HYPD, by site_url."
},
"plan_notice": {
"type": "string",
"description": "Explains properties held back by the user's plan."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_gsc_list_sites",
"title": "List Search Console sites",
"description": "The Search Console properties the user has selected in HYPD, each with its permission level: the site_url every other seo_gsc_* tool takes. Call it first for any question about the user's own organic performance and copy site_url exactly as returned ('sc-domain:example.com' is a domain property, 'https://example.com/' a URL-prefix one; never turn one into the other). Takes no arguments. An empty list means Search Console isn't connected yet or no property is selected: the research tools still work without it, so offer those and hypd_show_getting_started. A property added in Google lately appears once the user refreshes Search Console in HYPD.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"sites"
],
"properties": {
"sites": {
"type": "array",
"items": {
"type": "object",
"properties": {
"siteUrl": {
"type": "string",
"description": "The property identity to pass as site_url, verbatim."
},
"permissionLevel": {
"type": "string",
"description": "The user's access, e.g. siteOwner or siteFullUser."
}
},
"additionalProperties": {}
},
"description": "Properties the user selected for HYPD, by site_url."
},
"plan_notice": {
"type": "string",
"description": "Explains properties held back by the user's plan."
}
},
"additionalProperties": false
},
"annotations": {
"title": "List Search Console sites",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
The user's own organic clicks, impressions, CTR and average position from Search Console, grouped by up to two dimensions (query, page, country, device, date, search appearance) with filters. Position is impression-weighted, not a rank: filter position bands after fetching. To see a page's queries or a query's pages, use seo_gsc_page_query_breakdown instead of grouping by both (Google's load quota). Dates default to the 28 days ending 3 days ago; data_state 'final' is the default, 'all' adds fresh but provisional days. row_limit defaults to 250 (max 25,000); page with start_row. truncated and row_count flag an incomplete result. Rare queries are anonymised, so query rows never sum to the site's totals. Copy site_url from seo_gsc_list_sites.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Remove repeated schema validation from descriptions; focus on meaning and usage context.
site_url
The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other.
Clear enough to supply this argument.
start_date
Start of the date range, within Search Console's 16-month retention. Defaults to a 28-day window ending 3 days ago, where finalized data ends.
Clear enough to supply this argument.
end_date
End of the date range. Defaults to 3 days ago, where finalized data ends.
Clear enough to supply this argument.
dimensions
Row grouping. Do NOT group page and query together — that is the load-quota trap; use seo_gsc_page_query_breakdown instead.
Clear enough to supply this argument.
search_type
Search surface. Keep analyses on ONE surface: image CTR runs ~5-6x lower than web at the same position, so mixing surfaces corrupts CTR baselines.
Clear enough to supply this argument.
data_state
Which days count. 'final' covers only days Google has finalized, which lag 2-3 days. 'all' adds the latest days, matching the live Search Console dashboard, whose numbers can still change. The response echoes which state and dates were used.
Clear enough to supply this argument.
row_limit
The most rows to return on this call. The response's truncated says whether more exist; page with start_row for them.
Clear enough to supply this argument.
start_row
Zero-based index of the first row. For the next page, repeat the query with start_row plus the previous row_count.
Clear enough to supply this argument.
filters › items › dimension
The row field this filter tests.
Clear enough to supply this argument.
filters › items › operator
How expression is matched: exact value, substring, or an RE2 regular expression.
Clear enough to supply this argument.
filters › items › expression
The value to match: a query or URL fragment, a lowercase ISO 3166-1 alpha-3 country such as 'usa', or a device: DESKTOP, MOBILE or TABLET.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"keys": {
"type": "array",
"items": {
"type": "string"
},
"description": "One value per requested dimension, in request order. Absent for an ungrouped total."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Average position of the topmost result, 1 is first."
},
"impressions": {
"type": "number",
"description": "Times a result was shown in Google Search."
}
},
"additionalProperties": {}
},
"description": "Metrics per dimension combination."
},
"query": {
"type": "object",
"required": [
"startDate",
"endDate",
"searchType",
"dataState",
"dimensions",
"rowLimit",
"estimatedDataFinalizedThrough"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last day queried."
},
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"type": "string",
"description": "How expression was matched."
},
"dimension": {
"type": "string",
"description": "The row field tested."
},
"expression": {
"type": "string",
"description": "The value matched."
}
},
"additionalProperties": false
},
"description": "The filters applied, ANDed together."
},
"rowLimit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows requested."
},
"startRow": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Index of the first row returned."
},
"dataState": {
"type": "string",
"description": "'final' or 'all'; 'all' rows can still change."
},
"startDate": {
"type": "string",
"description": "First day queried."
},
"dimensions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row grouping actually applied. [] means NO grouping was applied and rows hold one site-wide aggregate — if you asked for a breakdown and see [], your dimensions argument did not arrive (check its spelling)."
},
"searchType": {
"type": "string",
"description": "Search surface queried."
},
"estimatedDataFinalizedThrough": {
"type": "string",
"description": "Estimated last day Google has finalized (~3 days behind today; Google exposes no exact value). Rows after this date are provisional and can change retroactively when data_state is 'all'."
}
},
"description": "The query as executed, defaults filled in.",
"additionalProperties": false
},
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows returned on this call."
},
"truncated": {
"type": "boolean",
"description": "True when the site had more rows than row_limit returned — treat the data as INCOMPLETE and say so; raise row_limit or page with start_row to see the rest."
},
"load_quota_warning": {
"type": "string",
"description": "Present when the query grouped page and query together — the load-quota trap. The data is real; the shape is what to avoid."
},
"anonymized_queries_note": {
"type": "string",
"description": "Explains why query rows don't sum to site totals."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_gsc_query_search_analytics",
"title": "Query organic search performance",
"description": "The user's own organic clicks, impressions, CTR and average position from Search Console, grouped by up to two dimensions (query, page, country, device, date, search appearance) with filters. Position is impression-weighted, not a rank: filter position bands after fetching. To see a page's queries or a query's pages, use seo_gsc_page_query_breakdown instead of grouping by both (Google's load quota). Dates default to the 28 days ending 3 days ago; data_state 'final' is the default, 'all' adds fresh but provisional days. row_limit defaults to 250 (max 25,000); page with start_row. truncated and row_count flag an incomplete result. Rare queries are anonymised, so query rows never sum to the site's totals. Copy site_url from seo_gsc_list_sites.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"site_url"
],
"properties": {
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"enum": [
"equals",
"notEquals",
"contains",
"notContains",
"includingRegex",
"excludingRegex"
],
"type": "string",
"description": "How expression is matched: exact value, substring, or an RE2 regular expression."
},
"dimension": {
"enum": [
"query",
"page",
"country",
"device",
"searchAppearance"
],
"type": "string",
"description": "The row field this filter tests."
},
"expression": {
"type": "string",
"minLength": 1,
"description": "The value to match: a query or URL fragment, a lowercase ISO 3166-1 alpha-3 country such as 'usa', or a device: DESKTOP, MOBILE or TABLET."
}
}
},
"maxItems": 4,
"description": "Row filters, ANDed together (e.g. country equals 'usa', page contains '/blog/')."
},
"end_date": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "End of the date range. Defaults to 3 days ago, where finalized data ends."
},
"site_url": {
"type": "string",
"minLength": 1,
"description": "The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other."
},
"row_limit": {
"type": "integer",
"default": 250,
"maximum": 25000,
"minimum": 1,
"description": "The most rows to return on this call. The response's truncated says whether more exist; page with start_row for them."
},
"start_row": {
"type": "integer",
"default": 0,
"maximum": 9007199254740991,
"minimum": 0,
"description": "Zero-based index of the first row. For the next page, repeat the query with start_row plus the previous row_count."
},
"data_state": {
"enum": [
"final",
"all"
],
"type": "string",
"default": "final",
"description": "Which days count. 'final' covers only days Google has finalized, which lag 2-3 days. 'all' adds the latest days, matching the live Search Console dashboard, whose numbers can still change. The response echoes which state and dates were used."
},
"dimensions": {
"type": "array",
"items": {
"enum": [
"query",
"page",
"country",
"device",
"date",
"searchAppearance"
],
"type": "string"
},
"maxItems": 2,
"description": "Row grouping. Do NOT group page and query together — that is the load-quota trap; use seo_gsc_page_query_breakdown instead."
},
"start_date": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "Start of the date range, within Search Console's 16-month retention. Defaults to a 28-day window ending 3 days ago, where finalized data ends."
},
"search_type": {
"enum": [
"web",
"image",
"video",
"news",
"discover",
"googleNews"
],
"type": "string",
"default": "web",
"description": "Search surface. Keep analyses on ONE surface: image CTR runs ~5-6x lower than web at the same position, so mixing surfaces corrupts CTR baselines."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"keys": {
"type": "array",
"items": {
"type": "string"
},
"description": "One value per requested dimension, in request order. Absent for an ungrouped total."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Average position of the topmost result, 1 is first."
},
"impressions": {
"type": "number",
"description": "Times a result was shown in Google Search."
}
},
"additionalProperties": {}
},
"description": "Metrics per dimension combination."
},
"query": {
"type": "object",
"required": [
"startDate",
"endDate",
"searchType",
"dataState",
"dimensions",
"rowLimit",
"estimatedDataFinalizedThrough"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last day queried."
},
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"type": "string",
"description": "How expression was matched."
},
"dimension": {
"type": "string",
"description": "The row field tested."
},
"expression": {
"type": "string",
"description": "The value matched."
}
},
"additionalProperties": false
},
"description": "The filters applied, ANDed together."
},
"rowLimit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows requested."
},
"startRow": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Index of the first row returned."
},
"dataState": {
"type": "string",
"description": "'final' or 'all'; 'all' rows can still change."
},
"startDate": {
"type": "string",
"description": "First day queried."
},
"dimensions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row grouping actually applied. [] means NO grouping was applied and rows hold one site-wide aggregate — if you asked for a breakdown and see [], your dimensions argument did not arrive (check its spelling)."
},
"searchType": {
"type": "string",
"description": "Search surface queried."
},
"estimatedDataFinalizedThrough": {
"type": "string",
"description": "Estimated last day Google has finalized (~3 days behind today; Google exposes no exact value). Rows after this date are provisional and can change retroactively when data_state is 'all'."
}
},
"description": "The query as executed, defaults filled in.",
"additionalProperties": false
},
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows returned on this call."
},
"truncated": {
"type": "boolean",
"description": "True when the site had more rows than row_limit returned — treat the data as INCOMPLETE and say so; raise row_limit or page with start_row to see the rest."
},
"load_quota_warning": {
"type": "string",
"description": "Present when the query grouped page and query together — the load-quota trap. The data is real; the shape is what to avoid."
},
"anonymized_queries_note": {
"type": "string",
"description": "Explains why query rows don't sum to site totals."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Query organic search performance",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Pass exactly one of page (a URL) for the queries it gets impressions and clicks for, or query for the pages Google shows for it. The tool for title and meta rewrites, content refreshes and cannibalisation checks (several pages competing for one query), done with a filter so it never trips Google's load quota. Rows carry clicks, impressions, CTR and impression-weighted position; truncated with row_count says more rows existed. A page's rare queries are anonymised, so its query rows never sum to its totals. Copy site_url from seo_gsc_list_sites.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove repeated schema validation from descriptions; focus on meaning and usage context.
site_url
The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other.
Clear enough to supply this argument.
page
A page URL: returns the queries driving traffic to it. Pass exactly one of page or query.
Clear enough to supply this argument.
query
A search query: returns the pages it lands on. Pass exactly one of page or query.
Clear enough to supply this argument.
start_date
Start of the date range, within Search Console's 16-month retention. Defaults to a 28-day window ending 3 days ago, where finalized data ends.
Clear enough to supply this argument.
end_date
End of the date range. Defaults to 3 days ago, where finalized data ends.
Clear enough to supply this argument.
search_type
Search surface. Keep analyses on ONE surface: image CTR runs ~5-6x lower than web at the same position, so mixing surfaces corrupts CTR baselines.
Clear enough to supply this argument.
data_state
Which days count. 'final' covers only days Google has finalized, which lag 2-3 days. 'all' adds the latest days, matching the live Search Console dashboard, whose numbers can still change. The response echoes which state and dates were used.
Clear enough to supply this argument.
row_limit
The most rows to return on this call. The response's truncated says whether more exist.
Clear enough to supply this argument.
Annotations100/100
All four behavior hints are declared.
{
"title": "Break down a page's queries",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
Output schema79/100
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"keys": {
"type": "array",
"items": {
"type": "string"
},
"description": "One value per requested dimension, in request order. Absent for an ungrouped total."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Average position of the topmost result, 1 is first."
},
"impressions": {
"type": "number",
"description": "Times a result was shown in Google Search."
}
},
"additionalProperties": {}
},
"description": "Metrics per dimension combination."
},
"query": {
"type": "object",
"required": [
"startDate",
"endDate",
"searchType",
"dataState",
"dimensions",
"rowLimit",
"estimatedDataFinalizedThrough"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last day queried."
},
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"type": "string",
"description": "How expression was matched."
},
"dimension": {
"type": "string",
"description": "The row field tested."
},
"expression": {
"type": "string",
"description": "The value matched."
}
},
"additionalProperties": false
},
"description": "The filters applied, ANDed together."
},
"rowLimit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows requested."
},
"startRow": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Index of the first row returned."
},
"dataState": {
"type": "string",
"description": "'final' or 'all'; 'all' rows can still change."
},
"startDate": {
"type": "string",
"description": "First day queried."
},
"dimensions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row grouping actually applied. [] means NO grouping was applied and rows hold one site-wide aggregate — if you asked for a breakdown and see [], your dimensions argument did not arrive (check its spelling)."
},
"searchType": {
"type": "string",
"description": "Search surface queried."
},
"estimatedDataFinalizedThrough": {
"type": "string",
"description": "Estimated last day Google has finalized (~3 days behind today; Google exposes no exact value). Rows after this date are provisional and can change retroactively when data_state is 'all'."
}
},
"description": "The query as executed, defaults filled in.",
"additionalProperties": false
},
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows returned on this call."
},
"truncated": {
"type": "boolean",
"description": "True when the site had more rows than row_limit returned — treat the data as INCOMPLETE and say so; raise row_limit or page with start_row to see the rest."
},
"load_quota_warning": {
"type": "string",
"description": "Present when the query grouped page and query together — the load-quota trap. The data is real; the shape is what to avoid."
},
"anonymized_queries_note": {
"type": "string",
"description": "Explains why query rows don't sum to site totals."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_gsc_page_query_breakdown",
"title": "Break down a page's queries",
"description": "Pass exactly one of page (a URL) for the queries it gets impressions and clicks for, or query for the pages Google shows for it. The tool for title and meta rewrites, content refreshes and cannibalisation checks (several pages competing for one query), done with a filter so it never trips Google's load quota. Rows carry clicks, impressions, CTR and impression-weighted position; truncated with row_count says more rows existed. A page's rare queries are anonymised, so its query rows never sum to its totals. Copy site_url from seo_gsc_list_sites.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"site_url"
],
"properties": {
"page": {
"type": "string",
"minLength": 1,
"description": "A page URL: returns the queries driving traffic to it. Pass exactly one of page or query."
},
"query": {
"type": "string",
"minLength": 1,
"description": "A search query: returns the pages it lands on. Pass exactly one of page or query."
},
"end_date": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "End of the date range. Defaults to 3 days ago, where finalized data ends."
},
"site_url": {
"type": "string",
"minLength": 1,
"description": "The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other."
},
"row_limit": {
"type": "integer",
"default": 250,
"maximum": 25000,
"minimum": 1,
"description": "The most rows to return on this call. The response's truncated says whether more exist."
},
"data_state": {
"enum": [
"final",
"all"
],
"type": "string",
"default": "final",
"description": "Which days count. 'final' covers only days Google has finalized, which lag 2-3 days. 'all' adds the latest days, matching the live Search Console dashboard, whose numbers can still change. The response echoes which state and dates were used."
},
"start_date": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "Start of the date range, within Search Console's 16-month retention. Defaults to a 28-day window ending 3 days ago, where finalized data ends."
},
"search_type": {
"enum": [
"web",
"image",
"video",
"news",
"discover",
"googleNews"
],
"type": "string",
"default": "web",
"description": "Search surface. Keep analyses on ONE surface: image CTR runs ~5-6x lower than web at the same position, so mixing surfaces corrupts CTR baselines."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"keys": {
"type": "array",
"items": {
"type": "string"
},
"description": "One value per requested dimension, in request order. Absent for an ungrouped total."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Average position of the topmost result, 1 is first."
},
"impressions": {
"type": "number",
"description": "Times a result was shown in Google Search."
}
},
"additionalProperties": {}
},
"description": "Metrics per dimension combination."
},
"query": {
"type": "object",
"required": [
"startDate",
"endDate",
"searchType",
"dataState",
"dimensions",
"rowLimit",
"estimatedDataFinalizedThrough"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last day queried."
},
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"type": "string",
"description": "How expression was matched."
},
"dimension": {
"type": "string",
"description": "The row field tested."
},
"expression": {
"type": "string",
"description": "The value matched."
}
},
"additionalProperties": false
},
"description": "The filters applied, ANDed together."
},
"rowLimit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows requested."
},
"startRow": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Index of the first row returned."
},
"dataState": {
"type": "string",
"description": "'final' or 'all'; 'all' rows can still change."
},
"startDate": {
"type": "string",
"description": "First day queried."
},
"dimensions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row grouping actually applied. [] means NO grouping was applied and rows hold one site-wide aggregate — if you asked for a breakdown and see [], your dimensions argument did not arrive (check its spelling)."
},
"searchType": {
"type": "string",
"description": "Search surface queried."
},
"estimatedDataFinalizedThrough": {
"type": "string",
"description": "Estimated last day Google has finalized (~3 days behind today; Google exposes no exact value). Rows after this date are provisional and can change retroactively when data_state is 'all'."
}
},
"description": "The query as executed, defaults filled in.",
"additionalProperties": false
},
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows returned on this call."
},
"truncated": {
"type": "boolean",
"description": "True when the site had more rows than row_limit returned — treat the data as INCOMPLETE and say so; raise row_limit or page with start_row to see the rest."
},
"load_quota_warning": {
"type": "string",
"description": "Present when the query grouped page and query together — the load-quota trap. The data is real; the shape is what to avoid."
},
"anonymized_queries_note": {
"type": "string",
"description": "Explains why query rows don't sum to site totals."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Break down a page's queries",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Compares two periods of the user's organic search performance with correct date math: pass the current period, and the previous one defaults to the equal window just before it. One row per page (default) or other dimension, with current, previous and delta clicks, impressions, CTR and position: the tool for "organic traffic dropped: since when, and which pages and queries lost it?". Keep data_state "final" (the default), or unfinalized recent days read as a drop. current_truncated or previous_truncated means a side was cut: raise row_limit before calling a row new or lost. Position deltas compare impression-weighted averages, not ranks.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
site_url
The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other.
Clear enough to supply this argument.
current_start_date
Start of the current period, the one being explained.
Clear enough to supply this argument.
current_end_date
End of the current period.
Clear enough to supply this argument.
previous_start_date
Start of the comparison period. Defaults to the immediately preceding window of equal length.
Clear enough to supply this argument.
previous_end_date
End of the comparison period. Pass it with previous_start_date, or neither for the default window.
Clear enough to supply this argument.
dimensions
Row grouping to compare by. Defaults to page.
Clear enough to supply this argument.
search_type
Search surface. Keep analyses on ONE surface: image CTR runs ~5-6x lower than web at the same position, so mixing surfaces corrupts CTR baselines.
Clear enough to supply this argument.
data_state
Which days count. 'final' covers only days Google has finalized, which lag 2-3 days. 'all' adds the latest days, matching the live Search Console dashboard, whose numbers can still change. The response echoes which state and dates were used.
Clear enough to supply this argument.
row_limit
The most rows to return on this call. The response's truncated says whether more exist.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keys",
"current",
"previous",
"delta"
],
"properties": {
"keys": {
"type": "array",
"items": {
"type": "string"
},
"description": "One value per dimension, in request order."
},
"delta": {
"anyOf": [
{
"type": "object",
"required": [
"clicks",
"impressions",
"ctr",
"position"
],
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Impression-weighted AVERAGE position across the row's impressions, not a rank. There is no position filter in the API — filter fetched rows yourself for position-band analyses (e.g. striking distance 8-15)."
},
"impressions": {
"type": "number",
"description": "Times a result was shown."
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "current minus previous; null unless both exist."
},
"current": {
"anyOf": [
{
"type": "object",
"required": [
"clicks",
"impressions",
"ctr",
"position"
],
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Impression-weighted AVERAGE position across the row's impressions, not a rank. There is no position filter in the API — filter fetched rows yourself for position-band analyses (e.g. striking distance 8-15)."
},
"impressions": {
"type": "number",
"description": "Times a result was shown."
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "Current period; null when the row is absent there."
},
"previous": {
"anyOf": [
{
"type": "object",
"required": [
"clicks",
"impressions",
"ctr",
"position"
],
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Impression-weighted AVERAGE position across the row's impressions, not a rank. There is no position filter in the API — filter fetched rows yourself for position-band analyses (e.g. striking distance 8-15)."
},
"impressions": {
"type": "number",
"description": "Times a result was shown."
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "Previous period; null when the row is absent there."
}
},
"additionalProperties": false
},
"description": "One row per dimension combination seen in either period."
},
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
},
"current_period": {
"type": "object",
"required": [
"startDate",
"endDate",
"searchType",
"dataState",
"dimensions",
"rowLimit",
"estimatedDataFinalizedThrough"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last day queried."
},
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"type": "string",
"description": "How expression was matched."
},
"dimension": {
"type": "string",
"description": "The row field tested."
},
"expression": {
"type": "string",
"description": "The value matched."
}
},
"additionalProperties": false
},
"description": "The filters applied, ANDed together."
},
"rowLimit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows requested."
},
"startRow": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Index of the first row returned."
},
"dataState": {
"type": "string",
"description": "'final' or 'all'; 'all' rows can still change."
},
"startDate": {
"type": "string",
"description": "First day queried."
},
"dimensions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row grouping actually applied. [] means NO grouping was applied and rows hold one site-wide aggregate — if you asked for a breakdown and see [], your dimensions argument did not arrive (check its spelling)."
},
"searchType": {
"type": "string",
"description": "Search surface queried."
},
"estimatedDataFinalizedThrough": {
"type": "string",
"description": "Estimated last day Google has finalized (~3 days behind today; Google exposes no exact value). Rows after this date are provisional and can change retroactively when data_state is 'all'."
}
},
"description": "The current query as executed.",
"additionalProperties": false
},
"previous_period": {
"type": "object",
"required": [
"startDate",
"endDate",
"searchType",
"dataState",
"dimensions",
"rowLimit",
"estimatedDataFinalizedThrough"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last day queried."
},
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"type": "string",
"description": "How expression was matched."
},
"dimension": {
"type": "string",
"description": "The row field tested."
},
"expression": {
"type": "string",
"description": "The value matched."
}
},
"additionalProperties": false
},
"description": "The filters applied, ANDed together."
},
"rowLimit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows requested."
},
"startRow": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Index of the first row returned."
},
"dataState": {
"type": "string",
"description": "'final' or 'all'; 'all' rows can still change."
},
"startDate": {
"type": "string",
"description": "First day queried."
},
"dimensions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row grouping actually applied. [] means NO grouping was applied and rows hold one site-wide aggregate — if you asked for a breakdown and see [], your dimensions argument did not arrive (check its spelling)."
},
"searchType": {
"type": "string",
"description": "Search surface queried."
},
"estimatedDataFinalizedThrough": {
"type": "string",
"description": "Estimated last day Google has finalized (~3 days behind today; Google exposes no exact value). Rows after this date are provisional and can change retroactively when data_state is 'all'."
}
},
"description": "The previous query as executed.",
"additionalProperties": false
},
"current_truncated": {
"type": "boolean",
"description": "True when the current period had more rows than row_limit — rows missing from a clipped period read as appeared/disappeared, so treat the comparison as incomplete."
},
"previous_truncated": {
"type": "boolean",
"description": "True when the previous period had more rows than row_limit — same caveat as current_truncated: a clipped previous period fakes newly-appeared rows."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_gsc_compare_periods",
"title": "Compare organic periods",
"description": "Compares two periods of the user's organic search performance with correct date math: pass the current period, and the previous one defaults to the equal window just before it. One row per page (default) or other dimension, with current, previous and delta clicks, impressions, CTR and position: the tool for \"organic traffic dropped: since when, and which pages and queries lost it?\". Keep data_state \"final\" (the default), or unfinalized recent days read as a drop. current_truncated or previous_truncated means a side was cut: raise row_limit before calling a row new or lost. Position deltas compare impression-weighted averages, not ranks.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"site_url",
"current_start_date",
"current_end_date"
],
"properties": {
"site_url": {
"type": "string",
"minLength": 1,
"description": "The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other."
},
"row_limit": {
"type": "integer",
"default": 250,
"maximum": 25000,
"minimum": 1,
"description": "The most rows to return on this call. The response's truncated says whether more exist."
},
"data_state": {
"enum": [
"final",
"all"
],
"type": "string",
"default": "final",
"description": "Which days count. 'final' covers only days Google has finalized, which lag 2-3 days. 'all' adds the latest days, matching the live Search Console dashboard, whose numbers can still change. The response echoes which state and dates were used."
},
"dimensions": {
"type": "array",
"items": {
"enum": [
"query",
"page",
"country",
"device"
],
"type": "string"
},
"maxItems": 2,
"description": "Row grouping to compare by. Defaults to page."
},
"search_type": {
"enum": [
"web",
"image",
"video",
"news",
"discover",
"googleNews"
],
"type": "string",
"default": "web",
"description": "Search surface. Keep analyses on ONE surface: image CTR runs ~5-6x lower than web at the same position, so mixing surfaces corrupts CTR baselines."
},
"current_end_date": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "End of the current period."
},
"previous_end_date": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "End of the comparison period. Pass it with previous_start_date, or neither for the default window."
},
"current_start_date": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "Start of the current period, the one being explained."
},
"previous_start_date": {
"type": "string",
"format": "date",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$",
"description": "Start of the comparison period. Defaults to the immediately preceding window of equal length."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keys",
"current",
"previous",
"delta"
],
"properties": {
"keys": {
"type": "array",
"items": {
"type": "string"
},
"description": "One value per dimension, in request order."
},
"delta": {
"anyOf": [
{
"type": "object",
"required": [
"clicks",
"impressions",
"ctr",
"position"
],
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Impression-weighted AVERAGE position across the row's impressions, not a rank. There is no position filter in the API — filter fetched rows yourself for position-band analyses (e.g. striking distance 8-15)."
},
"impressions": {
"type": "number",
"description": "Times a result was shown."
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "current minus previous; null unless both exist."
},
"current": {
"anyOf": [
{
"type": "object",
"required": [
"clicks",
"impressions",
"ctr",
"position"
],
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Impression-weighted AVERAGE position across the row's impressions, not a rank. There is no position filter in the API — filter fetched rows yourself for position-band analyses (e.g. striking distance 8-15)."
},
"impressions": {
"type": "number",
"description": "Times a result was shown."
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "Current period; null when the row is absent there."
},
"previous": {
"anyOf": [
{
"type": "object",
"required": [
"clicks",
"impressions",
"ctr",
"position"
],
"properties": {
"ctr": {
"type": "number",
"description": "Click-through rate, from 0 to 1."
},
"clicks": {
"type": "number",
"description": "Clicks from Google Search."
},
"position": {
"type": "number",
"description": "Impression-weighted AVERAGE position across the row's impressions, not a rank. There is no position filter in the API — filter fetched rows yourself for position-band analyses (e.g. striking distance 8-15)."
},
"impressions": {
"type": "number",
"description": "Times a result was shown."
}
},
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "Previous period; null when the row is absent there."
}
},
"additionalProperties": false
},
"description": "One row per dimension combination seen in either period."
},
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
},
"current_period": {
"type": "object",
"required": [
"startDate",
"endDate",
"searchType",
"dataState",
"dimensions",
"rowLimit",
"estimatedDataFinalizedThrough"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last day queried."
},
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"type": "string",
"description": "How expression was matched."
},
"dimension": {
"type": "string",
"description": "The row field tested."
},
"expression": {
"type": "string",
"description": "The value matched."
}
},
"additionalProperties": false
},
"description": "The filters applied, ANDed together."
},
"rowLimit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows requested."
},
"startRow": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Index of the first row returned."
},
"dataState": {
"type": "string",
"description": "'final' or 'all'; 'all' rows can still change."
},
"startDate": {
"type": "string",
"description": "First day queried."
},
"dimensions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row grouping actually applied. [] means NO grouping was applied and rows hold one site-wide aggregate — if you asked for a breakdown and see [], your dimensions argument did not arrive (check its spelling)."
},
"searchType": {
"type": "string",
"description": "Search surface queried."
},
"estimatedDataFinalizedThrough": {
"type": "string",
"description": "Estimated last day Google has finalized (~3 days behind today; Google exposes no exact value). Rows after this date are provisional and can change retroactively when data_state is 'all'."
}
},
"description": "The current query as executed.",
"additionalProperties": false
},
"previous_period": {
"type": "object",
"required": [
"startDate",
"endDate",
"searchType",
"dataState",
"dimensions",
"rowLimit",
"estimatedDataFinalizedThrough"
],
"properties": {
"endDate": {
"type": "string",
"description": "Last day queried."
},
"filters": {
"type": "array",
"items": {
"type": "object",
"required": [
"dimension",
"operator",
"expression"
],
"properties": {
"operator": {
"type": "string",
"description": "How expression was matched."
},
"dimension": {
"type": "string",
"description": "The row field tested."
},
"expression": {
"type": "string",
"description": "The value matched."
}
},
"additionalProperties": false
},
"description": "The filters applied, ANDed together."
},
"rowLimit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Rows requested."
},
"startRow": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Index of the first row returned."
},
"dataState": {
"type": "string",
"description": "'final' or 'all'; 'all' rows can still change."
},
"startDate": {
"type": "string",
"description": "First day queried."
},
"dimensions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Row grouping actually applied. [] means NO grouping was applied and rows hold one site-wide aggregate — if you asked for a breakdown and see [], your dimensions argument did not arrive (check its spelling)."
},
"searchType": {
"type": "string",
"description": "Search surface queried."
},
"estimatedDataFinalizedThrough": {
"type": "string",
"description": "Estimated last day Google has finalized (~3 days behind today; Google exposes no exact value). Rows after this date are provisional and can change retroactively when data_state is 'all'."
}
},
"description": "The previous query as executed.",
"additionalProperties": false
},
"current_truncated": {
"type": "boolean",
"description": "True when the current period had more rows than row_limit — rows missing from a clipped period read as appeared/disappeared, so treat the comparison as incomplete."
},
"previous_truncated": {
"type": "boolean",
"description": "True when the previous period had more rows than row_limit — same caveat as current_truncated: a clipped previous period fakes newly-appeared rows."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Compare organic periods",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Google's index verdict for one URL of the user's property: coverage state, Google-selected versus declared canonical, last crawl, the sitemaps that list it, and mobile and rich-result checks. The tool for "why doesn't this page rank or show up at all?". inspection_url must belong to site_url's property. One URL per call: for several, call it once per URL in parallel (the per-site quota is roomy).
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
site_url
The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other.
Clear enough to supply this argument.
inspection_url
The fully-qualified URL to inspect. Must belong to the site_url property.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
language_code
BCP-47 language for result messages, e.g. en-US.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
},
"inspection_result": {
"type": "object",
"properties": {
"ampResult": {
"type": "object",
"properties": {
"verdict": {
"type": "string",
"description": "PASS, PARTIAL, FAIL, NEUTRAL or VERDICT_UNSPECIFIED."
}
},
"description": "AMP status, present for AMP pages only.",
"additionalProperties": {}
},
"indexStatusResult": {
"type": "object",
"properties": {
"sitemap": {
"type": "array",
"items": {
"type": "string"
},
"description": "Sitemaps that list this URL."
},
"verdict": {
"type": "string",
"description": "PASS when indexed, NEUTRAL when excluded, FAIL or PARTIAL on errors."
},
"crawledAs": {
"type": "string",
"description": "The crawler used: DESKTOP or MOBILE."
},
"coverageState": {
"type": "string",
"description": "Google's reason, e.g. 'Submitted and indexed' or 'Crawled - currently not indexed'."
},
"indexingState": {
"type": "string",
"description": "Whether a noindex blocks indexing, e.g. INDEXING_ALLOWED or BLOCKED_BY_META_TAG."
},
"lastCrawlTime": {
"type": "string",
"description": "When Google last crawled the URL (ISO 8601)."
},
"referringUrls": {
"type": "array",
"items": {
"type": "string"
},
"description": "Pages Google found linking to this URL."
},
"userCanonical": {
"type": "string",
"description": "The canonical URL the page declares."
},
"pageFetchState": {
"type": "string",
"description": "Outcome of the last fetch, e.g. SUCCESSFUL, NOT_FOUND or SERVER_ERROR."
},
"robotsTxtState": {
"type": "string",
"description": "Whether robots.txt allows the crawl: ALLOWED or DISALLOWED."
},
"googleCanonical": {
"type": "string",
"description": "The canonical URL Google chose."
}
},
"description": "Whether the URL is indexed, and why or why not.",
"additionalProperties": {}
},
"richResultsResult": {
"type": "object",
"properties": {
"verdict": {
"type": "string",
"description": "PASS, PARTIAL, FAIL, NEUTRAL or VERDICT_UNSPECIFIED."
},
"detectedItems": {
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": {}
},
"description": "Rich result types found on the page, with their issues."
}
},
"description": "Structured data Google detected for rich results.",
"additionalProperties": {}
},
"inspectionResultLink": {
"type": "string",
"description": "This inspection in the Search Console UI."
},
"mobileUsabilityResult": {
"type": "object",
"properties": {
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": {}
}
},
"verdict": {
"type": "string",
"description": "PASS, PARTIAL, FAIL, NEUTRAL or VERDICT_UNSPECIFIED."
}
},
"description": "Mobile usability. Google retired the report, so VERDICT_UNSPECIFIED is common.",
"additionalProperties": {}
}
},
"description": "Google's URL Inspection result for the URL.",
"additionalProperties": {}
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_gsc_inspect_url",
"title": "Inspect a URL's indexing",
"description": "Google's index verdict for one URL of the user's property: coverage state, Google-selected versus declared canonical, last crawl, the sitemaps that list it, and mobile and rich-result checks. The tool for \"why doesn't this page rank or show up at all?\". inspection_url must belong to site_url's property. One URL per call: for several, call it once per URL in parallel (the per-site quota is roomy).",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"site_url",
"inspection_url"
],
"properties": {
"site_url": {
"type": "string",
"minLength": 1,
"description": "The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other."
},
"language_code": {
"type": "string",
"minLength": 1,
"description": "BCP-47 language for result messages, e.g. en-US."
},
"inspection_url": {
"type": "string",
"minLength": 1,
"description": "The fully-qualified URL to inspect. Must belong to the site_url property."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
},
"inspection_result": {
"type": "object",
"properties": {
"ampResult": {
"type": "object",
"properties": {
"verdict": {
"type": "string",
"description": "PASS, PARTIAL, FAIL, NEUTRAL or VERDICT_UNSPECIFIED."
}
},
"description": "AMP status, present for AMP pages only.",
"additionalProperties": {}
},
"indexStatusResult": {
"type": "object",
"properties": {
"sitemap": {
"type": "array",
"items": {
"type": "string"
},
"description": "Sitemaps that list this URL."
},
"verdict": {
"type": "string",
"description": "PASS when indexed, NEUTRAL when excluded, FAIL or PARTIAL on errors."
},
"crawledAs": {
"type": "string",
"description": "The crawler used: DESKTOP or MOBILE."
},
"coverageState": {
"type": "string",
"description": "Google's reason, e.g. 'Submitted and indexed' or 'Crawled - currently not indexed'."
},
"indexingState": {
"type": "string",
"description": "Whether a noindex blocks indexing, e.g. INDEXING_ALLOWED or BLOCKED_BY_META_TAG."
},
"lastCrawlTime": {
"type": "string",
"description": "When Google last crawled the URL (ISO 8601)."
},
"referringUrls": {
"type": "array",
"items": {
"type": "string"
},
"description": "Pages Google found linking to this URL."
},
"userCanonical": {
"type": "string",
"description": "The canonical URL the page declares."
},
"pageFetchState": {
"type": "string",
"description": "Outcome of the last fetch, e.g. SUCCESSFUL, NOT_FOUND or SERVER_ERROR."
},
"robotsTxtState": {
"type": "string",
"description": "Whether robots.txt allows the crawl: ALLOWED or DISALLOWED."
},
"googleCanonical": {
"type": "string",
"description": "The canonical URL Google chose."
}
},
"description": "Whether the URL is indexed, and why or why not.",
"additionalProperties": {}
},
"richResultsResult": {
"type": "object",
"properties": {
"verdict": {
"type": "string",
"description": "PASS, PARTIAL, FAIL, NEUTRAL or VERDICT_UNSPECIFIED."
},
"detectedItems": {
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": {}
},
"description": "Rich result types found on the page, with their issues."
}
},
"description": "Structured data Google detected for rich results.",
"additionalProperties": {}
},
"inspectionResultLink": {
"type": "string",
"description": "This inspection in the Search Console UI."
},
"mobileUsabilityResult": {
"type": "object",
"properties": {
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": {}
}
},
"verdict": {
"type": "string",
"description": "PASS, PARTIAL, FAIL, NEUTRAL or VERDICT_UNSPECIFIED."
}
},
"description": "Mobile usability. Google retired the report, so VERDICT_UNSPECIFIED is common.",
"additionalProperties": {}
}
},
"description": "Google's URL Inspection result for the URL.",
"additionalProperties": {}
}
},
"additionalProperties": false
},
"annotations": {
"title": "Inspect a URL's indexing",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
The sitemaps submitted for one of the user's Search Console properties, with when each was last submitted and downloaded, whether it is pending, and its warning and error counts by content type. Use it for crawl and indexing hygiene: a sitemap with errors, or important pages missing from every sitemap, often explains pages Google hasn't indexed. Copy site_url from seo_gsc_list_sites.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
site_url
The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"sitemaps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "The sitemap's URL."
},
"type": {
"type": "string",
"description": "sitemap, rssFeed, atomFeed, urlList or notSitemap."
},
"errors": {
"type": "string",
"description": "Processing errors, a count as a decimal string."
},
"contents": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Content type, e.g. web, image or video."
},
"indexed": {
"type": "string",
"description": "Google no longer fills this and returns '0' whatever the index state. Not an index count: inspect URLs one by one instead."
},
"submitted": {
"type": "string",
"description": "URLs submitted, a count as a decimal string."
}
},
"additionalProperties": {}
},
"description": "URL counts per content type."
},
"warnings": {
"type": "string",
"description": "Processing warnings, a count as a decimal string."
},
"isPending": {
"type": "boolean",
"description": "true while Google has yet to process it."
},
"lastSubmitted": {
"type": "string",
"description": "When it was last submitted (ISO 8601)."
},
"lastDownloaded": {
"type": "string",
"description": "When Google last fetched it (ISO 8601)."
},
"isSitemapsIndex": {
"type": "boolean",
"description": "true for a sitemap index that lists other sitemaps."
}
},
"additionalProperties": {}
},
"description": "Every sitemap Google knows for the property."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_gsc_list_sitemaps",
"title": "List submitted sitemaps",
"description": "The sitemaps submitted for one of the user's Search Console properties, with when each was last submitted and downloaded, whether it is pending, and its warning and error counts by content type. Use it for crawl and indexing hygiene: a sitemap with errors, or important pages missing from every sitemap, often explains pages Google hasn't indexed. Copy site_url from seo_gsc_list_sites.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"site_url"
],
"properties": {
"site_url": {
"type": "string",
"minLength": 1,
"description": "The Search Console property EXACTLY as seo_gsc_list_sites returned it: 'sc-domain:example.com' or a URL-prefix like 'https://example.com/'. Never rewrite one form into the other."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"guidance": {
"type": "string",
"description": "What the user should do to connect Search Console."
},
"sitemaps": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "The sitemap's URL."
},
"type": {
"type": "string",
"description": "sitemap, rssFeed, atomFeed, urlList or notSitemap."
},
"errors": {
"type": "string",
"description": "Processing errors, a count as a decimal string."
},
"contents": {
"type": "array",
"items": {
"type": "object",
"properties": {
"type": {
"type": "string",
"description": "Content type, e.g. web, image or video."
},
"indexed": {
"type": "string",
"description": "Google no longer fills this and returns '0' whatever the index state. Not an index count: inspect URLs one by one instead."
},
"submitted": {
"type": "string",
"description": "URLs submitted, a count as a decimal string."
}
},
"additionalProperties": {}
},
"description": "URL counts per content type."
},
"warnings": {
"type": "string",
"description": "Processing warnings, a count as a decimal string."
},
"isPending": {
"type": "boolean",
"description": "true while Google has yet to process it."
},
"lastSubmitted": {
"type": "string",
"description": "When it was last submitted (ISO 8601)."
},
"lastDownloaded": {
"type": "string",
"description": "When Google last fetched it (ISO 8601)."
},
"isSitemapsIndex": {
"type": "boolean",
"description": "true for a sitemap index that lists other sitemaps."
}
},
"additionalProperties": {}
},
"description": "Every sitemap Google knows for the property."
},
"connected": {
"type": "boolean",
"const": false,
"description": "false when no Google Search Console connection exists — follow `guidance`; the data fields are absent."
}
},
"additionalProperties": false
},
"annotations": {
"title": "List submitted sitemaps",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
The user's GA4 properties, grouped by Google Analytics account, as HYPD last synced them: the property_id (properties/<digits>) seo_ga4_landing_pages and seo_ga4_run_report take. Call it before any organic traffic question that needs sessions, engagement or conversions rather than clicks. Takes no arguments. GA4 is optional on this surface: an empty list means it isn't connected, and Search Console and the research tools still work, so carry on with those and mention the user can connect GA4 in HYPD.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"account_summaries"
],
"properties": {
"plan_notice": {
"type": "string",
"description": "Explains properties held back by the user's plan."
},
"account_summaries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"account": {
"type": "string",
"description": "The account id, accounts/<digits>."
},
"displayName": {
"type": "string",
"description": "The account's name."
},
"propertySummaries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string",
"description": "The property_id every report takes."
},
"displayName": {
"type": "string",
"description": "The property's name."
},
"propertyType": {
"type": "string",
"description": "e.g. PROPERTY_TYPE_ORDINARY."
}
},
"additionalProperties": {}
},
"description": "The account's GA4 properties."
}
},
"additionalProperties": {}
},
"description": "The user's selected GA4 accounts and their properties."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_ga4_list_properties",
"title": "List GA4 properties",
"description": "The user's GA4 properties, grouped by Google Analytics account, as HYPD last synced them: the property_id (properties/<digits>) seo_ga4_landing_pages and seo_ga4_run_report take. Call it before any organic traffic question that needs sessions, engagement or conversions rather than clicks. Takes no arguments. GA4 is optional on this surface: an empty list means it isn't connected, and Search Console and the research tools still work, so carry on with those and mention the user can connect GA4 in HYPD.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"account_summaries"
],
"properties": {
"plan_notice": {
"type": "string",
"description": "Explains properties held back by the user's plan."
},
"account_summaries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"account": {
"type": "string",
"description": "The account id, accounts/<digits>."
},
"displayName": {
"type": "string",
"description": "The account's name."
},
"propertySummaries": {
"type": "array",
"items": {
"type": "object",
"properties": {
"property": {
"type": "string",
"description": "The property_id every report takes."
},
"displayName": {
"type": "string",
"description": "The property's name."
},
"propertyType": {
"type": "string",
"description": "e.g. PROPERTY_TYPE_ORDINARY."
}
},
"additionalProperties": {}
},
"description": "The account's GA4 properties."
}
},
"additionalProperties": {}
},
"description": "The user's selected GA4 accounts and their properties."
}
},
"additionalProperties": false
},
"annotations": {
"title": "List GA4 properties",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description91/100
What happens after the click, per landing page: sessions, users, engagement rate, average session duration, conversions and revenue by landing page (with its query string), most sessions first. To see organic search only, pass a dimension_filter on sessionDefaultChannelGroup equal to "Organic Search". Pairs with seo_gsc_query_search_analytics: Search Console says which pages win clicks, this says which of them engage and convert. Pass property_id from seo_ga4_list_properties and date_ranges; optionally limit. Dimensions and metrics are fixed.
The description explains the capability, when to use it, and what to expect.
Inputs77/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
property_id
The GA4 Property ID in properties/<digits> form, from seo_ga4_list_properties.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
date_ranges › items › startDate
Start date: YYYY-MM-DD or a relative date like 28daysAgo.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
date_ranges › items › endDate
End date: YYYY-MM-DD or a relative date like today.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
date_ranges › items › name
A label for this range. With several ranges, rows carry it in the dateRange dimension.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dimension_filter › filter › fieldName
The GA4 dimension or metric API name to filter on.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description77/100
An open GA4 report on the user's property for questions seo_ga4_landing_pages doesn't cover: any dimensions and metrics over up to 4 date_ranges, with dimension_filter or metric_filter (one condition on a field, or an andGroup or orGroup of them), order_bys, limit and offset. For organic traffic, filter sessionDefaultChannelGroup to "Organic Search". GA4 allows at most 10 metrics and 9 dimensions per request. On a rate-limit error, run GA4 calls one at a time and retry after the wait it gives. Pass property_id from seo_ga4_list_properties.
The description explains the capability, when to use it, and what to expect.
Inputs82/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
property_id
The GA4 Property ID in properties/<digits> form, from seo_ga4_list_properties.
Clear enough to supply this argument.
metrics
GA4 metric API names, e.g. sessions, conversions, totalRevenue.
Clear enough to supply this argument.
date_ranges › items › startDate
Start date: YYYY-MM-DD or a relative date like 28daysAgo.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
date_ranges › items › endDate
End date: YYYY-MM-DD or a relative date like today.
Clear enough to supply this argument.
date_ranges › items › name
A label for this range. With several ranges, rows carry it in the dateRange dimension.
Clear enough to supply this argument.
dimensions
GA4 dimension API names, e.g. sessionDefaultChannelGroup.
Explain the meaning of this value, not just its name.
dimension_filter › filter › fieldName
The GA4 dimension or metric API name to filter on.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Broad keyword ideas from 1–20 seed keywords, with monthly search volume, competition and bid ranges, from Google Keyword Planner when the user has Google Ads connected and from a third party otherwise. Use it to brainstorm a topic's keyword space; for SEO difficulty and intent use seo_keyword_overview, for adjacent terms seo_related_keywords, for long-tail variants seo_keyword_suggestions. Pass location and language for the market (United States and English when omitted). Results keep 24 hours: result_id with page, page_size and sort_by re-reads them for free, without keywords, location or language.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
keywords
1-20 seed keywords to find related keyword ideas for. Examples: ["running shoes", "nike running", "marathon training"]
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
language
Target-market language for keyword research, e.g. "English" or "German". No Account-derived default; omit when paging with result_id.
Clear enough to supply this argument.
location
Target-market country for keyword research, e.g. "United States" or "Germany". No Account-derived default; omit when paging with result_id.
Clear enough to supply this argument.
page
Page number to return. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page_size
Rows per page to return. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
Result ID returned by a previous seo_keyword_ideas call. Valid for 24 hours; use for stored pages without a fresh provider request. After expiry, start a fresh lookup.
Clear enough to supply this argument.
sort_by
Sort related keyword ideas by relevance, search volume, competition, or bid metric. With result_id, sorts stored rows before paging.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"columns",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "This page's rows, each keyed by the names in columns."
},
"columns": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "The row fields, in display order."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_keyword_ideas",
"title": "Find keyword ideas",
"description": "Broad keyword ideas from 1–20 seed keywords, with monthly search volume, competition and bid ranges, from Google Keyword Planner when the user has Google Ads connected and from a third party otherwise. Use it to brainstorm a topic's keyword space; for SEO difficulty and intent use seo_keyword_overview, for adjacent terms seo_related_keywords, for long-tail variants seo_keyword_suggestions. Pass location and language for the market (United States and English when omitted). Results keep 24 hours: result_id with page, page_size and sort_by re-reads them for free, without keywords, location or language.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page number to return. Defaults to 1."
},
"sort_by": {
"enum": [
"relevance",
"search_volume",
"competition_index",
"low_top_of_page_bid",
"high_top_of_page_bid"
],
"type": "string",
"description": "Sort related keyword ideas by relevance, search volume, competition, or bid metric. With result_id, sorts stored rows before paging."
},
"keywords": {
"type": "array",
"items": {
"type": "string",
"maxLength": 80,
"minLength": 1
},
"maxItems": 20,
"minItems": 1,
"description": "1-20 seed keywords to find related keyword ideas for. Examples: [\"running shoes\", \"nike running\", \"marathon training\"]"
},
"language": {
"type": "string",
"minLength": 1,
"description": "Target-market language for keyword research, e.g. \"English\" or \"German\". No Account-derived default; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Target-market country for keyword research, e.g. \"United States\" or \"Germany\". No Account-derived default; omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page to return. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "Result ID returned by a previous seo_keyword_ideas call. Valid for 24 hours; use for stored pages without a fresh provider request. After expiry, start a fresh lookup."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"columns",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "This page's rows, each keyed by the names in columns."
},
"columns": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "The row fields, in display order."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Find keyword ideas",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Monthly search volume, the 12-month trend, CPC and competition for 1–1,000 keywords you already have, from Google Keyword Planner when the user has Google Ads connected and from a third party otherwise. Use it to size a keyword list; seo_keyword_overview adds difficulty and intent for up to 100. Pass location and language for the market (United States and English when omitted). Results keep 24 hours: result_id with page, page_size and sort_by re-reads them for free.
The description explains the capability, when to use it, and what to expect.
Inputs82/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
keywords
1-1000 known keywords to get search volume for. Examples: ["running shoes", "nike running", "marathon training"]
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
language
Target-market language for search volume research, e.g. "English" or "German". No Account-derived default; omit when paging with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
location
Target-market country for search volume research, e.g. "United States" or "Germany". No Account-derived default; omit when paging with result_id.
Clear enough to supply this argument.
page
Page number to return. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page_size
Rows per page to return. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
Result ID returned by a previous call to this research tool. Valid for 24 hours; use for stored pages without a fresh provider request. After expiry, start a fresh lookup.
Clear enough to supply this argument.
sort_by
Sort known keywords by relevance, search volume, competition, or bid metric. With result_id, sorts stored rows before paging.
Explain what happens when this optional value is omitted.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"columns",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "This page's rows, each keyed by the names in columns."
},
"columns": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "The row fields, in display order."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_keyword_search_volume",
"title": "Get search volumes",
"description": "Monthly search volume, the 12-month trend, CPC and competition for 1–1,000 keywords you already have, from Google Keyword Planner when the user has Google Ads connected and from a third party otherwise. Use it to size a keyword list; seo_keyword_overview adds difficulty and intent for up to 100. Pass location and language for the market (United States and English when omitted). Results keep 24 hours: result_id with page, page_size and sort_by re-reads them for free.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page number to return. Defaults to 1."
},
"sort_by": {
"enum": [
"relevance",
"search_volume",
"competition_index",
"low_top_of_page_bid",
"high_top_of_page_bid"
],
"type": "string",
"description": "Sort known keywords by relevance, search volume, competition, or bid metric. With result_id, sorts stored rows before paging."
},
"keywords": {
"type": "array",
"items": {
"type": "string",
"maxLength": 80,
"minLength": 1
},
"maxItems": 1000,
"minItems": 1,
"description": "1-1000 known keywords to get search volume for. Examples: [\"running shoes\", \"nike running\", \"marathon training\"]"
},
"language": {
"type": "string",
"minLength": 1,
"description": "Target-market language for search volume research, e.g. \"English\" or \"German\". No Account-derived default; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Target-market country for search volume research, e.g. \"United States\" or \"Germany\". No Account-derived default; omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page to return. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "Result ID returned by a previous call to this research tool. Valid for 24 hours; use for stored pages without a fresh provider request. After expiry, start a fresh lookup."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"columns",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "This page's rows, each keyed by the names in columns."
},
"columns": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "The row fields, in display order."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Get search volumes",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Scores up to 100 keywords for organic search in one market: keyword difficulty (0–100, how hard page one is to reach), main and secondary intent (informational, navigational, commercial, transactional), monthly volume, CPC, yearly trend and the SERP features Google shows. Use it to pick a page's target keyword or decide whether a term is worth the effort. Pass location and language from the market the user named; ask if unknown. Keywords without data are left out. Returns rows and a result_id; paging with result_id is free.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
keywords
Keywords to score for SEO, e.g. a page's target keywords. Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
location
Search-market country, e.g. "United States" or "Germany". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
language
Search language, e.g. "English" or "German". Required for a new lookup; omit when paging with result_id.
Clear enough to supply this argument.
page
Page of rows to return. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page_size
Rows per page. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_keyword_overview",
"title": "Score keywords for SEO",
"description": "Scores up to 100 keywords for organic search in one market: keyword difficulty (0–100, how hard page one is to reach), main and secondary intent (informational, navigational, commercial, transactional), monthly volume, CPC, yearly trend and the SERP features Google shows. Use it to pick a page's target keyword or decide whether a term is worth the effort. Pass location and language from the market the user named; ask if unknown. Keywords without data are left out. Returns rows and a result_id; paging with result_id is free.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"keywords": {
"type": "array",
"items": {
"type": "string",
"maxLength": 80,
"minLength": 1
},
"maxItems": 100,
"minItems": 1,
"description": "Keywords to score for SEO, e.g. a page's target keywords. Required for a new lookup."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Search language, e.g. \"English\" or \"German\". Required for a new lookup; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Search-market country, e.g. \"United States\" or \"Germany\". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Score keywords for SEO",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
Expand internal abbreviations and remove technical prefixes from the display title.
Description94/100
Expands one seed keyword through Google's related searches into adjacent and secondary terms for a content brief, highest volume first, each with difficulty, intent, CPC and trend. depth 1 (default) gives the close neighbours (about 8), depth 2 one step further (about 70). Filter with min_volume and max_difficulty. For longer searches that contain the seed use seo_keyword_suggestions. Pass location and language for the market; ask if unknown. Returns rows and a result_id; paging with result_id is free. More rows cost more.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
keyword
The seed keyword. Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
depth
How far out from the seed to follow Google's related searches: 1 (default, about 8 keywords) or 2 (about 70).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
location
Search-market country, e.g. "United States" or "Germany". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id.
Clear enough to supply this argument.
language
Search language, e.g. "English" or "German". Required for a new lookup; omit when paging with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
min_volume
Only keywords with at least this monthly search volume.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
max_difficulty
Only keywords at or below this keyword difficulty (0–100: how hard it is to reach the top 10 organically).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Page of rows to return. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page_size
Rows per page. Defaults to 10.
Clear enough to supply this argument.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features",
"depth"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"depth": {
"type": [
"number",
"null"
],
"description": "Steps from the seed keyword, 1 for direct."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_related_keywords",
"title": "Find related keywords",
"description": "Expands one seed keyword through Google's related searches into adjacent and secondary terms for a content brief, highest volume first, each with difficulty, intent, CPC and trend. depth 1 (default) gives the close neighbours (about 8), depth 2 one step further (about 70). Filter with min_volume and max_difficulty. For longer searches that contain the seed use seo_keyword_suggestions. Pass location and language for the market; ask if unknown. Returns rows and a result_id; paging with result_id is free. More rows cost more.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"depth": {
"type": "integer",
"maximum": 2,
"minimum": 1,
"description": "How far out from the seed to follow Google's related searches: 1 (default, about 8 keywords) or 2 (about 70)."
},
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id."
},
"keyword": {
"type": "string",
"maxLength": 80,
"minLength": 1,
"description": "The seed keyword. Required for a new lookup."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Search language, e.g. \"English\" or \"German\". Required for a new lookup; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Search-market country, e.g. \"United States\" or \"Germany\". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"min_volume": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Only keywords with at least this monthly search volume."
},
"max_difficulty": {
"type": "integer",
"maximum": 100,
"minimum": 0,
"description": "Only keywords at or below this keyword difficulty (0–100: how hard it is to reach the top 10 organically)."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features",
"depth"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"depth": {
"type": [
"number",
"null"
],
"description": "Steps from the seed keyword, 1 for direct."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Find related keywords",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Longer searches that contain a seed keyword ("running shoes" → "best running shoes for flat feet"), highest volume first, each with difficulty, intent, CPC and trend: the place to find low-difficulty long-tail targets and FAQ-style questions around a topic. Filter with min_volume and max_difficulty. For adjacent terms without the seed use seo_related_keywords. Pass location and language for the market; ask if unknown. Returns rows and a result_id; paging with result_id is free. More rows cost more.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
keyword
The seed keyword: suggestions are longer searches that contain it. Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
location
Search-market country, e.g. "United States" or "Germany". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id.
Clear enough to supply this argument.
language
Search language, e.g. "English" or "German". Required for a new lookup; omit when paging with result_id.
Clear enough to supply this argument.
limit
Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
min_volume
Only keywords with at least this monthly search volume.
Clear enough to supply this argument.
max_difficulty
Only keywords at or below this keyword difficulty (0–100: how hard it is to reach the top 10 organically).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Page of rows to return. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page_size
Rows per page. Defaults to 10.
Clear enough to supply this argument.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_keyword_suggestions",
"title": "Find long-tail keywords",
"description": "Longer searches that contain a seed keyword (\"running shoes\" → \"best running shoes for flat feet\"), highest volume first, each with difficulty, intent, CPC and trend: the place to find low-difficulty long-tail targets and FAQ-style questions around a topic. Filter with min_volume and max_difficulty. For adjacent terms without the seed use seo_related_keywords. Pass location and language for the market; ask if unknown. Returns rows and a result_id; paging with result_id is free. More rows cost more.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id."
},
"keyword": {
"type": "string",
"maxLength": 80,
"minLength": 1,
"description": "The seed keyword: suggestions are longer searches that contain it. Required for a new lookup."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Search language, e.g. \"English\" or \"German\". Required for a new lookup; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Search-market country, e.g. \"United States\" or \"Germany\". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"min_volume": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Only keywords with at least this monthly search volume."
},
"max_difficulty": {
"type": "integer",
"maximum": 100,
"minimum": 0,
"description": "Only keywords at or below this keyword difficulty (0–100: how hard it is to reach the top 10 organically)."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Find long-tail keywords",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
How search interest in 1–5 terms moves over time on Google web search, news, YouTube, images or shopping: the series, the regions where interest is highest and, for a single term, related topics and queries, top and rising. The summary gives each term's direction with its % change, its peak, and the peak and low months over two years or more. Use it for "is this topic growing?", content timing and seasonality. Values are relative interest (0–100 within one call), not volume: use seo_keyword_search_volume for volume. Pass location, or omit it for worldwide. Returns rows and a result_id; paging with result_id is free.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
keywords
Searches to compare, e.g. ["running shoes", "trail shoes"]. Interest is scaled across all of them, so compare terms in one call, not across calls. Related topics and queries come back only for a single keyword. Required for a new lookup.
Clear enough to supply this argument.
location
Country, e.g. "United States" or "Germany". Reuse known market context; omit only for worldwide interest.
Clear enough to supply this argument.
language
Language for topic names, e.g. "German". Defaults to English.
Clear enough to supply this argument.
time_range
Period to cover (default "past_12_months"). past_5_years shows seasonality across years; past_7_days is hourly.
Clear enough to supply this argument.
date_from
Start of a custom range. Replaces time_range.
Clear enough to supply this argument.
date_to
End of a custom range. Replaces time_range.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
search_type
Which Google search to measure (default "web").
Clear enough to supply this argument.
category_code
Google Trends category id to narrow an ambiguous term, e.g. 71 for Food & Drink: the number in a Trends URL's cat= parameter. Omit for all categories.
Clear enough to supply this argument.
page
Page of rows to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Google's results page for one keyword in one market, by block: organic, featured_snippet, people_also_ask, ai_overview, local_pack, related_searches and more. Pass item_types for the blocks you need. Add "ai_overview" for Google's AI Overview text and the pages it cites, with cited_domain to check whether the user's site is among them: the GEO check for Google. With "people_also_ask", paa_depth (1–4) opens the questions' answers and sources for an FAQ brief. Pass location and language from the market the user named; never assume worldwide. Returns paged items and a result_id; paging with result_id is free. Google data combined with third-party data.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Remove repeated schema validation from descriptions; focus on meaning and usage context.
keyword
The single search query to pull SERP results for. Example: "bilan de compétences CPF". Required for a new search; omit when paging with result_id.
Clear enough to supply this argument.
item_types
SERP block types to return, e.g. ["organic"] or ["paid"]. Required for a new search; omit when paging with result_id. Ordering note: if the first element is anything other than "organic", results are ordered by that first type.
Clear enough to supply this argument.
location
Country for the SERP (e.g. "United States", "Germany", "France"). Specify the intended search-market country; the server does not infer it from a Google Ads Account. Reuse known market context or ask the user; do not omit location or assume worldwide on fresh searches. Omit when paging with result_id.
Clear enough to supply this argument.
language
Language for the SERP (e.g. "English", "German", "French"). Specify the intended search language; the server does not infer it from a Google Ads Account. Reuse known market context or ask the user. Omit when paging with result_id.
Clear enough to supply this argument.
device
Device to emulate for the SERP. Defaults to desktop.
Clear enough to supply this argument.
paa_depth
With "people_also_ask" in item_types: how many levels of questions to open, each answer with its source page. Each level costs more; omit for the questions as shown.
Clear enough to supply this argument.
cited_domain
With "ai_overview" in item_types: a domain to look for among the AI Overview's cited pages, e.g. "acme.com". The result says whether it (or a subdomain) is cited.
Clear enough to supply this argument.
page
Page number to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page to return. Defaults to 10.
Clear enough to supply this argument.
result_id
Result ID returned by a previous call to this research tool. Valid for 24 hours; use for stored pages without a fresh provider request. After expiry, start a fresh lookup.
Clear enough to supply this argument.
Annotations100/100
All four behavior hints are declared.
{
"title": "Read a Google results page",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
Output schema74/100
The output schema explains the structured result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "The results page as returned, nested by result type; organic results carry rank_group, url, title and description."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"ai_overview": {
"type": "object",
"required": [
"present",
"text",
"references"
],
"properties": {
"text": {
"type": [
"string",
"null"
],
"description": "The summary's text."
},
"present": {
"type": "boolean",
"description": "Whether the page shows an AI summary."
},
"references": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain",
"title",
"url"
],
"properties": {
"url": {
"type": [
"string",
"null"
],
"description": "The cited page."
},
"title": {
"type": [
"string",
"null"
],
"description": "The cited page's title."
},
"domain": {
"type": [
"string",
"null"
],
"description": "The cited site."
}
},
"additionalProperties": false
},
"description": "Sources the summary cites."
},
"cites_domain": {
"type": "boolean",
"description": "With cited_domain: whether a source is on it."
}
},
"description": "The AI summary on the results page, when asked for.",
"additionalProperties": false
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
},
"people_also_ask": {
"type": "array",
"items": {
"type": "object",
"required": [
"question",
"answer",
"url",
"domain"
],
"properties": {
"url": {
"type": [
"string",
"null"
],
"description": "The answer's source page."
},
"answer": {
"type": [
"string",
"null"
],
"description": "The answer shown under it."
},
"domain": {
"type": [
"string",
"null"
],
"description": "The answer's source site."
},
"question": {
"type": "string",
"description": "The question."
}
},
"additionalProperties": false
},
"description": "People also ask questions, when asked for."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_serp_results",
"title": "Read a Google results page",
"description": "Google's results page for one keyword in one market, by block: organic, featured_snippet, people_also_ask, ai_overview, local_pack, related_searches and more. Pass item_types for the blocks you need. Add \"ai_overview\" for Google's AI Overview text and the pages it cites, with cited_domain to check whether the user's site is among them: the GEO check for Google. With \"people_also_ask\", paa_depth (1–4) opens the questions' answers and sources for an FAQ brief. Pass location and language from the market the user named; never assume worldwide. Returns paged items and a result_id; paging with result_id is free. Google data combined with third-party data.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page number to return. Defaults to 1."
},
"device": {
"enum": [
"desktop",
"mobile"
],
"type": "string",
"description": "Device to emulate for the SERP. Defaults to desktop."
},
"keyword": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "The single search query to pull SERP results for. Example: \"bilan de compétences CPF\". Required for a new search; omit when paging with result_id."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Language for the SERP (e.g. \"English\", \"German\", \"French\"). Specify the intended search language; the server does not infer it from a Google Ads Account. Reuse known market context or ask the user. Omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Country for the SERP (e.g. \"United States\", \"Germany\", \"France\"). Specify the intended search-market country; the server does not infer it from a Google Ads Account. Reuse known market context or ask the user; do not omit location or assume worldwide on fresh searches. Omit when paging with result_id."
},
"paa_depth": {
"type": "integer",
"maximum": 4,
"minimum": 1,
"description": "With \"people_also_ask\" in item_types: how many levels of questions to open, each answer with its source page. Each level costs more; omit for the questions as shown."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page to return. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "Result ID returned by a previous call to this research tool. Valid for 24 hours; use for stored pages without a fresh provider request. After expiry, start a fresh lookup."
},
"item_types": {
"type": "array",
"items": {
"enum": [
"organic",
"paid",
"featured_snippet",
"local_pack",
"people_also_ask",
"knowledge_graph",
"answer_box",
"shopping",
"video",
"images",
"top_stories",
"related_searches",
"carousel",
"ai_overview"
],
"type": "string"
},
"minItems": 1,
"description": "SERP block types to return, e.g. [\"organic\"] or [\"paid\"]. Required for a new search; omit when paging with result_id. Ordering note: if the first element is anything other than \"organic\", results are ordered by that first type."
},
"cited_domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "With \"ai_overview\" in item_types: a domain to look for among the AI Overview's cited pages, e.g. \"acme.com\". The result says whether it (or a subdomain) is cited."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "The results page as returned, nested by result type; organic results carry rank_group, url, title and description."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"ai_overview": {
"type": "object",
"required": [
"present",
"text",
"references"
],
"properties": {
"text": {
"type": [
"string",
"null"
],
"description": "The summary's text."
},
"present": {
"type": "boolean",
"description": "Whether the page shows an AI summary."
},
"references": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain",
"title",
"url"
],
"properties": {
"url": {
"type": [
"string",
"null"
],
"description": "The cited page."
},
"title": {
"type": [
"string",
"null"
],
"description": "The cited page's title."
},
"domain": {
"type": [
"string",
"null"
],
"description": "The cited site."
}
},
"additionalProperties": false
},
"description": "Sources the summary cites."
},
"cites_domain": {
"type": "boolean",
"description": "With cited_domain: whether a source is on it."
}
},
"description": "The AI summary on the results page, when asked for.",
"additionalProperties": false
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
},
"people_also_ask": {
"type": "array",
"items": {
"type": "object",
"required": [
"question",
"answer",
"url",
"domain"
],
"properties": {
"url": {
"type": [
"string",
"null"
],
"description": "The answer's source page."
},
"answer": {
"type": [
"string",
"null"
],
"description": "The answer shown under it."
},
"domain": {
"type": [
"string",
"null"
],
"description": "The answer's source site."
},
"question": {
"type": "string",
"description": "The question."
}
},
"additionalProperties": false
},
"description": "People also ask questions, when asked for."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Read a Google results page",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Asks ChatGPT a buyer's question with web search on and returns its answer, the pages it cited and the searches it ran: the GEO check for ChatGPT. Pass brand to see whether the answer names it, and domain to see whether that site is among the cited sources; run it for the user and a competitor to compare. Write prompt the way a buyer would, in their language, and set country to their market. Answers vary: runs (1–3) repeats the question and the summary counts mentions and citations across runs. Citations aren't guaranteed even with web search. A slow, costly call: one question per call, few runs. Returns a row per run, a summary and a result_id.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
prompt
The question a buyer would ask ChatGPT, in their words and language, e.g. "Which CRM is best for a 10-person startup?". Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
brand
A brand name to look for in the answer text, e.g. "Acme".
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
domain
A domain to look for among the cited sources, e.g. "acme.com".
Clear enough to supply this argument.
country
The country the web search runs from, e.g. "US" or "DE". Use the User's market; answers and sources differ by country.
Clear enough to supply this argument.
model
ChatGPT model to ask (default "gpt-5-mini"). Must support web search; larger models answer slower and cost more.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
runs
How many times to ask the same prompt (default 1). Answers vary between runs; more runs show how stable a mention is, and cost more.
Clear enough to supply this argument.
page
Page of runs to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Runs per page. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
result_id from an earlier call, valid for 24 hours: re-reads the same answers at no cost. With it, pass only page and page_size.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"run",
"model",
"answer",
"citations",
"fan_out_queries"
],
"properties": {
"run": {
"type": "number",
"description": "Which run this answer is, from 1."
},
"model": {
"type": [
"string",
"null"
],
"description": "The model that answered."
},
"answer": {
"type": "string",
"description": "The answer text, cut with … when very long."
},
"citations": {
"type": "array",
"items": {
"type": "object",
"required": [
"url",
"domain",
"title"
],
"properties": {
"url": {
"type": "string",
"description": "The cited page."
},
"title": {
"type": [
"string",
"null"
],
"description": "Its title, when the answer gave one."
},
"domain": {
"type": [
"string",
"null"
],
"description": "Its domain, without www."
}
},
"additionalProperties": {}
},
"description": "Sources the answer cited, once each, in order."
},
"domain_cited": {
"type": "boolean",
"description": "With domain: whether a citation is on it."
},
"brand_mentioned": {
"type": "boolean",
"description": "With brand: whether the answer text names it."
},
"fan_out_queries": {
"type": "array",
"items": {
"type": "string"
},
"description": "Web searches the model ran to answer."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"runs",
"cited_domains",
"citations_found"
],
"properties": {
"runs": {
"type": "number",
"description": "Runs asked."
},
"cited_domains": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain",
"runs"
],
"properties": {
"runs": {
"type": "number",
"description": "Runs that cite it."
},
"domain": {
"type": "string",
"description": "A cited domain."
}
},
"additionalProperties": {}
},
"description": "The most cited domains, most runs first."
},
"citations_found": {
"type": "boolean",
"description": "Whether any run cited a source."
},
"domain_cited_in_runs": {
"type": "number",
"description": "With domain: runs that cite it."
},
"brand_mentioned_in_runs": {
"type": "number",
"description": "With brand: runs whose answer names it."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_ai_visibility",
"title": "Check visibility in ChatGPT",
"description": "Asks ChatGPT a buyer's question with web search on and returns its answer, the pages it cited and the searches it ran: the GEO check for ChatGPT. Pass brand to see whether the answer names it, and domain to see whether that site is among the cited sources; run it for the user and a competitor to compare. Write prompt the way a buyer would, in their language, and set country to their market. Answers vary: runs (1–3) repeats the question and the summary counts mentions and citations across runs. Citations aren't guaranteed even with web search. A slow, costly call: one question per call, few runs. Returns a row per run, a summary and a result_id.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of runs to return. Defaults to 1."
},
"runs": {
"type": "integer",
"maximum": 3,
"minimum": 1,
"description": "How many times to ask the same prompt (default 1). Answers vary between runs; more runs show how stable a mention is, and cost more."
},
"brand": {
"type": "string",
"maxLength": 100,
"minLength": 1,
"description": "A brand name to look for in the answer text, e.g. \"Acme\"."
},
"model": {
"type": "string",
"maxLength": 64,
"minLength": 1,
"description": "ChatGPT model to ask (default \"gpt-5-mini\"). Must support web search; larger models answer slower and cost more."
},
"domain": {
"type": "string",
"description": "A domain to look for among the cited sources, e.g. \"acme.com\"."
},
"prompt": {
"type": "string",
"maxLength": 500,
"minLength": 1,
"description": "The question a buyer would ask ChatGPT, in their words and language, e.g. \"Which CRM is best for a 10-person startup?\". Required for a new lookup."
},
"country": {
"type": "string",
"pattern": "^[A-Za-z]{2}$",
"description": "The country the web search runs from, e.g. \"US\" or \"DE\". Use the User's market; answers and sources differ by country."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Runs per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call, valid for 24 hours: re-reads the same answers at no cost. With it, pass only page and page_size."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"run",
"model",
"answer",
"citations",
"fan_out_queries"
],
"properties": {
"run": {
"type": "number",
"description": "Which run this answer is, from 1."
},
"model": {
"type": [
"string",
"null"
],
"description": "The model that answered."
},
"answer": {
"type": "string",
"description": "The answer text, cut with … when very long."
},
"citations": {
"type": "array",
"items": {
"type": "object",
"required": [
"url",
"domain",
"title"
],
"properties": {
"url": {
"type": "string",
"description": "The cited page."
},
"title": {
"type": [
"string",
"null"
],
"description": "Its title, when the answer gave one."
},
"domain": {
"type": [
"string",
"null"
],
"description": "Its domain, without www."
}
},
"additionalProperties": {}
},
"description": "Sources the answer cited, once each, in order."
},
"domain_cited": {
"type": "boolean",
"description": "With domain: whether a citation is on it."
},
"brand_mentioned": {
"type": "boolean",
"description": "With brand: whether the answer text names it."
},
"fan_out_queries": {
"type": "array",
"items": {
"type": "string"
},
"description": "Web searches the model ran to answer."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"runs",
"cited_domains",
"citations_found"
],
"properties": {
"runs": {
"type": "number",
"description": "Runs asked."
},
"cited_domains": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain",
"runs"
],
"properties": {
"runs": {
"type": "number",
"description": "Runs that cite it."
},
"domain": {
"type": "string",
"description": "A cited domain."
}
},
"additionalProperties": {}
},
"description": "The most cited domains, most runs first."
},
"citations_found": {
"type": "boolean",
"description": "Whether any run cited a source."
},
"domain_cited_in_runs": {
"type": "number",
"description": "With domain: runs that cite it."
},
"brand_mentioned_in_runs": {
"type": "number",
"description": "With brand: runs whose answer names it."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Check visibility in ChatGPT",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
The sites that compete with a domain in Google's organic results, one row each: keywords shared and the average position on them, then the competitor's organic and paid keyword counts, estimated monthly visits and what that traffic would cost to buy in USD. Skip large platforms such as youtube.com or reddit.com, which share keywords with almost any site. Pass domain without https:// or a path ("acme.com"), and location and language for the market. Third-party estimates. Results keep 24 hours: result_id with page and page_size re-reads them for free. Then use seo_competitor_keyword_gap on the closest ones.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Remove repeated schema validation from descriptions; focus on meaning and usage context.
domain
Domain whose organic-search competitors to find, without a scheme, port, path, query, or fragment. Example: "acme.com". Required for a new lookup; omit when paging with result_id.
Clear enough to supply this argument.
location
Target search-market country for a new competitor lookup (e.g. "United States", "Germany", "France"), not the user's personal location. Reuse known Account context or ask the user if unknown; the server does not infer it from a Google Ads Account. Omit when paging with result_id.
Clear enough to supply this argument.
language
Target search language for a new competitor lookup (e.g. "English", "German", "French"). Reuse known Account context or ask the user if unknown; the server does not infer it from a Google Ads Account. Omit when paging with result_id.
Clear enough to supply this argument.
limit
Competitor domains to fetch for a new lookup. Uses the provider default if omitted. Omit when paging with result_id.
Clear enough to supply this argument.
page
Page number to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page to return. Defaults to 10.
Clear enough to supply this argument.
result_id
Result ID from a previous seo_competitors lookup, valid for 24 hours. With result_id, only page and page_size may also be supplied; omit domain, location, language, and limit. Omit result_id for a new lookup.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"shared_keywords",
"avg_position",
"shared_keywords_traffic",
"organic_keywords",
"organic_traffic",
"organic_traffic_value_usd",
"paid_keywords",
"paid_traffic",
"paid_traffic_cost_usd"
],
"properties": {
"domain": {
"type": "string",
"description": "The competing site."
},
"avg_position": {
"type": [
"number",
"null"
],
"description": "Its average position on those shared keywords."
},
"paid_traffic": {
"type": [
"number",
"null"
],
"description": "Its estimated monthly paid visits."
},
"paid_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords it bids on."
},
"organic_traffic": {
"type": [
"number",
"null"
],
"description": "Its estimated monthly organic visits."
},
"shared_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords both sites rank for."
},
"organic_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords it ranks for organically."
},
"paid_traffic_cost_usd": {
"type": [
"number",
"null"
],
"description": "Its estimated monthly ad spend for that traffic, in USD."
},
"shared_keywords_traffic": {
"type": [
"number",
"null"
],
"description": "Its estimated monthly visits from the shared keywords."
},
"organic_traffic_value_usd": {
"type": [
"number",
"null"
],
"description": "What that organic traffic would cost as ads, in USD."
}
},
"additionalProperties": {}
},
"description": "This page's competitors, one per row."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_competitors",
"title": "Find organic competitors",
"description": "The sites that compete with a domain in Google's organic results, one row each: keywords shared and the average position on them, then the competitor's organic and paid keyword counts, estimated monthly visits and what that traffic would cost to buy in USD. Skip large platforms such as youtube.com or reddit.com, which share keywords with almost any site. Pass domain without https:// or a path (\"acme.com\"), and location and language for the market. Third-party estimates. Results keep 24 hours: result_id with page and page_size re-reads them for free. Then use seo_competitor_keyword_gap on the closest ones.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page number to return. Defaults to 1."
},
"limit": {
"type": "integer",
"maximum": 1000,
"minimum": 1,
"description": "Competitor domains to fetch for a new lookup. Uses the provider default if omitted. Omit when paging with result_id."
},
"domain": {
"type": "string",
"maxLength": 253,
"minLength": 1,
"description": "Domain whose organic-search competitors to find, without a scheme, port, path, query, or fragment. Example: \"acme.com\". Required for a new lookup; omit when paging with result_id."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Target search language for a new competitor lookup (e.g. \"English\", \"German\", \"French\"). Reuse known Account context or ask the user if unknown; the server does not infer it from a Google Ads Account. Omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Target search-market country for a new competitor lookup (e.g. \"United States\", \"Germany\", \"France\"), not the user's personal location. Reuse known Account context or ask the user if unknown; the server does not infer it from a Google Ads Account. Omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page to return. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "Result ID from a previous seo_competitors lookup, valid for 24 hours. With result_id, only page and page_size may also be supplied; omit domain, location, language, and limit. Omit result_id for a new lookup."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"shared_keywords",
"avg_position",
"shared_keywords_traffic",
"organic_keywords",
"organic_traffic",
"organic_traffic_value_usd",
"paid_keywords",
"paid_traffic",
"paid_traffic_cost_usd"
],
"properties": {
"domain": {
"type": "string",
"description": "The competing site."
},
"avg_position": {
"type": [
"number",
"null"
],
"description": "Its average position on those shared keywords."
},
"paid_traffic": {
"type": [
"number",
"null"
],
"description": "Its estimated monthly paid visits."
},
"paid_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords it bids on."
},
"organic_traffic": {
"type": [
"number",
"null"
],
"description": "Its estimated monthly organic visits."
},
"shared_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords both sites rank for."
},
"organic_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords it ranks for organically."
},
"paid_traffic_cost_usd": {
"type": [
"number",
"null"
],
"description": "Its estimated monthly ad spend for that traffic, in USD."
},
"shared_keywords_traffic": {
"type": [
"number",
"null"
],
"description": "Its estimated monthly visits from the shared keywords."
},
"organic_traffic_value_usd": {
"type": [
"number",
"null"
],
"description": "What that organic traffic would cost as ads, in USD."
}
},
"additionalProperties": {}
},
"description": "This page's competitors, one per row."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Find organic competitors",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
A site's organic and paid Google footprint in one market: keywords ranked, how many in the top 3 and top 10, estimated monthly traffic and its value, and keywords gained and lost. Compare the user's site with competitors in one call by passing domains (up to 50) instead of domain. Domains go without https:// or a path ("acme.com"), with location and language for the market; ask if unknown. Third-party estimates refreshed weekly, not the user's Search Console data. Returns rows and a result_id. For the keywords behind the numbers use seo_competitor_ranked_keywords.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
domain
One domain to size up in detail, e.g. "acme.com" (yours or a competitor's). Pass this or domains for a new lookup.
Clear enough to supply this argument.
domains
Several domains to compare in one call, e.g. ["acme.com", "rival.com"]. Use it instead of one call per domain when sizing up a list of competitors. Returns traffic and keyword counts per domain; pass a single domain for the top-3/top-10 split, traffic value and keywords gained and lost.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
location
Search-market country, e.g. "United States" or "Germany". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id.
Clear enough to supply this argument.
language
Search language, e.g. "English" or "German". Required for a new lookup; omit when paging with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Page of rows to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page. Defaults to 10.
Clear enough to supply this argument.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
Clear enough to supply this argument.
Annotations100/100
All four behavior hints are declared.
{
"title": "Size up a site's search footprint",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
Output schema78/100
The output schema explains the structured result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain"
],
"properties": {
"paid": {
"type": "object",
"required": [
"keywords",
"estimated_monthly_traffic"
],
"properties": {
"keywords": {
"type": [
"number",
"null"
],
"description": "Keywords it ranks for."
},
"new_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords gained lately. Single-domain lookups only."
},
"lost_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords lost lately. Single-domain lookups only."
},
"top3_keywords": {
"type": "number",
"description": "Keywords in positions 1 to 3. Single-domain lookups only."
},
"top10_keywords": {
"type": "number",
"description": "Keywords in positions 1 to 10. Single-domain lookups only."
},
"estimated_traffic_value": {
"type": [
"number",
"null"
],
"description": "What that traffic would cost as ads, in USD. Single-domain lookups only."
},
"estimated_monthly_traffic": {
"type": [
"number",
"null"
],
"description": "Estimated monthly visits."
}
},
"description": "Its paid search footprint.",
"additionalProperties": {}
},
"domain": {
"type": [
"string",
"null"
],
"description": "The domain."
},
"organic": {
"type": "object",
"required": [
"keywords",
"estimated_monthly_traffic"
],
"properties": {
"keywords": {
"type": [
"number",
"null"
],
"description": "Keywords it ranks for."
},
"new_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords gained lately. Single-domain lookups only."
},
"lost_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords lost lately. Single-domain lookups only."
},
"top3_keywords": {
"type": "number",
"description": "Keywords in positions 1 to 3. Single-domain lookups only."
},
"top10_keywords": {
"type": "number",
"description": "Keywords in positions 1 to 10. Single-domain lookups only."
},
"estimated_traffic_value": {
"type": [
"number",
"null"
],
"description": "What that traffic would cost as ads, in USD. Single-domain lookups only."
},
"estimated_monthly_traffic": {
"type": [
"number",
"null"
],
"description": "Estimated monthly visits."
}
},
"description": "Its organic search footprint.",
"additionalProperties": {}
},
"has_data": {
"type": "boolean",
"description": "List lookups: false when the vendor has no data for it."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"domains",
"with_data",
"note"
],
"properties": {
"note": {
"type": "string",
"description": "What a list lookup leaves out."
},
"domains": {
"type": "number",
"description": "Domains asked for."
},
"with_data": {
"type": "number",
"description": "Domains the vendor has data for."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_competitor_domain_overview",
"title": "Size up a site's search footprint",
"description": "A site's organic and paid Google footprint in one market: keywords ranked, how many in the top 3 and top 10, estimated monthly traffic and its value, and keywords gained and lost. Compare the user's site with competitors in one call by passing domains (up to 50) instead of domain. Domains go without https:// or a path (\"acme.com\"), with location and language for the market; ask if unknown. Third-party estimates refreshed weekly, not the user's Search Console data. Returns rows and a result_id. For the keywords behind the numbers use seo_competitor_ranked_keywords.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"domain": {
"type": "string",
"description": "One domain to size up in detail, e.g. \"acme.com\" (yours or a competitor's). Pass this or domains for a new lookup."
},
"domains": {
"type": "array",
"items": {
"type": "string"
},
"maxItems": 50,
"minItems": 1,
"description": "Several domains to compare in one call, e.g. [\"acme.com\", \"rival.com\"]. Use it instead of one call per domain when sizing up a list of competitors. Returns traffic and keyword counts per domain; pass a single domain for the top-3/top-10 split, traffic value and keywords gained and lost."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Search language, e.g. \"English\" or \"German\". Required for a new lookup; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Search-market country, e.g. \"United States\" or \"Germany\". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain"
],
"properties": {
"paid": {
"type": "object",
"required": [
"keywords",
"estimated_monthly_traffic"
],
"properties": {
"keywords": {
"type": [
"number",
"null"
],
"description": "Keywords it ranks for."
},
"new_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords gained lately. Single-domain lookups only."
},
"lost_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords lost lately. Single-domain lookups only."
},
"top3_keywords": {
"type": "number",
"description": "Keywords in positions 1 to 3. Single-domain lookups only."
},
"top10_keywords": {
"type": "number",
"description": "Keywords in positions 1 to 10. Single-domain lookups only."
},
"estimated_traffic_value": {
"type": [
"number",
"null"
],
"description": "What that traffic would cost as ads, in USD. Single-domain lookups only."
},
"estimated_monthly_traffic": {
"type": [
"number",
"null"
],
"description": "Estimated monthly visits."
}
},
"description": "Its paid search footprint.",
"additionalProperties": {}
},
"domain": {
"type": [
"string",
"null"
],
"description": "The domain."
},
"organic": {
"type": "object",
"required": [
"keywords",
"estimated_monthly_traffic"
],
"properties": {
"keywords": {
"type": [
"number",
"null"
],
"description": "Keywords it ranks for."
},
"new_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords gained lately. Single-domain lookups only."
},
"lost_keywords": {
"type": [
"number",
"null"
],
"description": "Keywords lost lately. Single-domain lookups only."
},
"top3_keywords": {
"type": "number",
"description": "Keywords in positions 1 to 3. Single-domain lookups only."
},
"top10_keywords": {
"type": "number",
"description": "Keywords in positions 1 to 10. Single-domain lookups only."
},
"estimated_traffic_value": {
"type": [
"number",
"null"
],
"description": "What that traffic would cost as ads, in USD. Single-domain lookups only."
},
"estimated_monthly_traffic": {
"type": [
"number",
"null"
],
"description": "Estimated monthly visits."
}
},
"description": "Its organic search footprint.",
"additionalProperties": {}
},
"has_data": {
"type": "boolean",
"description": "List lookups: false when the vendor has no data for it."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"domains",
"with_data",
"note"
],
"properties": {
"note": {
"type": "string",
"description": "What a list lookup leaves out."
},
"domains": {
"type": "number",
"description": "Domains asked for."
},
"with_data": {
"type": "number",
"description": "Domains the vendor has data for."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Size up a site's search footprint",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
The Google keywords a domain, or one page, ranks for in one market: position, ranking URL, estimated traffic, volume, difficulty and intent, most traffic first. Pass a page URL with https:// as target for that page alone, to find a competing page's content gaps against the user's. Filter with min_volume, max_position (10 = page one) and branded ("exclude" for non-branded demand). Pass location and language; ask if unknown. Third-party estimates; for the user's own measured rankings use seo_gsc_query_search_analytics. Returns rows, a summary with the total count and a result_id; paging is free. More rows cost more, so keep limit modest.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
target
A domain ("acme.com") or one page URL with its scheme ("https://acme.com/pricing") for the keywords that page ranks for. Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
location
Search-market country, e.g. "United States" or "Germany". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id.
Clear enough to supply this argument.
language
Search language, e.g. "English" or "German". Required for a new lookup; omit when paging with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
min_volume
Only keywords with at least this monthly search volume.
Clear enough to supply this argument.
max_position
Only keywords where the target ranks at this position or better, e.g. 10 for page one.
Clear enough to supply this argument.
branded
Branded keywords (containing the domain's brand word): "exclude" for the non-branded footprint, "only" for brand demand. Default "all". A heuristic on the domain name.
Clear enough to supply this argument.
page
Page of rows to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page. Defaults to 10.
Clear enough to supply this argument.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features",
"position",
"url",
"result_type",
"estimated_traffic"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"url": {
"type": [
"string",
"null"
],
"description": "The ranking page."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"position": {
"type": [
"number",
"null"
],
"description": "The ranking page's position in organic results."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"result_type": {
"type": [
"string",
"null"
],
"description": "The result type, e.g. organic."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"estimated_traffic": {
"type": [
"number",
"null"
],
"description": "Estimated monthly visits from this keyword."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"total_ranked_keywords"
],
"properties": {
"total_ranked_keywords": {
"type": "number",
"description": "Keywords it ranks for in total, beyond the fetched rows."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_competitor_ranked_keywords",
"title": "List a site's ranking keywords",
"description": "The Google keywords a domain, or one page, ranks for in one market: position, ranking URL, estimated traffic, volume, difficulty and intent, most traffic first. Pass a page URL with https:// as target for that page alone, to find a competing page's content gaps against the user's. Filter with min_volume, max_position (10 = page one) and branded (\"exclude\" for non-branded demand). Pass location and language; ask if unknown. Third-party estimates; for the user's own measured rankings use seo_gsc_query_search_analytics. Returns rows, a summary with the total count and a result_id; paging is free. More rows cost more, so keep limit modest.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id."
},
"target": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "A domain (\"acme.com\") or one page URL with its scheme (\"https://acme.com/pricing\") for the keywords that page ranks for. Required for a new lookup."
},
"branded": {
"enum": [
"all",
"exclude",
"only"
],
"type": "string",
"description": "Branded keywords (containing the domain's brand word): \"exclude\" for the non-branded footprint, \"only\" for brand demand. Default \"all\". A heuristic on the domain name."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Search language, e.g. \"English\" or \"German\". Required for a new lookup; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Search-market country, e.g. \"United States\" or \"Germany\". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"min_volume": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Only keywords with at least this monthly search volume."
},
"max_position": {
"type": "integer",
"maximum": 100,
"minimum": 1,
"description": "Only keywords where the target ranks at this position or better, e.g. 10 for page one."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features",
"position",
"url",
"result_type",
"estimated_traffic"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"url": {
"type": [
"string",
"null"
],
"description": "The ranking page."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"position": {
"type": [
"number",
"null"
],
"description": "The ranking page's position in organic results."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"result_type": {
"type": [
"string",
"null"
],
"description": "The result type, e.g. organic."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"estimated_traffic": {
"type": [
"number",
"null"
],
"description": "Estimated monthly visits from this keyword."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"total_ranked_keywords"
],
"properties": {
"total_ranked_keywords": {
"type": "number",
"description": "Keywords it ranks for in total, beyond the fetched rows."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "List a site's ranking keywords",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Keywords relevant to a domain or page, ranking or not, highest volume first, with difficulty, intent, CPC and trend. On the user's own site it suggests topics to cover; on a competitor's, the topics their content targets. Filter with min_volume and max_difficulty. Pass target as a bare domain or a page URL with https://, plus location and language; ask if unknown. For what a site already ranks for use seo_competitor_ranked_keywords. Third-party estimates. Returns rows and a result_id; paging with result_id is free. More rows cost more.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
target
A domain ("acme.com") or a page URL with its scheme. Works for the User's own site too: keyword ideas that fit it. Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
location
Search-market country, e.g. "United States" or "Germany". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id.
Clear enough to supply this argument.
language
Search language, e.g. "English" or "German". Required for a new lookup; omit when paging with result_id.
Clear enough to supply this argument.
limit
Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
min_volume
Only keywords with at least this monthly search volume.
Clear enough to supply this argument.
max_difficulty
Only keywords at or below this keyword difficulty (0–100: how hard it is to reach the top 10 organically).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Page of rows to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
Clear enough to supply this argument.
Annotations100/100
All four behavior hints are declared.
{
"title": "Find keywords a site is relevant for",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
Output schema87/100
The output schema explains the structured result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_competitor_keywords_for_site",
"title": "Find keywords a site is relevant for",
"description": "Keywords relevant to a domain or page, ranking or not, highest volume first, with difficulty, intent, CPC and trend. On the user's own site it suggests topics to cover; on a competitor's, the topics their content targets. Filter with min_volume and max_difficulty. Pass target as a bare domain or a page URL with https://, plus location and language; ask if unknown. For what a site already ranks for use seo_competitor_ranked_keywords. Third-party estimates. Returns rows and a result_id; paging with result_id is free. More rows cost more.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id."
},
"target": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "A domain (\"acme.com\") or a page URL with its scheme. Works for the User's own site too: keyword ideas that fit it. Required for a new lookup."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Search language, e.g. \"English\" or \"German\". Required for a new lookup; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Search-market country, e.g. \"United States\" or \"Germany\". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"min_volume": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Only keywords with at least this monthly search volume."
},
"max_difficulty": {
"type": "integer",
"maximum": 100,
"minimum": 0,
"description": "Only keywords at or below this keyword difficulty (0–100: how hard it is to reach the top 10 organically)."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Find keywords a site is relevant for",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Compares the Google organic keywords of the user's domain and one competitor in one market. mode "gap" (default) lists keywords the competitor ranks for and the user doesn't, highest volume first: the content to create. mode "shared" lists keywords both rank for, with both positions and URLs: where to win ground. Rows carry volume, difficulty, intent and CPC. Pass domain and competitor without https:// or a path, plus location and language; ask if unknown. Filter with min_volume. Third-party estimates. Returns rows and a result_id; paging with result_id is free. More rows cost more.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
domain
The User's domain, e.g. "acme.com". Needed unless result_id is passed.
Clear enough to supply this argument.
competitor
The competitor's domain, e.g. "rival.com". Needed unless result_id is passed.
Clear enough to supply this argument.
mode
"gap" (default): keywords the competitor ranks for and the User's domain does not. "shared": keywords both rank for, with both positions.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
location
Search-market country, e.g. "United States" or "Germany". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id.
Clear enough to supply this argument.
language
Search language, e.g. "English" or "German". Required for a new lookup; omit when paging with result_id.
Clear enough to supply this argument.
limit
Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
min_volume
Only keywords with at least this monthly search volume.
Clear enough to supply this argument.
page
Page of rows to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page. Defaults to 10.
Clear enough to supply this argument.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features",
"competitor_position",
"competitor_url",
"your_position",
"your_url"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"your_url": {
"type": [
"string",
"null"
],
"description": "The User's ranking page; null in gap mode."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"your_position": {
"type": [
"number",
"null"
],
"description": "The User's position; null in gap mode, where they don't rank."
},
"competitor_url": {
"type": [
"string",
"null"
],
"description": "The competitor's ranking page."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"competitor_position": {
"type": [
"number",
"null"
],
"description": "The competitor's position."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_competitor_keyword_gap",
"title": "Find the keyword gap",
"description": "Compares the Google organic keywords of the user's domain and one competitor in one market. mode \"gap\" (default) lists keywords the competitor ranks for and the user doesn't, highest volume first: the content to create. mode \"shared\" lists keywords both rank for, with both positions and URLs: where to win ground. Rows carry volume, difficulty, intent and CPC. Pass domain and competitor without https:// or a path, plus location and language; ask if unknown. Filter with min_volume. Third-party estimates. Returns rows and a result_id; paging with result_id is free. More rows cost more.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"mode": {
"enum": [
"gap",
"shared"
],
"type": "string",
"description": "\"gap\" (default): keywords the competitor ranks for and the User's domain does not. \"shared\": keywords both rank for, with both positions."
},
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Rows to fetch for a new lookup, best first (default 50). More rows cost more; page through them with result_id."
},
"domain": {
"type": "string",
"description": "The User's domain, e.g. \"acme.com\". Needed unless result_id is passed."
},
"language": {
"type": "string",
"minLength": 1,
"description": "Search language, e.g. \"English\" or \"German\". Required for a new lookup; omit when paging with result_id."
},
"location": {
"type": "string",
"minLength": 1,
"description": "Search-market country, e.g. \"United States\" or \"Germany\". Required for a new lookup: reuse known market context or ask the User; never assume worldwide. Omit when paging with result_id."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"competitor": {
"type": "string",
"description": "The competitor's domain, e.g. \"rival.com\". Needed unless result_id is passed."
},
"min_volume": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Only keywords with at least this monthly search volume."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"keyword",
"search_volume",
"keyword_difficulty",
"intent",
"secondary_intents",
"cpc",
"competition",
"yearly_trend_percent",
"serp_features",
"competitor_position",
"competitor_url",
"your_position",
"your_url"
],
"properties": {
"cpc": {
"type": [
"number",
"null"
],
"description": "Average cost per click on Google Ads, in USD."
},
"intent": {
"type": [
"string",
"null"
],
"description": "Main search intent: informational, navigational, commercial or transactional."
},
"keyword": {
"type": [
"string",
"null"
],
"description": "The keyword."
},
"your_url": {
"type": [
"string",
"null"
],
"description": "The User's ranking page; null in gap mode."
},
"competition": {
"type": [
"string",
"null"
],
"description": "Advertiser competition: LOW, MEDIUM or HIGH."
},
"search_volume": {
"type": [
"number",
"null"
],
"description": "Average monthly Google searches."
},
"serp_features": {
"type": "array",
"items": {
"type": "string"
},
"description": "Result types on its first page, e.g. featured_snippet."
},
"your_position": {
"type": [
"number",
"null"
],
"description": "The User's position; null in gap mode, where they don't rank."
},
"competitor_url": {
"type": [
"string",
"null"
],
"description": "The competitor's ranking page."
},
"secondary_intents": {
"type": "array",
"items": {
"type": "string"
},
"description": "Other intents it carries."
},
"keyword_difficulty": {
"type": [
"number",
"null"
],
"description": "How hard ranking in the top 10 is, 0 to 100."
},
"competitor_position": {
"type": [
"number",
"null"
],
"description": "The competitor's position."
},
"yearly_trend_percent": {
"type": [
"number",
"null"
],
"description": "Change in search volume over the last year, in percent."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"description": "Totals for the whole result, sent with a fresh lookup.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Find the keyword gap",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
The links pointing at a domain or one page, in numbers: link authority rank (0–100), backlinks, referring domains, the followed share, spam score, broken backlinks, when links were first seen, and the spread by top-level domain, link type, platform and country. Use it as the authority side of a competitive brief, or to judge whether a page can compete for a keyword; call it once per site to compare the user's with a competitor's. For who links use seo_backlinks_referring_domains; for the link wording seo_backlinks_anchors. Returns one row and a result_id.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
target
A domain ("acme.com") or one page URL with its scheme ("https://acme.com/pricing"). Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
include_subdomains
Count links to the domain's subdomains too (default true). Ignored for a page URL.
Clear enough to supply this argument.
page
Page of rows to return. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page_size
Rows per page. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"target",
"rank",
"backlinks",
"referring_domains",
"referring_main_domains",
"referring_ips",
"dofollow_domain_share",
"spam_score",
"broken_backlinks",
"first_seen",
"top_tlds",
"link_types",
"site_platforms",
"top_countries"
],
"properties": {
"rank": {
"type": [
"number",
"null"
],
"description": "Link authority, 0 to 100 (vendor scale)."
},
"target": {
"type": [
"string",
"null"
],
"description": "The domain or page looked up."
},
"top_tlds": {
"type": "object",
"description": "Top 10 entries, each a share of backlinks from 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"backlinks": {
"type": [
"number",
"null"
],
"description": "Backlinks pointing at the target."
},
"first_seen": {
"type": [
"string",
"null"
],
"description": "When the vendor first found it."
},
"link_types": {
"type": "object",
"description": "Top 10 entries, each a share of backlinks from 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"spam_score": {
"type": [
"number",
"null"
],
"description": "Vendor spam score of the backlinks, 0 to 100."
},
"referring_ips": {
"type": [
"number",
"null"
],
"description": "IP addresses the links come from."
},
"top_countries": {
"type": "object",
"description": "Top 10 entries, each a share of backlinks from 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"site_platforms": {
"type": "object",
"description": "Top 10 entries, each a share of backlinks from 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"broken_backlinks": {
"type": [
"number",
"null"
],
"description": "Backlinks to pages that no longer load."
},
"referring_domains": {
"type": [
"number",
"null"
],
"description": "Domains linking to the target."
},
"dofollow_domain_share": {
"type": [
"number",
"null"
],
"description": "Share of referring domains with followed links, 0 to 1."
},
"referring_main_domains": {
"type": [
"number",
"null"
],
"description": "Registrable domains linking, subdomains merged."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"scale"
],
"properties": {
"scale": {
"type": "string",
"description": "How to read rank and the shares."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_backlinks_summary",
"title": "Summarize a backlink profile",
"description": "The links pointing at a domain or one page, in numbers: link authority rank (0–100), backlinks, referring domains, the followed share, spam score, broken backlinks, when links were first seen, and the spread by top-level domain, link type, platform and country. Use it as the authority side of a competitive brief, or to judge whether a page can compete for a keyword; call it once per site to compare the user's with a competitor's. For who links use seo_backlinks_referring_domains; for the link wording seo_backlinks_anchors. Returns one row and a result_id.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"target": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "A domain (\"acme.com\") or one page URL with its scheme (\"https://acme.com/pricing\"). Required for a new lookup."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"include_subdomains": {
"type": "boolean",
"description": "Count links to the domain's subdomains too (default true). Ignored for a page URL."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"target",
"rank",
"backlinks",
"referring_domains",
"referring_main_domains",
"referring_ips",
"dofollow_domain_share",
"spam_score",
"broken_backlinks",
"first_seen",
"top_tlds",
"link_types",
"site_platforms",
"top_countries"
],
"properties": {
"rank": {
"type": [
"number",
"null"
],
"description": "Link authority, 0 to 100 (vendor scale)."
},
"target": {
"type": [
"string",
"null"
],
"description": "The domain or page looked up."
},
"top_tlds": {
"type": "object",
"description": "Top 10 entries, each a share of backlinks from 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"backlinks": {
"type": [
"number",
"null"
],
"description": "Backlinks pointing at the target."
},
"first_seen": {
"type": [
"string",
"null"
],
"description": "When the vendor first found it."
},
"link_types": {
"type": "object",
"description": "Top 10 entries, each a share of backlinks from 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"spam_score": {
"type": [
"number",
"null"
],
"description": "Vendor spam score of the backlinks, 0 to 100."
},
"referring_ips": {
"type": [
"number",
"null"
],
"description": "IP addresses the links come from."
},
"top_countries": {
"type": "object",
"description": "Top 10 entries, each a share of backlinks from 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"site_platforms": {
"type": "object",
"description": "Top 10 entries, each a share of backlinks from 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"broken_backlinks": {
"type": [
"number",
"null"
],
"description": "Backlinks to pages that no longer load."
},
"referring_domains": {
"type": [
"number",
"null"
],
"description": "Domains linking to the target."
},
"dofollow_domain_share": {
"type": [
"number",
"null"
],
"description": "Share of referring domains with followed links, 0 to 1."
},
"referring_main_domains": {
"type": [
"number",
"null"
],
"description": "Registrable domains linking, subdomains merged."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"scale"
],
"properties": {
"scale": {
"type": "string",
"description": "How to read rank and the shares."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Summarize a backlink profile",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
The domains linking to a domain or one page, strongest first (or by most backlinks with sort_by): each with its link authority rank, backlinks to the target, followed share, spam score and first link date; the summary gives the total. Use it for link-building targets that link to a competitor but not to the user, or with status "lost" to see who stopped linking. 50 domains by default, up to 500; more cost more. Returns rows and a result_id; paging with result_id is free.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
target
A domain ("acme.com") or one page URL with its scheme ("https://acme.com/pricing"). Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
include_subdomains
Count links to the domain's subdomains too (default true). Ignored for a page URL.
Clear enough to supply this argument.
status
Links that exist now ("live", default) or that were lost: who stopped linking.
Clear enough to supply this argument.
limit
Rows to fetch for a new lookup (default 50). More rows cost more; page through them with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sort_by
Strongest domains first ("rank", default) or those linking most ("backlinks").
Clear enough to supply this argument.
page
Page of rows to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page. Defaults to 10.
Clear enough to supply this argument.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain",
"rank",
"backlinks",
"dofollow_share",
"spam_score",
"first_seen"
],
"properties": {
"rank": {
"type": [
"number",
"null"
],
"description": "Link authority, 0 to 100 (vendor scale)."
},
"domain": {
"type": [
"string",
"null"
],
"description": "The linking domain."
},
"backlinks": {
"type": [
"number",
"null"
],
"description": "Backlinks from this domain to the target."
},
"lost_date": {
"type": "string",
"description": "When the links were lost; lost links only."
},
"first_seen": {
"type": [
"string",
"null"
],
"description": "When the vendor first found it."
},
"spam_score": {
"type": [
"number",
"null"
],
"description": "Vendor spam score, 0 to 100."
},
"dofollow_share": {
"type": [
"number",
"null"
],
"description": "Share of its linking pages with followed links, 0 to 1."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"total_referring_domains"
],
"properties": {
"total_referring_domains": {
"type": "number",
"description": "Referring domains in total, beyond the fetched rows."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_backlinks_referring_domains",
"title": "List referring domains",
"description": "The domains linking to a domain or one page, strongest first (or by most backlinks with sort_by): each with its link authority rank, backlinks to the target, followed share, spam score and first link date; the summary gives the total. Use it for link-building targets that link to a competitor but not to the user, or with status \"lost\" to see who stopped linking. 50 domains by default, up to 500; more cost more. Returns rows and a result_id; paging with result_id is free.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Rows to fetch for a new lookup (default 50). More rows cost more; page through them with result_id."
},
"status": {
"enum": [
"live",
"lost"
],
"type": "string",
"description": "Links that exist now (\"live\", default) or that were lost: who stopped linking."
},
"target": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "A domain (\"acme.com\") or one page URL with its scheme (\"https://acme.com/pricing\"). Required for a new lookup."
},
"sort_by": {
"enum": [
"rank",
"backlinks"
],
"type": "string",
"description": "Strongest domains first (\"rank\", default) or those linking most (\"backlinks\")."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"include_subdomains": {
"type": "boolean",
"description": "Count links to the domain's subdomains too (default true). Ignored for a page URL."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"domain",
"rank",
"backlinks",
"dofollow_share",
"spam_score",
"first_seen"
],
"properties": {
"rank": {
"type": [
"number",
"null"
],
"description": "Link authority, 0 to 100 (vendor scale)."
},
"domain": {
"type": [
"string",
"null"
],
"description": "The linking domain."
},
"backlinks": {
"type": [
"number",
"null"
],
"description": "Backlinks from this domain to the target."
},
"lost_date": {
"type": "string",
"description": "When the links were lost; lost links only."
},
"first_seen": {
"type": [
"string",
"null"
],
"description": "When the vendor first found it."
},
"spam_score": {
"type": [
"number",
"null"
],
"description": "Vendor spam score, 0 to 100."
},
"dofollow_share": {
"type": [
"number",
"null"
],
"description": "Share of its linking pages with followed links, 0 to 1."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"total_referring_domains"
],
"properties": {
"total_referring_domains": {
"type": "number",
"description": "Referring domains in total, beyond the fetched rows."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "List referring domains",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
The anchor texts other sites use when they link to a domain or one page, most backlinks first: each with its backlinks, referring domains, followed share and kind (branded, url, empty for image links, or other words). The summary weighs the mix of kinds, a quick read on how natural the profile looks. Use it to compare a competitor's link wording with the user's, or for anchor themes in a link-building plan. 50 anchors by default, up to 500; more cost more. Returns rows and a result_id; paging with result_id is free.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
target
A domain ("acme.com") or one page URL with its scheme ("https://acme.com/pricing"). Required for a new lookup.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
include_subdomains
Count links to the domain's subdomains too (default true). Ignored for a page URL.
Clear enough to supply this argument.
status
Links that exist now ("live", default) or that were lost: who stopped linking.
Clear enough to supply this argument.
limit
Rows to fetch for a new lookup (default 50). More rows cost more; page through them with result_id.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page
Page of rows to return. Defaults to 1.
Clear enough to supply this argument.
page_size
Rows per page. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"anchor",
"kind",
"backlinks",
"referring_domains",
"dofollow_share",
"rank",
"first_seen"
],
"properties": {
"kind": {
"enum": [
"branded",
"url",
"empty",
"other"
],
"type": "string",
"description": "branded names the target's brand, url is a bare address, empty has no text."
},
"rank": {
"type": [
"number",
"null"
],
"description": "Link authority, 0 to 100 (vendor scale)."
},
"anchor": {
"type": [
"string",
"null"
],
"description": "The link text."
},
"backlinks": {
"type": [
"number",
"null"
],
"description": "Backlinks using this anchor."
},
"first_seen": {
"type": [
"string",
"null"
],
"description": "When the vendor first found it."
},
"dofollow_share": {
"type": [
"number",
"null"
],
"description": "Share of those domains with followed links, 0 to 1."
},
"referring_domains": {
"type": [
"number",
"null"
],
"description": "Domains using this anchor."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"total_anchors",
"anchor_mix",
"note"
],
"properties": {
"note": {
"type": "string",
"description": "What anchorMix covers."
},
"anchor_mix": {
"type": "object",
"description": "Each anchor kind's share of the fetched backlinks, 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"total_anchors": {
"type": [
"number",
"null"
],
"description": "Distinct anchors in total, beyond the fetched rows."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_backlinks_anchors",
"title": "List backlink anchor texts",
"description": "The anchor texts other sites use when they link to a domain or one page, most backlinks first: each with its backlinks, referring domains, followed share and kind (branded, url, empty for image links, or other words). The summary weighs the mix of kinds, a quick read on how natural the profile looks. Use it to compare a competitor's link wording with the user's, or for anchor themes in a link-building plan. 50 anchors by default, up to 500; more cost more. Returns rows and a result_id; paging with result_id is free.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"limit": {
"type": "integer",
"maximum": 500,
"minimum": 1,
"description": "Rows to fetch for a new lookup (default 50). More rows cost more; page through them with result_id."
},
"status": {
"enum": [
"live",
"lost"
],
"type": "string",
"description": "Links that exist now (\"live\", default) or that were lost: who stopped linking."
},
"target": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "A domain (\"acme.com\") or one page URL with its scheme (\"https://acme.com/pricing\"). Required for a new lookup."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"include_subdomains": {
"type": "boolean",
"description": "Count links to the domain's subdomains too (default true). Ignored for a page URL."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"anchor",
"kind",
"backlinks",
"referring_domains",
"dofollow_share",
"rank",
"first_seen"
],
"properties": {
"kind": {
"enum": [
"branded",
"url",
"empty",
"other"
],
"type": "string",
"description": "branded names the target's brand, url is a bare address, empty has no text."
},
"rank": {
"type": [
"number",
"null"
],
"description": "Link authority, 0 to 100 (vendor scale)."
},
"anchor": {
"type": [
"string",
"null"
],
"description": "The link text."
},
"backlinks": {
"type": [
"number",
"null"
],
"description": "Backlinks using this anchor."
},
"first_seen": {
"type": [
"string",
"null"
],
"description": "When the vendor first found it."
},
"dofollow_share": {
"type": [
"number",
"null"
],
"description": "Share of those domains with followed links, 0 to 1."
},
"referring_domains": {
"type": [
"number",
"null"
],
"description": "Domains using this anchor."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"total_anchors",
"anchor_mix",
"note"
],
"properties": {
"note": {
"type": "string",
"description": "What anchorMix covers."
},
"anchor_mix": {
"type": "object",
"description": "Each anchor kind's share of the fetched backlinks, 0 to 1.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"total_anchors": {
"type": [
"number",
"null"
],
"description": "Distinct anchors in total, beyond the fetched rows."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "List backlink anchor texts",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Opens one URL in a real browser and returns what Google's renderer would see: the JavaScript-rendered DOM, HTTP status, redirect chain and server timings. Use it for on-page SEO checks a plain fetch misses: the title tag, meta description, canonical, robots meta, hreflang, structured data and headings as rendered. Pass the full url with https://; browser_preset picks desktop (default), mobile or tablet. For speed and Core Web Vitals use seo_page_lighthouse; for the content outline seo_page_outline.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
url
The full landing page URL to audit, including the scheme. Example: https://acme.com/lp/spring-sale
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
browser_preset
Rendering viewport for the audit: 'desktop', 'mobile', or 'tablet'. Defaults to desktop.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Declare the result fields and their types in the output schema.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result",
"result_count"
],
"properties": {
"result": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "The page as a real browser rendered it: HTTP status, redirect chain, server timings, the meta tags (title, description, canonical, robots, hreflang), headings and structured data."
},
"result_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Entries in result."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_page_audit",
"title": "Audit a page's rendered HTML",
"description": "Opens one URL in a real browser and returns what Google's renderer would see: the JavaScript-rendered DOM, HTTP status, redirect chain and server timings. Use it for on-page SEO checks a plain fetch misses: the title tag, meta description, canonical, robots meta, hreflang, structured data and headings as rendered. Pass the full url with https://; browser_preset picks desktop (default), mobile or tablet. For speed and Core Web Vitals use seo_page_lighthouse; for the content outline seo_page_outline.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"minLength": 1,
"description": "The full landing page URL to audit, including the scheme. Example: https://acme.com/lp/spring-sale"
},
"browser_preset": {
"enum": [
"desktop",
"mobile",
"tablet"
],
"type": "string",
"description": "Rendering viewport for the audit: 'desktop', 'mobile', or 'tablet'. Defaults to desktop."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result",
"result_count"
],
"properties": {
"result": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "The page as a real browser rendered it: HTTP status, redirect chain, server timings, the meta tags (title, description, canonical, robots, hreflang), headings and structured data."
},
"result_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Entries in result."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Audit a page's rendered HTML",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Runs Google Lighthouse on one URL: Performance, Accessibility and Best Practices scores with the metrics behind them, Core Web Vitals included, the page-experience side of ranking. Pass the full url with https://; for_mobile true runs the mobile audit, which is what Google indexes with (desktop by default). categories narrows it to any of performance, accessibility and best_practices. For how the page looks use seo_page_screenshot.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
url
The full landing page URL to audit, including the scheme. Example: https://acme.com/lp/spring-sale
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
for_mobile
Run the mobile Lighthouse audit instead of desktop. Defaults to desktop.
Clear enough to supply this argument.
categories
Array of Lighthouse categories to audit. Each item must be one of "performance", "accessibility", "best_practices". Provide one or more; omit to audit all three. SEO is intentionally not available.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"result": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "The Lighthouse report: a score from 0 to 1 for each requested category, and the audits behind it."
},
"audited": {
"type": "boolean",
"const": false,
"description": "false when the target page itself failed to load or render — see `page_error` and `guidance`; the audit fields are absent."
},
"guidance": {
"type": "string"
},
"page_error": {
"type": "string"
},
"result_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Entries in result."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_page_lighthouse",
"title": "Run a Lighthouse audit",
"description": "Runs Google Lighthouse on one URL: Performance, Accessibility and Best Practices scores with the metrics behind them, Core Web Vitals included, the page-experience side of ranking. Pass the full url with https://; for_mobile true runs the mobile audit, which is what Google indexes with (desktop by default). categories narrows it to any of performance, accessibility and best_practices. For how the page looks use seo_page_screenshot.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"minLength": 1,
"description": "The full landing page URL to audit, including the scheme. Example: https://acme.com/lp/spring-sale"
},
"categories": {
"type": "array",
"items": {
"enum": [
"performance",
"accessibility",
"best_practices"
],
"type": "string"
},
"minItems": 1,
"description": "Array of Lighthouse categories to audit. Each item must be one of \"performance\", \"accessibility\", \"best_practices\". Provide one or more; omit to audit all three. SEO is intentionally not available."
},
"for_mobile": {
"type": "boolean",
"description": "Run the mobile Lighthouse audit instead of desktop. Defaults to desktop."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"result": {
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
},
"description": "The Lighthouse report: a score from 0 to 1 for each requested category, and the audits behind it."
},
"audited": {
"type": "boolean",
"const": false,
"description": "false when the target page itself failed to load or render — see `page_error` and `guidance`; the audit fields are absent."
},
"guidance": {
"type": "string"
},
"page_error": {
"type": "string"
},
"result_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Entries in result."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Run a Lighthouse audit",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Lists the scripts, stylesheets and images one URL loads, with their load timing: the way to find what slows a page down, broken resources (resource_type "broken"), or whether analytics and tag manager scripts load at all. Pass the full url with https://; resource_type narrows the list to script, stylesheet, image or broken.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
url
The full landing page URL to inspect, including the scheme. Example: https://acme.com/lp/spring-sale
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
resource_type
Filter the inventory to one resource type: 'script', 'stylesheet', 'image', or 'broken'. Defaults to all types.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/100
Captures one URL in a real browser and returns the image inline: what a searcher sees on arrival, above the fold and on mobile. Use it to judge whether a page answers the query it ranks for, or to compare a competitor's page with the user's. Pass the full url with https://; full_page captures the whole scrolling page; browser_preset picks desktop (default), mobile or tablet. Judge the page from the image itself.
The description explains the capability, when to use it, and what to expect.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
url
The full landing page URL to capture, including the scheme. Example: https://acme.com/lp/spring-sale
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
full_page
Capture the entire scrollable page instead of just the viewport. Defaults to viewport only.
Clear enough to supply this argument.
browser_preset
Rendering viewport for the screenshot: 'desktop', 'mobile', or 'tablet'. Defaults to desktop.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result",
"result_count"
],
"properties": {
"result": {
"type": "array",
"items": {
"type": "object",
"required": [
"url",
"full_page",
"browser_preset"
],
"properties": {
"url": {
"type": "string",
"description": "The page captured."
},
"full_page": {
"type": "boolean",
"description": "true for the whole scrollable page, false for the viewport."
},
"browser_preset": {
"type": "string",
"description": "The viewport: desktop, mobile or tablet."
}
},
"additionalProperties": {}
},
"description": "What was captured. The screenshot itself is the image in the result's content."
},
"result_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Entries in result."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_page_screenshot",
"title": "Screenshot a page",
"description": "Captures one URL in a real browser and returns the image inline: what a searcher sees on arrival, above the fold and on mobile. Use it to judge whether a page answers the query it ranks for, or to compare a competitor's page with the user's. Pass the full url with https://; full_page captures the whole scrolling page; browser_preset picks desktop (default), mobile or tablet. Judge the page from the image itself.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"minLength": 1,
"description": "The full landing page URL to capture, including the scheme. Example: https://acme.com/lp/spring-sale"
},
"full_page": {
"type": "boolean",
"description": "Capture the entire scrollable page instead of just the viewport. Defaults to viewport only."
},
"browser_preset": {
"enum": [
"desktop",
"mobile",
"tablet"
],
"type": "string",
"description": "Rendering viewport for the screenshot: 'desktop', 'mobile', or 'tablet'. Defaults to desktop."
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result",
"result_count"
],
"properties": {
"result": {
"type": "array",
"items": {
"type": "object",
"required": [
"url",
"full_page",
"browser_preset"
],
"properties": {
"url": {
"type": "string",
"description": "The page captured."
},
"full_page": {
"type": "boolean",
"description": "true for the whole scrollable page, false for the viewport."
},
"browser_preset": {
"type": "string",
"description": "The viewport: desktop, mobile or tablet."
}
},
"additionalProperties": {}
},
"description": "What was captured. The screenshot itself is the image in the result's content."
},
"result_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Entries in result."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Screenshot a page",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
A page's main content as an outline, without header, footer or sidebars: each heading with its level and the paragraphs, lists and tables under it. Sections have stable ids ("h2-3" is the third H2) and their heading path, so a content brief can say exactly where an edit goes. The summary has the title, word count, heading counts and heading problems (no H1, several H1s, skipped levels). Use it for content briefs and to compare a competitor's page structure with the user's. Pass the full url; javascript true renders scripts first and costs more, for pages whose outline comes back empty. Returns rows and a result_id; paging with result_id is free.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
url
The page to outline, e.g. "https://acme.com/blog/post". Required for a new lookup.
Clear enough to supply this argument.
javascript
Run the page's JavaScript before reading it (default false). Costs more; use it when an outline comes back empty for a page that renders its content in the browser.
Clear enough to supply this argument.
page
Page of rows to return. Defaults to 1.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
page_size
Rows per page. Defaults to 10.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
result_id
result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size.
Align the output schema with the tool’s documented result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"path",
"level",
"heading",
"paragraphs",
"word_count"
],
"properties": {
"id": {
"type": "string",
"description": "Stable section id: h2-3 is the third H2, intro-N text before any heading."
},
"path": {
"type": "string",
"description": "The ids of the headings it sits under, then its own."
},
"items": {
"type": "array",
"items": {
"type": "string"
},
"description": "Its list items."
},
"level": {
"type": [
"number",
"null"
],
"description": "Heading level 1 to 6; null for intro text."
},
"table": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string"
}
},
"description": "A table in the section, as rows of cell text."
},
"heading": {
"type": [
"string",
"null"
],
"description": "The heading text."
},
"paragraphs": {
"type": "array",
"items": {
"type": "string"
},
"description": "Its paragraphs, long ones cut with …."
},
"word_count": {
"type": "number",
"description": "Words in the section."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"url",
"status_code",
"title",
"language",
"author",
"sections",
"word_count",
"headings",
"heading_issues",
"secondary_sections"
],
"properties": {
"url": {
"type": "string",
"description": "The page."
},
"hint": {
"type": "string",
"description": "Present when nothing was found without JavaScript."
},
"title": {
"type": [
"string",
"null"
],
"description": "The page title."
},
"author": {
"type": [
"string",
"null"
],
"description": "The author, when the page names one."
},
"headings": {
"type": "object",
"description": "Headings per level, e.g. h2: 5.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"language": {
"type": [
"string",
"null"
],
"description": "The page language."
},
"sections": {
"type": "number",
"description": "Sections in the main content."
},
"word_count": {
"type": "number",
"description": "Words in the main content."
},
"status_code": {
"type": [
"number",
"null"
],
"description": "Its HTTP status."
},
"heading_issues": {
"type": "array",
"items": {
"type": "string"
},
"description": "A missing or repeated H1, or a skipped heading level."
},
"secondary_sections": {
"type": "number",
"description": "Sections outside the main content, such as sidebars."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "seo_page_outline",
"title": "Outline a page's content",
"description": "A page's main content as an outline, without header, footer or sidebars: each heading with its level and the paragraphs, lists and tables under it. Sections have stable ids (\"h2-3\" is the third H2) and their heading path, so a content brief can say exactly where an edit goes. The summary has the title, word count, heading counts and heading problems (no H1, several H1s, skipped levels). Use it for content briefs and to compare a competitor's page structure with the user's. Pass the full url; javascript true renders scripts first and costs more, for pages whose outline comes back empty. Returns rows and a result_id; paging with result_id is free.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"url": {
"type": "string",
"maxLength": 2048,
"minLength": 1,
"description": "The page to outline, e.g. \"https://acme.com/blog/post\". Required for a new lookup."
},
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Page of rows to return. Defaults to 1."
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page. Defaults to 10."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "result_id from an earlier call of this tool, valid for 24 hours: reads more pages of the same result, at no cost. With it, pass only page and page_size."
},
"javascript": {
"type": "boolean",
"description": "Run the page's JavaScript before reading it (default false). Costs more; use it when an outline comes back empty for a page that renders its content in the browser."
}
},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"result"
],
"properties": {
"result": {
"type": "object",
"required": [
"expires_at",
"page",
"page_size",
"result_id",
"row_count",
"total_pages",
"rows"
],
"properties": {
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "This page's number."
},
"rows": {
"type": "array",
"items": {
"type": "object",
"required": [
"id",
"path",
"level",
"heading",
"paragraphs",
"word_count"
],
"properties": {
"id": {
"type": "string",
"description": "Stable section id: h2-3 is the third H2, intro-N text before any heading."
},
"path": {
"type": "string",
"description": "The ids of the headings it sits under, then its own."
},
"items": {
"type": "array",
"items": {
"type": "string"
},
"description": "Its list items."
},
"level": {
"type": [
"number",
"null"
],
"description": "Heading level 1 to 6; null for intro text."
},
"table": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string"
}
},
"description": "A table in the section, as rows of cell text."
},
"heading": {
"type": [
"string",
"null"
],
"description": "The heading text."
},
"paragraphs": {
"type": "array",
"items": {
"type": "string"
},
"description": "Its paragraphs, long ones cut with …."
},
"word_count": {
"type": "number",
"description": "Words in the section."
}
},
"additionalProperties": {}
},
"description": "This page's rows."
},
"summary": {
"type": "object",
"required": [
"url",
"status_code",
"title",
"language",
"author",
"sections",
"word_count",
"headings",
"heading_issues",
"secondary_sections"
],
"properties": {
"url": {
"type": "string",
"description": "The page."
},
"hint": {
"type": "string",
"description": "Present when nothing was found without JavaScript."
},
"title": {
"type": [
"string",
"null"
],
"description": "The page title."
},
"author": {
"type": [
"string",
"null"
],
"description": "The author, when the page names one."
},
"headings": {
"type": "object",
"description": "Headings per level, e.g. h2: 5.",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": "number"
}
},
"language": {
"type": [
"string",
"null"
],
"description": "The page language."
},
"sections": {
"type": "number",
"description": "Sections in the main content."
},
"word_count": {
"type": "number",
"description": "Words in the main content."
},
"status_code": {
"type": [
"number",
"null"
],
"description": "Its HTTP status."
},
"heading_issues": {
"type": "array",
"items": {
"type": "string"
},
"description": "A missing or repeated H1, or a skipped heading level."
},
"secondary_sections": {
"type": "number",
"description": "Sections outside the main content, such as sidebars."
}
},
"description": "Totals for the whole result, sent with a fresh lookup.",
"additionalProperties": {}
},
"page_size": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Rows per page."
},
"result_id": {
"type": "string",
"minLength": 1,
"description": "The stored result. With page and page_size, reads another page without a new lookup."
},
"row_count": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0,
"description": "Rows in the whole result, across all pages."
},
"expires_at": {
"type": "string",
"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))$",
"description": "When the stored result expires. Until then result_id reads its other pages for free."
},
"total_pages": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1,
"description": "Pages in the whole result at this page_size."
}
},
"description": "One page of the lookup's rows.",
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"title": "Outline a page's content",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Shows the user's getting started steps for HYPD SEO & GEO: connecting Search Console with a selected property, a first look at which queries and pages lost organic clicks, and checking whether ChatGPT names their brand. Use it when init or seo_gsc_list_sites says so, or when the user is new or asks how to get started; a concrete SEO question goes straight to the seo_* tools. Clients that render MCP Apps show the steps with a button each: a click sends that step's prompt as the user's next message, or opens the HYPD app. There, say only that the steps are shown above: do not repeat them and do not run a step before the user clicks it. Elsewhere, list the steps with their prompts and links.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No input fields.
Annotations100/100
All four behavior hints are declared.
{
"title": "Getting started with HYPD SEO & GEO",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
Output schema76/100
The output schema explains the structured result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"done_count",
"step_count"
],
"properties": {
"done_count": {
"type": "number",
"description": "Steps the user has completed."
},
"step_count": {
"type": "number",
"description": "Steps in total."
}
},
"description": "Counts only. The steps, with their prompts and links, go to the widget; the text content lists them for clients that show no widget.",
"additionalProperties": false
}
Original tool metadata
{
"name": "hypd_show_getting_started",
"title": "Getting started with HYPD SEO & GEO",
"description": "Shows the user's getting started steps for HYPD SEO & GEO: connecting Search Console with a selected property, a first look at which queries and pages lost organic clicks, and checking whether ChatGPT names their brand. Use it when init or seo_gsc_list_sites says so, or when the user is new or asks how to get started; a concrete SEO question goes straight to the seo_* tools. Clients that render MCP Apps show the steps with a button each: a click sends that step's prompt as the user's next message, or opens the HYPD app. There, say only that the steps are shown above: do not repeat them and do not run a step before the user clicks it. Elsewhere, list the steps with their prompts and links.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {},
"additionalProperties": false
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"done_count",
"step_count"
],
"properties": {
"done_count": {
"type": "number",
"description": "Steps the user has completed."
},
"step_count": {
"type": "number",
"description": "Steps in total."
}
},
"description": "Counts only. The steps, with their prompts and links, go to the widget; the text content lists them for clients that show no widget.",
"additionalProperties": false
},
"annotations": {
"title": "Getting started with HYPD SEO & GEO",
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Searches HYPD's help center for articles that answer a question about HYPD itself: connecting or reconnecting ad accounts, plans, billing and credits, privacy and data access, what HYPD can do, and setting HYPD up in Claude, ChatGPT or other AI clients. Returns the matching articles' text and links; answer from them and cite them. Not for advertising advice or the user's account data; use the platform tools for those.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
question
The user's question about HYPD, in their words, e.g. 'How do I connect my Google Ads account?'
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations100/100
All four behavior hints are declared.
{
"title": "Search the HYPD help center",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
Output schema74/100
The output schema explains the structured result.
View output schema
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"status",
"articles",
"help_center_url",
"note"
],
"properties": {
"note": {
"type": "string",
"description": "How these results relate to the question."
},
"status": {
"enum": [
"ok",
"no_results"
],
"type": "string",
"description": "no_results when no article matched."
},
"articles": {
"type": "array",
"items": {
"type": "object",
"required": [
"title",
"url",
"description",
"content",
"updated_at"
],
"properties": {
"url": {
"type": "string",
"description": "The article's public link."
},
"title": {
"type": "string",
"description": "The article's title."
},
"content": {
"type": "string",
"description": "The article text to answer from."
},
"updated_at": {
"type": "string",
"description": "When the article last changed."
},
"description": {
"type": "string",
"description": "A one-line summary."
}
},
"additionalProperties": false
},
"description": "The matching articles."
},
"help_center_url": {
"type": "string",
"description": "The help center, for questions no article answers."
}
},
"additionalProperties": false
}
Original tool metadata
{
"name": "hypd_search_help",
"title": "Search the HYPD help center",
"description": "Searches HYPD's help center for articles that answer a question about HYPD itself: connecting or reconnecting ad accounts, plans, billing and credits, privacy and data access, what HYPD can do, and setting HYPD up in Claude, ChatGPT or other AI clients. Returns the matching articles' text and links; answer from them and cite them. Not for advertising advice or the user's account data; use the platform tools for those.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"question"
],
"properties": {
"question": {
"type": "string",
"maxLength": 500,
"minLength": 1,
"description": "The user's question about HYPD, in their words, e.g. 'How do I connect my Google Ads account?'"
}
}
},
"outputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"status",
"articles",
"help_center_url",
"note"
],
"properties": {
"note": {
"type": "string",
"description": "How these results relate to the question."
},
"status": {
"enum": [
"ok",
"no_results"
],
"type": "string",
"description": "no_results when no article matched."
},
"articles": {
"type": "array",
"items": {
"type": "object",
"required": [
"title",
"url",
"description",
"content",
"updated_at"
],
"properties": {
"url": {
"type": "string",
"description": "The article's public link."
},
"title": {
"type": "string",
"description": "The article's title."
},
"content": {
"type": "string",
"description": "The article text to answer from."
},
"updated_at": {
"type": "string",
"description": "When the article last changed."
},
"description": {
"type": "string",
"description": "A one-line summary."
}
},
"additionalProperties": false
},
"description": "The matching articles."
},
"help_center_url": {
"type": "string",
"description": "The help center, for questions no article answers."
}
},
"additionalProperties": false
},
"annotations": {
"title": "Search the HYPD help center",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Check Google TrendsHow search interest in 1–5 terms moves over time on Google web search, news, YouTube, images or shopping: the series, the regions where interest is highest a…
02Search the HYPD help centerSearches HYPD's help center for articles that answer a question about HYPD itself: connecting or reconnecting ad accounts, plans, billing and credits, privac…
03Read a Google results pageGoogle's results page for one keyword in one market, by block: organic, featured_snippet, people_also_ask, ai_overview, local_pack, related_searches and more.
04Audit a page's rendered HTMLOpens one URL in a real browser and returns what Google's renderer would see: the JavaScript-rendered DOM, HTTP status, redirect chain and server timings.
05Run a Lighthouse auditRuns Google Lighthouse on one URL: Performance, Accessibility and Best Practices scores with the metrics behind them, Core Web Vitals included, the page-expe…
Want to run these tasks against your MCP server with us?
HYPD AI for SEO & GEO setup, tools, quality score, publishing readiness, and alternatives.
How do I add HYPD AI for SEO & GEO to Claude, ChatGPT, or Cursor?
Add HYPD AI for SEO & GEO to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://seo.hypd.ai/mcp.
Is HYPD AI for SEO & GEO MCP ready for ChatGPT and Claude?
As of November 13, 2026, HYPD AI for SEO & GEO scores 100/100 on Manufact's MCP publishing checklist. The scan meets ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is HYPD AI for SEO & GEO's MCP tool documentation?
As of November 13, 2026, HYPD AI for SEO & GEO scores 92/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 33 of 33 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What are the best alternatives to HYPD AI for SEO & GEO?
As of November 13, 2026, alternatives to HYPD AI for SEO & GEO in marketing-seo on the Manufact MCP leaderboard include BulkPublish, Notra, Fuxux, HYPD AI for App Store Optimization, and HYPD AI for Google Search Console.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.