<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: AgentSEO-dev</title>
    <description>The latest articles on DEV Community by AgentSEO-dev (@agentseodev).</description>
    <link>https://dev.to/agentseodev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4038290%2F83084df5-eb23-41ca-8787-0ab95e10c6dd.png</url>
      <title>DEV Community: AgentSEO-dev</title>
      <link>https://dev.to/agentseodev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/agentseodev"/>
    <language>en</language>
    <item>
      <title>How to Audit Title Tags and Meta Descriptions Without Chasing Character Counts</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Thu, 27 Aug 2026 07:22:49 +0000</pubDate>
      <link>https://dev.to/agentseodev/how-to-audit-title-tags-and-meta-descriptions-without-chasing-character-counts-267g</link>
      <guid>https://dev.to/agentseodev/how-to-audit-title-tags-and-meta-descriptions-without-chasing-character-counts-267g</guid>
      <description>&lt;p&gt;A title and meta description audit can produce hundreds of “issues” without finding one page worth changing.&lt;/p&gt;

&lt;p&gt;The usual export flags every title over 60 characters and every description over 160. That catches obvious implementation defects. It does not tell you whether Google showed the title, whether the snippet matched the query, whether the page earned impressions, or whether a rewrite would improve the result.&lt;/p&gt;

&lt;p&gt;This workflow separates three different jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;fix broken or ambiguous metadata;&lt;/li&gt;
&lt;li&gt;align the title, visible heading, and page promise;&lt;/li&gt;
&lt;li&gt;test search-result copy only where query-level evidence justifies it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The output is a short action queue, not a spreadsheet full of red cells.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the displayed result, not a universal length limit
&lt;/h2&gt;

&lt;p&gt;Google does not document a fixed character limit for title links or meta descriptions. Title links are truncated as needed, usually to fit the device width. Snippets are also truncated to fit the result.&lt;/p&gt;

&lt;p&gt;More importantly, your HTML is an input rather than a command.&lt;/p&gt;

&lt;p&gt;Google can create a title link from the &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; element, visible page title, headings, &lt;code&gt;og:title&lt;/code&gt;, prominent page text, and link text. It primarily creates snippets from page content and may use the meta description when that gives a better page summary for the search.&lt;/p&gt;

&lt;p&gt;That changes the audit question.&lt;/p&gt;

&lt;p&gt;Do not ask only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is this title under 60 characters?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;For an important query, does the displayed title and snippet describe the page
accurately, distinguish it from competing results, and set up the promise the
visitor sees after clicking?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Length is still useful as a risk signal. It is not a pass/fail standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the audit from four evidence sets
&lt;/h2&gt;

&lt;p&gt;You need four inputs to make a defensible decision.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Evidence&lt;/th&gt;
&lt;th&gt;What it tells you&lt;/th&gt;
&lt;th&gt;What it cannot tell you&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Crawl or rendered HTML&lt;/td&gt;
&lt;td&gt;Missing, duplicate, empty, or conflicting signals&lt;/td&gt;
&lt;td&gt;What Google displayed for a query&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page copy and headings&lt;/td&gt;
&lt;td&gt;Whether the metadata matches the visible promise&lt;/td&gt;
&lt;td&gt;Whether searchers found the result attractive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search Console page/query data&lt;/td&gt;
&lt;td&gt;Impressions, clicks, CTR, and average position&lt;/td&gt;
&lt;td&gt;The exact causal effect of changing copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A current SERP check&lt;/td&gt;
&lt;td&gt;Displayed title, snippet, competitors, and result features&lt;/td&gt;
&lt;td&gt;A stable result for every user, query, or device&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Use the crawl to find defects. Use the page to judge accuracy. Use Search Console to prioritize. Use the live result to inspect what Google actually chose.&lt;/p&gt;

&lt;p&gt;Do not use one evidence set as a substitute for the others.&lt;/p&gt;

&lt;h2&gt;
  
  
  Triage implementation defects before copy opportunities
&lt;/h2&gt;

&lt;p&gt;Start with canonical, indexable pages that return a successful response. Metadata work on a blocked, redirected, or non-canonical URL is usually the wrong queue.&lt;/p&gt;

&lt;p&gt;Then flag defects that prevent a clear page signal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no HTML title element;&lt;/li&gt;
&lt;li&gt;an empty or half-complete title that contains only a separator and brand name;&lt;/li&gt;
&lt;li&gt;multiple templates producing the same title for different pages;&lt;/li&gt;
&lt;li&gt;an obsolete year, price, availability claim, or product name;&lt;/li&gt;
&lt;li&gt;no clear main heading;&lt;/li&gt;
&lt;li&gt;a title, H1, and visible introduction that describe different jobs;&lt;/li&gt;
&lt;li&gt;a missing description on a commercially or editorially important page;&lt;/li&gt;
&lt;li&gt;a description copied across pages where the details should differ;&lt;/li&gt;
&lt;li&gt;metadata present in a CMS field but missing from rendered HTML.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are repair tasks. You do not need a CTR theory to fix them.&lt;/p&gt;

&lt;p&gt;Google's title-link guidance specifically identifies half-empty, obsolete, inaccurate, and boilerplate titles, along with pages that have no clear main title. A generated replacement is often a symptom of ambiguous or stale page signals—not proof that Google has made an error.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat Google rewrites as a diagnostic clue
&lt;/h2&gt;

&lt;p&gt;Practitioners regularly ask why Google ignored a supplied title or description. Recent r/TechSEO discussions show the same frustration: a CMS field looks correct, but the search result uses a heading or opening sentence instead.&lt;/p&gt;

&lt;p&gt;That community evidence is directional, not a rewrite-rate benchmark. The useful pattern is the question itself.&lt;/p&gt;

&lt;p&gt;When a displayed result differs from your metadata, record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;query;&lt;/li&gt;
&lt;li&gt;URL;&lt;/li&gt;
&lt;li&gt;device and country;&lt;/li&gt;
&lt;li&gt;supplied title and description;&lt;/li&gt;
&lt;li&gt;displayed title and snippet;&lt;/li&gt;
&lt;li&gt;the on-page source Google appears to have used;&lt;/li&gt;
&lt;li&gt;date checked.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then classify the difference.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rewrite pattern&lt;/th&gt;
&lt;th&gt;Likely issue to inspect&lt;/th&gt;
&lt;th&gt;First action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Google uses the H1&lt;/td&gt;
&lt;td&gt;Title may be vague, boilerplate, or less descriptive&lt;/td&gt;
&lt;td&gt;Compare the title with the H1 and query intent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google uses an opening paragraph&lt;/td&gt;
&lt;td&gt;Meta description may not summarize the visible page&lt;/td&gt;
&lt;td&gt;Improve page copy before polishing the tag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google removes the brand&lt;/td&gt;
&lt;td&gt;Branding may be repetitive or unhelpful in this result&lt;/td&gt;
&lt;td&gt;Keep branding concise; do not force repetition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google changes a date or product detail&lt;/td&gt;
&lt;td&gt;Metadata may be obsolete&lt;/td&gt;
&lt;td&gt;Correct every conflicting page signal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Different queries show different snippets&lt;/td&gt;
&lt;td&gt;The page answers multiple specific needs&lt;/td&gt;
&lt;td&gt;Check whether each snippet is accurate; this may be normal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not promise to “stop Google rewriting” metadata. Google documents the generation as automated and query-dependent. You can make the signals clearer; you cannot force one exact result for every search.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prioritize pages with query-level evidence
&lt;/h2&gt;

&lt;p&gt;A metadata queue should begin with pages that matter, not pages that are easiest to export.&lt;/p&gt;

&lt;p&gt;For each canonical URL, compare the latest 28 days with a useful prior period and keep the query dimension. Prioritize pages where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;impressions are meaningful enough to learn from;&lt;/li&gt;
&lt;li&gt;average position is reasonably stable;&lt;/li&gt;
&lt;li&gt;CTR fell for the same query cluster;&lt;/li&gt;
&lt;li&gt;the displayed result is inaccurate, generic, or visibly misaligned;&lt;/li&gt;
&lt;li&gt;the page still satisfies the intent after the click;&lt;/li&gt;
&lt;li&gt;a business-relevant action happens on the page.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Deprioritize pages where demand collapsed, position changed materially, the SERP layout changed, or the page no longer satisfies the query. Those are not clean metadata tests.&lt;/p&gt;

&lt;p&gt;Average CTR benchmarks are a poor substitute for this comparison. CTR varies with position, query type, brand familiarity, device, country, and SERP features. Compare the same page and query family under reasonably similar conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a decision table instead of rewriting everything
&lt;/h2&gt;

&lt;p&gt;This is the action model I would apply to the queue.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Condition&lt;/th&gt;
&lt;th&gt;Decision&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Missing, empty, obsolete, deceptive, or duplicate title&lt;/td&gt;
&lt;td&gt;Fix now&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Title, H1, and opening promise conflict&lt;/td&gt;
&lt;td&gt;Fix the page-message system, then metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Description missing on a priority URL&lt;/td&gt;
&lt;td&gt;Add a page-specific summary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google rewrite is accurate and useful&lt;/td&gt;
&lt;td&gt;Leave it alone; record the observation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supplied metadata is accurate but displayed copy is weak for an important query&lt;/td&gt;
&lt;td&gt;Test one aligned alternative&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CTR fell because position or SERP features changed&lt;/td&gt;
&lt;td&gt;Diagnose the ranking or result-layout change first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Page no longer fulfills the query&lt;/td&gt;
&lt;td&gt;Refresh or reposition the page before testing snippet copy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Low-impression URL with no business value&lt;/td&gt;
&lt;td&gt;Deprioritize&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The hard part is accepting that “no change” is a valid audit result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generate options from the page promise, not a keyword list
&lt;/h2&gt;

&lt;p&gt;Once a URL passes triage, create alternatives from the visible page.&lt;/p&gt;

&lt;p&gt;The title should identify the topic and distinguish the page. The description should summarize what the visitor can actually get. Neither should promise a comparison, template, price, result, or feature that the page does not provide.&lt;/p&gt;

&lt;p&gt;AgentSEO's &lt;code&gt;/content/title-meta&lt;/code&gt; endpoint can turn a URL or Markdown page into three title options, three meta description options, current-signal checks, snippet risks, and an implementation checklist.&lt;/p&gt;

&lt;p&gt;Here is a copy-paste request using Markdown so the input remains reproducible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://www.agentseo.dev/api/v1/content/title-meta?sync=true"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: sk_live_REPLACE_ME"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "keyword": "SEO API for AI agents",
    "target": "AgentSEO",
    "page_type": "software",
    "current_title": "SEO API | AgentSEO",
    "current_meta_description": "The token-optimized SEO API for AI agents.",
    "page_markdown": "# SEO Intelligence API for AI Agents\n\nAgentSEO returns compact SERP metrics, content workflow recommendations, and strict JSON for MCP and REST integrations. Builders can test requests in the Playground before wiring scheduled production jobs.\n\n## Build with deterministic search intelligence\n\nUse documented endpoints for content briefs, rank tracking, internal links, and technical QA."
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current endpoint costs two credits and does not call a paid SERP provider. It uses the page you supply or retrieves the URL, then checks signal alignment and produces options. Confirm current behavior and pricing in the &lt;a href="https://www.agentseo.dev/docs/api-reference" rel="noopener noreferrer"&gt;AgentSEO API reference&lt;/a&gt; before production use.&lt;/p&gt;

&lt;p&gt;Treat the result as a review plan. The endpoint does not inspect a live Google result or forecast a CTR gain.&lt;/p&gt;

&lt;p&gt;A useful output review looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Reject any option that changes the page's actual promise.
2. Resolve high-severity missing-title or missing-H1 findings first.
3. Check the title against the visible H1 and first screen of copy.
4. Choose one option for the target query family.
5. Record the exact old and new values before deployment.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you prefer tools inside an agent workflow, the same job is available through the &lt;a href="https://www.agentseo.dev/mcp" rel="noopener noreferrer"&gt;AgentSEO MCP server&lt;/a&gt;. Use REST when this is a scheduled batch or application backend; use MCP when an operator is reviewing pages interactively with an agent.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test one controlled change
&lt;/h2&gt;

&lt;p&gt;Metadata tests are noisy, so keep the release small.&lt;/p&gt;

&lt;p&gt;Record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL and target query family;&lt;/li&gt;
&lt;li&gt;deployment date and time;&lt;/li&gt;
&lt;li&gt;old and new title and description;&lt;/li&gt;
&lt;li&gt;reason for the change;&lt;/li&gt;
&lt;li&gt;28-day and 90-day pre-change query metrics;&lt;/li&gt;
&lt;li&gt;displayed result before the change;&lt;/li&gt;
&lt;li&gt;any simultaneous content, template, or internal-link changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verify the rendered HTML immediately. Then allow time for recrawling and reprocessing. Google's title-link documentation says this can take a few days to a few weeks.&lt;/p&gt;

&lt;p&gt;Review recrawl and display behavior in 3–7 days, direction after 14 days, and the primary comparison after 28 days. Keep the query, device, country, position, and SERP layout in view.&lt;/p&gt;

&lt;p&gt;Do not call a CTR change causal if rankings, demand, result features, or page content changed at the same time. The honest outcome may be “promising but confounded.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Failure modes that make the audit look busier than it is
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Rewriting every long title
&lt;/h3&gt;

&lt;p&gt;A long title can be truncated, but Google does not publish a universal character ceiling. Fix verbosity and ambiguity; do not cut useful words only to make a crawler cell green.&lt;/p&gt;

&lt;h3&gt;
  
  
  Treating every generated snippet as a defect
&lt;/h3&gt;

&lt;p&gt;Different searches can legitimately produce different snippets from the same page. Inspect whether the displayed text is accurate for that query.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimizing the tag while ignoring the page
&lt;/h3&gt;

&lt;p&gt;If the H1, introduction, and body do not support the promise, the metadata is cosmetic. Fix the visible page first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Changing titles on pages with unstable positions
&lt;/h3&gt;

&lt;p&gt;A CTR change is hard to interpret when average position or the SERP layout is moving. Stabilize the comparison or label the result inconclusive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using schema to force ordinary titles or descriptions
&lt;/h3&gt;

&lt;p&gt;Structured data can make a page eligible for supported search features. It does not provide a control panel for the ordinary title link and snippet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automating deployment from a generated option
&lt;/h3&gt;

&lt;p&gt;Generation is reversible. Publishing is not. Keep a human review gate before a title or description reaches production, especially on revenue pages and large templates.&lt;/p&gt;

&lt;h2&gt;
  
  
  The finished queue should fit on one screen
&lt;/h2&gt;

&lt;p&gt;The deliverable is not a sitewide list of lengths. It is a ranked decision queue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fix now: broken or misleading signals
Align first: title, H1, and page promise conflict
Test: important query with stable visibility and a weak displayed result
Observe: accurate Google rewrite with no clear user problem
Ignore: low-value page or confounded evidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start with ten priority URLs. Fix defects, test one aligned change at a time, and leave accurate generated results alone.&lt;/p&gt;

&lt;p&gt;That is slower than bulk rewriting metadata. It is also an audit you can learn from.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;AI assistance disclosure:&lt;/strong&gt; Human topic selection, product context, source standards, and publication judgment guide this article. AI assisted with research organization and drafting. Daniel Martin must review the claims, examples, voice, and final recommendation before publication.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Do an Internal Linking Audit That Produces Useful Fixes</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Thu, 27 Aug 2026 07:03:53 +0000</pubDate>
      <link>https://dev.to/agentseodev/how-to-do-an-internal-linking-audit-that-produces-useful-fixes-b9p</link>
      <guid>https://dev.to/agentseodev/how-to-do-an-internal-linking-audit-that-produces-useful-fixes-b9p</guid>
      <description>&lt;p&gt;An internal linking audit can produce a clean spreadsheet and still fail to improve the site.&lt;/p&gt;

&lt;p&gt;The usual report counts links, flags orphan pages, and lists crawl depth. That is necessary diagnostic work. It does not answer the harder editorial question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Which page should link to this URL, in which section, with what anchor, and why would the link help the reader?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You need both layers. First, audit the site graph to find structural problems. Then review the page context before adding any link.&lt;/p&gt;

&lt;p&gt;This tutorial gives you a repeatable workflow for doing that. It includes a spreadsheet-ready decision model and a copy-paste AgentSEO request for ranking supplied target pages against a source article.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;To audit internal links:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build an inventory of canonical, indexable URLs.&lt;/li&gt;
&lt;li&gt;Crawl the site and join the crawl with sitemap, analytics, and Search Console exports.&lt;/li&gt;
&lt;li&gt;Find orphan candidates, broken destinations, redirects, excessive depth, and important pages with weak relevant support.&lt;/li&gt;
&lt;li&gt;Prioritize pages by business value and search role, not raw inlink count.&lt;/li&gt;
&lt;li&gt;Choose contextually relevant source pages for each target.&lt;/li&gt;
&lt;li&gt;Write concise, descriptive anchors inside useful body copy.&lt;/li&gt;
&lt;li&gt;Verify the rendered HTML contains normal crawlable &lt;code&gt;&amp;lt;a href&amp;gt;&lt;/code&gt; links.&lt;/li&gt;
&lt;li&gt;Release a controlled batch and measure page-level outcomes.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Google's current link guidance supports the fundamentals behind this workflow: links help Google discover pages and understand relevance, crawlable links generally use an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element with an &lt;code&gt;href&lt;/code&gt;, and anchor text should be descriptive, concise, and relevant. Google also says every page you care about should have a link from at least one other page on your site. &lt;a href="https://developers.google.com/search/docs/crawling-indexing/links-crawlable" rel="noopener noreferrer"&gt;Read Google's link best practices&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;That guidance does not mean every page needs more links. The audit should improve routes through the site, not maximize a count.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a page inventory, not an anchor-text brainstorm
&lt;/h2&gt;

&lt;p&gt;Your crawler sees URLs it can reach. Your XML sitemap may contain URLs the crawler cannot reach. Search Console and analytics may contain historical URLs absent from both.&lt;/p&gt;

&lt;p&gt;Combine at least these sources:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;What it can reveal&lt;/th&gt;
&lt;th&gt;What it cannot prove alone&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Site crawl&lt;/td&gt;
&lt;td&gt;Current link paths, status codes, depth, inlinks, outlinks&lt;/td&gt;
&lt;td&gt;Whether an uncrawled URL exists elsewhere&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;XML sitemap&lt;/td&gt;
&lt;td&gt;URLs you intend search engines to discover&lt;/td&gt;
&lt;td&gt;Whether each URL has internal support or deserves indexation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search Console&lt;/td&gt;
&lt;td&gt;Pages with Google Search impressions or clicks&lt;/td&gt;
&lt;td&gt;A complete site architecture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Analytics&lt;/td&gt;
&lt;td&gt;Pages people visit and paths they take&lt;/td&gt;
&lt;td&gt;Search-engine crawlability&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CMS export&lt;/td&gt;
&lt;td&gt;Published pages and ownership metadata&lt;/td&gt;
&lt;td&gt;What production actually renders&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Normalize the URLs before comparing them. Remove fragments, handle trailing slashes consistently, and separate tracking parameters from canonical URLs. Keep the original values in another column so the cleanup stays reversible.&lt;/p&gt;

&lt;p&gt;Your working inventory should include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;url
canonical_url
status_code
indexability
page_type
primary_topic
business_priority
inlinks
unique_linking_pages
crawl_depth
sitemap_present
search_impressions_90d
organic_clicks_90d
conversion_role
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not call a page an orphan merely because one crawler missed it. A crawl limit, blocked resource, JavaScript rendering problem, or incomplete starting set can create false positives. Treat orphan status as a candidate finding until you reconcile the crawl with the sitemap, CMS, Search Console, and analytics.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate technical defects from editorial opportunities
&lt;/h2&gt;

&lt;p&gt;One queue should not mix broken links with optional content improvements. The fixes have different risk and ownership.&lt;/p&gt;

&lt;h3&gt;
  
  
  Technical defects
&lt;/h3&gt;

&lt;p&gt;These normally deserve the first pass:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;internal links that resolve to &lt;code&gt;4xx&lt;/code&gt; or &lt;code&gt;5xx&lt;/code&gt; pages&lt;/li&gt;
&lt;li&gt;links that pass through avoidable redirect chains&lt;/li&gt;
&lt;li&gt;important URLs that have no confirmed crawlable internal link&lt;/li&gt;
&lt;li&gt;links implemented as click handlers without a resolvable &lt;code&gt;href&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;links to non-canonical, duplicate, or unintended &lt;code&gt;noindex&lt;/code&gt; URLs&lt;/li&gt;
&lt;li&gt;important pages buried behind pagination or excessive crawl depth&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Editorial opportunities
&lt;/h3&gt;

&lt;p&gt;These require judgment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a strong source page mentions a concept but does not link to the best next resource&lt;/li&gt;
&lt;li&gt;an important product or documentation page is supported only by navigation links&lt;/li&gt;
&lt;li&gt;anchors such as “click here” or “read more” hide the destination's meaning&lt;/li&gt;
&lt;li&gt;multiple links use forced exact-match phrasing that reads unnaturally&lt;/li&gt;
&lt;li&gt;unrelated pages link to a target only because they have traffic or backlinks&lt;/li&gt;
&lt;li&gt;a new or refreshed page does not connect to its surrounding topic cluster&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The technical queue asks, “Can a crawler reach the right URL?” The editorial queue asks, “Does this link make sense in the reader's journey?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Prioritize targets before choosing sources
&lt;/h2&gt;

&lt;p&gt;Raw inlink count is a weak priority rule. Ten boilerplate links from tag pages are not equivalent to two relevant contextual links from pages that readers already use.&lt;/p&gt;

&lt;p&gt;Score target pages with criteria your team can defend:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Criterion&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Example score&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Business role&lt;/td&gt;
&lt;td&gt;Does the page support evaluation, activation, or retention?&lt;/td&gt;
&lt;td&gt;0–3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search opportunity&lt;/td&gt;
&lt;td&gt;Does the page already have impressions, useful rankings, or validated demand?&lt;/td&gt;
&lt;td&gt;0–3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structural need&lt;/td&gt;
&lt;td&gt;Is it orphaned, deep, or weakly supported by relevant pages?&lt;/td&gt;
&lt;td&gt;0–3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Content readiness&lt;/td&gt;
&lt;td&gt;Is the destination accurate, useful, canonical, and fit to receive traffic?&lt;/td&gt;
&lt;td&gt;0–3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fix confidence&lt;/td&gt;
&lt;td&gt;Can the team identify a genuinely relevant source and placement?&lt;/td&gt;
&lt;td&gt;0–3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Prioritize high-value pages with structural need and a sound destination. Do not push more internal traffic to a thin, outdated, redirected, or conversion-hostile page. Fix the destination first.&lt;/p&gt;

&lt;p&gt;This is also where you avoid a common audit failure: adding links to every orphan. Some orphan candidates should be merged, redirected, removed from the sitemap, or left out of the index rather than rescued.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the source page and placement together
&lt;/h2&gt;

&lt;p&gt;Once you have a target shortlist, search the content inventory for pages that discuss the same problem, task, entity, or next step.&lt;/p&gt;

&lt;p&gt;A useful source page passes four checks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Topical fit:&lt;/strong&gt; The surrounding section naturally relates to the target.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reader utility:&lt;/strong&gt; The destination helps the reader continue, compare, implement, or verify.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Page quality:&lt;/strong&gt; The source is canonical, indexable, and worth maintaining.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Placement clarity:&lt;/strong&gt; You can point to an existing paragraph or heading where the link belongs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you cannot name the sentence-level reason for the link, do not add it yet.&lt;/p&gt;

&lt;p&gt;Recent practitioner discussions make the same distinction. One r/TechSEO thread argues that a technically crawlable page can still lack meaningful support when it has few links from relevant pages or vague anchors. Another discussion notes that an inlink count misses where links come from and whether the anchor describes the destination. These are practitioner observations, not proof of a ranking effect, but they expose a real audit-quality problem. &lt;a href="https://www.reddit.com/r/TechSEO/comments/1trllxi/" rel="noopener noreferrer"&gt;Read the first discussion&lt;/a&gt; and &lt;a href="https://www.reddit.com/r/TechSEO/comments/1u6j9gx/" rel="noopener noreferrer"&gt;the follow-up discussion&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use AgentSEO to rank supplied targets for one source page
&lt;/h2&gt;

&lt;p&gt;AgentSEO's &lt;code&gt;/content/internal-links&lt;/code&gt; endpoint handles the editorial layer of the workflow. You provide one source URL or its Markdown plus 1–50 candidate target pages. It returns ranked opportunities, suggested anchor text, a source section, placement instructions, confidence, anchor risk, and review guardrails.&lt;/p&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; crawl the entire site graph in v1. Use a crawler, CMS export, sitemap audit, or Search Console data to build and prioritize the candidate set first.&lt;/p&gt;

&lt;p&gt;Here is a copy-paste request using supplied Markdown, which makes the input reproducible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://www.agentseo.dev/api/v1/content/internal-links?sync=true"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: &lt;/span&gt;&lt;span class="nv"&gt;$AGENTSEO_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "keyword": "SEO API",
    "target": "AgentSEO",
    "max_suggestions": 4,
    "source_markdown": "# Build an SEO agent\n\nAn SEO agent needs stable search data, explicit workflow boundaries, and a review gate before changes reach production.\n\n## Choose the integration\n\nUse a tool protocol when the model should discover and call SEO capabilities during a conversation. Use REST when your application controls orchestration, retries, and storage.\n\n## Validate the result\n\nCheck the returned evidence, confidence, limitations, and next action before allowing an automated change.",
    "target_pages": [
      {
        "url": "https://www.agentseo.dev/seo-mcp-server",
        "title": "AgentSEO MCP Server",
        "description": "Connect SEO search intelligence tools to compatible AI clients.",
        "keywords": ["SEO MCP server", "MCP tools"]
      },
      {
        "url": "https://www.agentseo.dev/docs/api-reference",
        "title": "AgentSEO API Reference",
        "description": "REST endpoints, request fields, and response contracts.",
        "keywords": ["SEO API reference", "REST endpoints"]
      },
      {
        "url": "https://www.agentseo.dev/editorial-policy",
        "title": "AgentSEO Editorial and Evidence Policy",
        "description": "Evidence, review, disclosure, and publication standards.",
        "keywords": ["editorial review", "evidence policy"]
      }
    ]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use your actual page descriptions and topic labels. Weak metadata creates weak matching.&lt;/p&gt;

&lt;p&gt;I verified this exact request against the production endpoint on August 27, 2026. The short sync window returned a standard &lt;code&gt;202&lt;/code&gt; job envelope, and polling the supplied &lt;code&gt;poll_url&lt;/code&gt; returned a completed result with three opportunities:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Suggested target&lt;/th&gt;
&lt;th&gt;Anchor&lt;/th&gt;
&lt;th&gt;Relevance&lt;/th&gt;
&lt;th&gt;Confidence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AgentSEO API Reference&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SEO API reference&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;26/100&lt;/td&gt;
&lt;td&gt;0.64&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AgentSEO Editorial and Evidence Policy&lt;/td&gt;
&lt;td&gt;&lt;code&gt;editorial review&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;25/100&lt;/td&gt;
&lt;td&gt;0.63&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AgentSEO MCP Server&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SEO MCP server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;21/100&lt;/td&gt;
&lt;td&gt;0.60&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The output also flagged the 71-word sample as thin and recommended adding useful context before inserting several links. That is the right kind of resistance: all three matches are candidates for review, not automatic edits. This was one supplied-markdown test with three candidate targets, so it verifies the request and response contract rather than recommendation quality across a full site.&lt;/p&gt;

&lt;p&gt;The endpoint currently costs two credits and does not call a paid SERP provider. See the current request contract in the &lt;a href="https://www.agentseo.dev/docs/api-reference" rel="noopener noreferrer"&gt;AgentSEO API reference&lt;/a&gt; and test the workflow in the &lt;a href="https://www.agentseo.dev/dashboard/playground" rel="noopener noreferrer"&gt;AgentSEO Playground&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review the output as a recommendation, not an instruction
&lt;/h2&gt;

&lt;p&gt;A returned opportunity should survive a human review before implementation.&lt;/p&gt;

&lt;p&gt;For each suggestion, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the target the canonical page for this intent?&lt;/li&gt;
&lt;li&gt;Does the source paragraph actually introduce the target's topic?&lt;/li&gt;
&lt;li&gt;Would a reader reasonably want the destination at this point?&lt;/li&gt;
&lt;li&gt;Is the proposed anchor descriptive without sounding forced?&lt;/li&gt;
&lt;li&gt;Does the source already link to this destination?&lt;/li&gt;
&lt;li&gt;Will the link render in production as an &lt;code&gt;&amp;lt;a&amp;gt;&lt;/code&gt; element with an &lt;code&gt;href&lt;/code&gt;?&lt;/li&gt;
&lt;li&gt;Are you creating too many links in one paragraph or section?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An automated relevance score cannot see every business constraint. It may not know that a product page is being retired, that two docs pages are about to merge, or that a legally required disclaimer changes the best placement.&lt;/p&gt;

&lt;p&gt;Keep a rejection reason in the audit sheet. “Not relevant enough,” “target being consolidated,” and “destination not ready” are useful training data for the next review. Silent deletion is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write anchors for comprehension
&lt;/h2&gt;

&lt;p&gt;Google recommends anchor text that is descriptive, reasonably concise, and relevant to both the source and destination. That is a better rule than forcing the same target keyword every time.&lt;/p&gt;

&lt;p&gt;Prefer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;AgentSEO API reference&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content decay workflow&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compare MCP and REST for SEO agents&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;click here&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;learn more&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;a long sentence linked in full&lt;/li&gt;
&lt;li&gt;the same exact commercial phrase on every source page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anchor diversity should come from natural language and different source contexts, not a spreadsheet quota. If the most accurate anchor repeats occasionally, that is less concerning than rewriting useful copy into awkward variants.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ship the fixes in controlled batches
&lt;/h2&gt;

&lt;p&gt;Do not rewrite the entire link graph in one release. Start with a small group of priority targets and record:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deployment date and changed URLs&lt;/li&gt;
&lt;li&gt;source URL, target URL, anchor, and placement&lt;/li&gt;
&lt;li&gt;reason for the change&lt;/li&gt;
&lt;li&gt;pre-change crawl depth and unique linking pages&lt;/li&gt;
&lt;li&gt;pre-change 28-day and 90-day Search Console page/query metrics&lt;/li&gt;
&lt;li&gt;conversion or activation event tied to the target page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verify the rendered pages immediately. Then review recrawl and indexation after 3–7 days, directional page/query movement after 14 days, primary performance after 28 days, and retain/iterate decisions after 56 days.&lt;/p&gt;

&lt;p&gt;Do not claim that a ranking change came from one internal link unless you controlled the other variables. Search demand, page edits, external links, competitors, and Google systems can all move at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The audit is complete when every recommendation has an owner
&lt;/h2&gt;

&lt;p&gt;A useful internal linking audit does not end with a severity score. It ends with a decision:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fix the broken or redirected link&lt;/li&gt;
&lt;li&gt;add a relevant contextual link&lt;/li&gt;
&lt;li&gt;improve the destination before linking&lt;/li&gt;
&lt;li&gt;merge or redirect the target&lt;/li&gt;
&lt;li&gt;leave the link graph unchanged&lt;/li&gt;
&lt;li&gt;monitor because the evidence is incomplete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical next move is to choose five important target pages, reconcile their crawl and sitemap status, then review only the most relevant source pages. That small batch will teach you more than automatically inserting hundreds of links.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: AI assisted with research organization, drafting, editing, and cover-image creation. Daniel Martin should review the claims, examples, recommendations, and final publication decision before this article is published.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Find and Fix Keyword Cannibalization With Google Search Console Data</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Tue, 25 Aug 2026 15:31:29 +0000</pubDate>
      <link>https://dev.to/agentseodev/how-to-find-and-fix-keyword-cannibalization-with-google-search-console-data-2o1b</link>
      <guid>https://dev.to/agentseodev/how-to-find-and-fix-keyword-cannibalization-with-google-search-console-data-2o1b</guid>
      <description>&lt;p&gt;Two pages receiving impressions for the same query is not enough evidence to merge them.&lt;/p&gt;

&lt;p&gt;It is a reason to investigate.&lt;/p&gt;

&lt;p&gt;That distinction matters because a rushed cannibalization cleanup can erase a useful page, redirect an audience to the wrong intent, or canonicalize two pages that are not actually duplicates. The site ends up tidier in a spreadsheet and less useful in search.&lt;/p&gt;

&lt;p&gt;A safer workflow combines three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Google Search Console performance data&lt;/li&gt;
&lt;li&gt;page-level intent and business value&lt;/li&gt;
&lt;li&gt;a clear ownership decision for every affected query&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial shows how to turn those inputs into a review queue, use an agent to structure the evidence, and choose among differentiation, internal linking, consolidation, canonicalization, or no change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a conflict, not a duplicate keyword
&lt;/h2&gt;

&lt;p&gt;Keyword overlap is normal.&lt;/p&gt;

&lt;p&gt;A product page and a tutorial can both receive impressions for the same broad phrase. Two location pages can share service terms. A glossary page may appear for a query that usually belongs to a commercial page.&lt;/p&gt;

&lt;p&gt;The useful question is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Do multiple URLs appear for this query?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Are multiple URLs serving the same intent, and is that overlap preventing the right page from performing its job?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Recent discussions in r/SEO keep returning to this distinction. Practitioners recommend starting with query-page exports, but they also warn that multiple ranking URLs can be normal and must be judged case by case. Treat that as directional community evidence, not a ranking rule. &lt;a href="https://www.reddit.com/r/SEO/comments/1uawuse/canibalization/" rel="noopener noreferrer"&gt;Discussion: checking cannibalization across a 200-page site&lt;/a&gt; · &lt;a href="https://www.reddit.com/r/SEO/comments/1r2hgif/what_is_the_best_way_to_diagnose_cannibalized/" rel="noopener noreferrer"&gt;Discussion: different intents are not necessarily cannibalization&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google's own documentation gives us two important constraints:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search Console lets you group and filter performance by query and page, but anonymized queries and data truncation mean the report is not a complete ledger. &lt;a href="https://support.google.com/webmasters/answer/17011259?hl=en" rel="noopener noreferrer"&gt;Search Console dimensions and data groupings&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Canonicalization is Google's process for selecting a representative URL among duplicate or very similar pages. It is not a general-purpose fix for every pair of pages that shares a keyword. &lt;a href="https://developers.google.com/search/docs/crawling-indexing/canonicalization" rel="noopener noreferrer"&gt;Google Search Central: canonicalization&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those constraints should make the audit more conservative, not less.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a query-to-page review table in Search Console
&lt;/h2&gt;

&lt;p&gt;Use a date range long enough to reduce noise. Ninety days is a practical starting point for an established site, but compare it with the previous period and check seasonality before treating a movement as structural.&lt;/p&gt;

&lt;p&gt;In the Search results Performance report:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Export query and page performance for Web search.&lt;/li&gt;
&lt;li&gt;Keep clicks, impressions, CTR, and average position.&lt;/li&gt;
&lt;li&gt;Group rows by query.&lt;/li&gt;
&lt;li&gt;Flag queries associated with two or more indexable URLs.&lt;/li&gt;
&lt;li&gt;Exclude navigational queries and obvious sitelink behaviour before prioritizing the queue.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not rely on a single filtered total. Google notes that query or URL filters can change report totals because of anonymized queries and truncation. &lt;a href="https://support.google.com/webmasters/answer/17011165?hl=en" rel="noopener noreferrer"&gt;Search Console filtering limitations&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your first table can be simple:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Query&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Clicks&lt;/th&gt;
&lt;th&gt;Impressions&lt;/th&gt;
&lt;th&gt;Avg. position&lt;/th&gt;
&lt;th&gt;Intended page job&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;seo api for agents&lt;/td&gt;
&lt;td&gt;/seo-api&lt;/td&gt;
&lt;td&gt;126&lt;/td&gt;
&lt;td&gt;3,900&lt;/td&gt;
&lt;td&gt;7.4&lt;/td&gt;
&lt;td&gt;commercial evaluation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seo api for agents&lt;/td&gt;
&lt;td&gt;/blog/best-seo-api-agents&lt;/td&gt;
&lt;td&gt;41&lt;/td&gt;
&lt;td&gt;2,100&lt;/td&gt;
&lt;td&gt;11.8&lt;/td&gt;
&lt;td&gt;comparison and education&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;seo api for agents&lt;/td&gt;
&lt;td&gt;/docs/api-reference&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;440&lt;/td&gt;
&lt;td&gt;18.2&lt;/td&gt;
&lt;td&gt;implementation reference&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This example is illustrative. It shows why URL count alone is weak evidence. All three pages can legitimately mention the query, but only one should usually own its primary search job.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate harmless overlap from harmful competition
&lt;/h2&gt;

&lt;p&gt;Review each flagged cluster against four tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  The pages serve the same intent
&lt;/h3&gt;

&lt;p&gt;Read the pages before changing them. Compare the promised outcome, page type, target reader, funnel stage, and likely next action.&lt;/p&gt;

&lt;p&gt;If one page teaches and another sells, the overlap may be useful. If both pages make the same promise to the same reader, the conflict is more credible.&lt;/p&gt;

&lt;h3&gt;
  
  
  The wrong URL wins or the winner keeps changing
&lt;/h3&gt;

&lt;p&gt;Look for repeated evidence across time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the less useful URL receives most clicks for the target query&lt;/li&gt;
&lt;li&gt;the ranking URL changes between periods&lt;/li&gt;
&lt;li&gt;both pages remain in weak positions instead of one becoming the clear result&lt;/li&gt;
&lt;li&gt;internal links use similar anchors for both pages&lt;/li&gt;
&lt;li&gt;the preferred landing page loses qualified conversions while the other page gains impressions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No single signal proves cannibalization. Together, they justify review.&lt;/p&gt;

&lt;h3&gt;
  
  
  The overlap creates a user or business cost
&lt;/h3&gt;

&lt;p&gt;An informational article outranking a product page is not automatically bad. It becomes a problem when the query has commercial intent and the article cannot help the visitor complete the job.&lt;/p&gt;

&lt;p&gt;Measure the cost that matters: qualified clicks, sign-ups, assisted conversions, or support burden. Rankings without page purpose are not enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  The evidence survives known Search Console limitations
&lt;/h3&gt;

&lt;p&gt;Search Console assigns most performance data to canonical URLs, and some query data is omitted or truncated. A small sample of overlapping rows should not trigger a redirect. Check the live pages, inspect Google's selected canonical where relevant, and review the current SERP before deciding. &lt;a href="https://support.google.com/webmasters/answer/17011259?hl=en" rel="noopener noreferrer"&gt;How Search Console groups page data&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Give the agent structured evidence, not a vague prompt
&lt;/h2&gt;

&lt;p&gt;An agent can compare dozens of page clusters consistently, but only if the input preserves page role and performance context.&lt;/p&gt;

&lt;p&gt;AgentSEO exposes &lt;code&gt;agentseo_content_cannibalization&lt;/code&gt; for this job. The tool accepts page titles, headings, target and ranking queries, page type, canonical URL, indexability, performance, backlinks, and freshness signals. It returns conflicts, page signals, clusters, and a reviewable fix plan.&lt;/p&gt;

&lt;p&gt;Use a prompt like this in an MCP client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use agentseo_content_cannibalization to review these pages for the focus query
"seo api for agents".

Use balanced sensitivity. Treat the supplied Search Console metrics as directional,
not proof of harm. Return:
1. the intended job of each page,
2. whether the pages share the same intent,
3. the preferred primary URL and why,
4. the safest fix,
5. evidence that still needs human verification.

Do not recommend a redirect or canonical solely because two URLs receive impressions.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a REST workflow, the same review can be called directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://www.agentseo.dev/api/v1/content/cannibalization?sync=true"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: YOUR_AGENTSEO_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"content-type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "target": "example.com",
    "focus_keywords": ["seo api for agents"],
    "sensitivity": "balanced",
    "pages": [
      {
        "url": "https://example.com/seo-api",
        "title": "SEO API for AI Agents",
        "headings": ["Live search data for agent workflows"],
        "target_keywords": ["seo api for agents"],
        "ranking_queries": ["seo api for agents", "seo api"],
        "page_type": "product",
        "clicks": 126,
        "impressions": 3900,
        "avg_position": 7.4,
        "indexable": true
      },
      {
        "url": "https://example.com/blog/best-seo-api-agents",
        "title": "How to Evaluate an SEO API for AI Agents",
        "headings": ["The evaluation criteria", "Payload design"],
        "target_keywords": ["best seo api for ai agents"],
        "ranking_queries": ["seo api for agents", "best seo api for ai agents"],
        "page_type": "blog_post",
        "clicks": 41,
        "impressions": 2100,
        "avg_position": 11.8,
        "indexable": true
      }
    ]
  }'&lt;/span&gt; | jq &lt;span class="s1"&gt;'.result.content_cannibalization // .content_cannibalization'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the illustrative values with a consistent Search Console period. Keep the source export beside the result so a reviewer can trace the recommendation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose the fix that matches the page relationship
&lt;/h2&gt;

&lt;p&gt;The audit should end in one of five decisions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Relationship&lt;/th&gt;
&lt;th&gt;Default action&lt;/th&gt;
&lt;th&gt;What gets worse if misused&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Same topic, different intent&lt;/td&gt;
&lt;td&gt;Differentiate titles, headings, copy, and internal anchors&lt;/td&gt;
&lt;td&gt;Forced separation can make both pages less complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One clear primary page with useful support pages&lt;/td&gt;
&lt;td&gt;Reinforce ownership through internal links and navigation&lt;/td&gt;
&lt;td&gt;Over-optimized anchors can make the site feel mechanical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Two pages perform the same job and one adds little unique value&lt;/td&gt;
&lt;td&gt;Consolidate useful material and redirect the weaker URL&lt;/td&gt;
&lt;td&gt;You can lose long-tail coverage or backlinks if the merge is careless&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Duplicate or very similar URL variants&lt;/td&gt;
&lt;td&gt;Use canonicalization or redirects as appropriate&lt;/td&gt;
&lt;td&gt;A canonical can hide a page that deserved separate indexing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overlap without measurable harm&lt;/td&gt;
&lt;td&gt;Leave the pages alone and monitor&lt;/td&gt;
&lt;td&gt;Premature cleanup creates work without improving the search result&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Google describes redirects as a strong canonical signal, &lt;code&gt;rel="canonical"&lt;/code&gt; as another strong signal, and sitemap inclusion as weaker. Signals can reinforce one another, but Google still makes the final canonical choice. &lt;a href="https://developers.google.com/search/docs/crawling-indexing/consolidate-duplicate-urls" rel="noopener noreferrer"&gt;Google Search Central: specifying a canonical URL&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is why a canonical tag should express a genuine duplicate relationship. It should not substitute for deciding what two distinct pages are meant to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make URL ownership visible before creating the next page
&lt;/h2&gt;

&lt;p&gt;Fixing existing conflicts is only half the job. The content process must stop recreating them.&lt;/p&gt;

&lt;p&gt;Maintain a keyword map with one primary URL per search intent. Before approving a new brief, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the primary query and close variants&lt;/li&gt;
&lt;li&gt;the page type and intended reader&lt;/li&gt;
&lt;li&gt;the existing URL that currently owns the intent&lt;/li&gt;
&lt;li&gt;whether the new asset supports, differentiates, or replaces that URL&lt;/li&gt;
&lt;li&gt;which internal links should point to the primary page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AgentSEO's &lt;code&gt;agentseo_content_keyword_map&lt;/code&gt; can map supplied keywords to existing pages and flag weak matches, missing pages, and cannibalization risks before drafting begins. The important output is not another keyword cluster. It is an explicit ownership decision that downstream briefs and agents can follow.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The operator move:&lt;/strong&gt; do not merge the first pair of pages that shares impressions. Assign the intended search job, verify actual harm, then make the smallest change that clarifies ownership.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Re-measure the query after the change
&lt;/h2&gt;

&lt;p&gt;Record the change date, affected URLs, target query, and expected outcome. Then compare a meaningful post-change period against the baseline.&lt;/p&gt;

&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the preferred URL receiving a more stable share of clicks and impressions&lt;/li&gt;
&lt;li&gt;improved qualified conversions for the query cluster&lt;/li&gt;
&lt;li&gt;fewer unwanted ranking-URL changes&lt;/li&gt;
&lt;li&gt;preserved performance for distinct long-tail intents&lt;/li&gt;
&lt;li&gt;Google's selected canonical matching the intended duplicate relationship, where applicable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not claim success from a ranking change alone. Seasonality, SERP changes, competitor updates, and demand shifts can move the same metrics.&lt;/p&gt;

&lt;p&gt;The workflow is deliberately conservative: detect overlap, verify intent, estimate harm, choose a page owner, apply the smallest defensible fix, and monitor the result.&lt;/p&gt;

&lt;p&gt;That is slower than bulk-merging URLs from a spreadsheet.&lt;/p&gt;

&lt;p&gt;It is also much less likely to delete a useful part of your search system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the workflow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.agentseo.dev/docs/workflows" rel="noopener noreferrer"&gt;AgentSEO workflow guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.agentseo.dev/docs/quickstart" rel="noopener noreferrer"&gt;AgentSEO API quickstart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.agentseo.dev/seo-mcp-server" rel="noopener noreferrer"&gt;AgentSEO MCP server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.agentseo.dev/editorial-policy" rel="noopener noreferrer"&gt;AgentSEO Editorial and Evidence Policy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Disclosure: AI tools assisted with research organization, drafting, and editing. Daniel Martin reviewed and approved the topic, claims, workflow, examples, and publication decision.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>seo</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to Do a Competitor Content Gap Analysis Without Copying Competitors</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Tue, 25 Aug 2026 14:56:45 +0000</pubDate>
      <link>https://dev.to/agentseodev/how-to-do-a-competitor-content-gap-analysis-without-copying-competitors-4n3o</link>
      <guid>https://dev.to/agentseodev/how-to-do-a-competitor-content-gap-analysis-without-copying-competitors-4n3o</guid>
      <description>&lt;p&gt;A competitor content gap export is not a content plan.&lt;/p&gt;

&lt;p&gt;It is a list of things other sites rank for.&lt;/p&gt;

&lt;p&gt;That distinction matters. If you send every missing keyword to a writer, you create a backlog shaped by somebody else's business. You also risk publishing new pages for queries an existing page already serves, copying formats that do not fit your audience, and spending weeks on traffic that will never reach the product.&lt;/p&gt;

&lt;p&gt;A useful competitor content gap analysis makes three decisions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;which gaps deserve a new page&lt;/li&gt;
&lt;li&gt;which gaps belong in an existing page&lt;/li&gt;
&lt;li&gt;which gaps should be ignored&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial shows how to make those decisions with search intent, buyer stage, page type, product fit, and current SERP evidence. It also includes a copy-paste AgentSEO request for turning supplied page exports into a prioritized matrix.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;Run the analysis in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define the audience, product boundary, and conversion you care about.&lt;/li&gt;
&lt;li&gt;Select search competitors, not only business competitors.&lt;/li&gt;
&lt;li&gt;Export your pages and competitor pages with queries and useful metrics.&lt;/li&gt;
&lt;li&gt;Group gaps by topic, page type, and buyer stage.&lt;/li&gt;
&lt;li&gt;Check whether each gap is missing coverage, weak coverage, a format gap, or a stage gap.&lt;/li&gt;
&lt;li&gt;Validate the strongest candidates against the live SERP and your existing URLs.&lt;/li&gt;
&lt;li&gt;Send accepted candidates to a new-page brief or refresh brief.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The final output should be a short action queue. A 4,000-row spreadsheet is research material, not a strategy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with a boundary competitors cannot choose for you
&lt;/h2&gt;

&lt;p&gt;Before collecting competitor keywords, write this sentence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We want to attract [specific audience] who need to [specific job],
and the useful next step is [product-relevant conversion].
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For AgentSEO, one version is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;We want to attract growth engineers and technical marketers who need to
turn search data into repeatable agent workflows, and the useful next step
is to run a workflow through the API or playground.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This boundary removes plenty of tempting but irrelevant gaps.&lt;/p&gt;

&lt;p&gt;A large SEO platform may rank for social media calendars, email templates, or general marketing definitions. Those keywords may have demand. They are still poor candidates for an agent-native SEO intelligence API unless they support a credible workflow and conversion path.&lt;/p&gt;

&lt;p&gt;Google's people-first content guidance asks whether a site has an intended audience, demonstrates first-hand expertise, and leaves readers feeling they learned enough to achieve their goal. It also warns against producing content across many topics merely in the hope that some of it performs. That makes audience and task fit useful filters before volume or difficulty enters the queue. &lt;a href="https://developers.google.com/search/docs/fundamentals/creating-helpful-content" rel="noopener noreferrer"&gt;Read Google's people-first content guidance&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose competitors from the SERP, not the sales deck
&lt;/h2&gt;

&lt;p&gt;Your commercial competitors and search competitors are not always the same.&lt;/p&gt;

&lt;p&gt;Use three groups:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Competitor type&lt;/th&gt;
&lt;th&gt;What it reveals&lt;/th&gt;
&lt;th&gt;Main risk&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Direct product competitor&lt;/td&gt;
&lt;td&gt;Commercial topics, comparisons, use cases&lt;/td&gt;
&lt;td&gt;Copying their positioning instead of yours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SERP competitor&lt;/td&gt;
&lt;td&gt;Formats and pages winning the target queries&lt;/td&gt;
&lt;td&gt;Treating an unrelated publisher as a business model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audience competitor&lt;/td&gt;
&lt;td&gt;Questions your buyers ask before or after purchase&lt;/td&gt;
&lt;td&gt;Expanding beyond the product's credible boundary&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Start with two or three domains that repeatedly appear for queries your audience owns. Add a direct competitor when it provides a useful commercial comparison, even if it does not dominate the same informational results.&lt;/p&gt;

&lt;p&gt;Do not select a competitor because its estimated traffic is large. A broad publisher can create thousands of apparent gaps that have no product fit.&lt;/p&gt;

&lt;p&gt;Recent practitioner discussions show why this step causes trouble. One r/seogrowth thread asks how smaller sites should map competitor content without blindly following larger domains. Another discussion about crawling competitor sites focuses on turning page structure and query data into briefs, but questions how accurately automation can identify meaningful gaps. These are directional community observations, not evidence of a ranking factor. &lt;a href="https://www.reddit.com/r/seogrowth/comments/1qnf93z/how_do_you_figure_out_what_content_topics_to/" rel="noopener noreferrer"&gt;Read the competitor-selection discussion&lt;/a&gt; and &lt;a href="https://www.reddit.com/r/n8n_ai_agents/comments/1t38u6x/built_an_ai_seo_content_gap_analyzer_in_n8n_auto/" rel="noopener noreferrer"&gt;the automation discussion&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Collect page-level inputs, not keywords in isolation
&lt;/h2&gt;

&lt;p&gt;A keyword-only export hides the decision context.&lt;/p&gt;

&lt;p&gt;For each owned and competitor page, collect what you can from this list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URL and title&lt;/li&gt;
&lt;li&gt;ranking queries or assigned keywords&lt;/li&gt;
&lt;li&gt;likely page type&lt;/li&gt;
&lt;li&gt;likely buyer stage&lt;/li&gt;
&lt;li&gt;estimated traffic and search volume&lt;/li&gt;
&lt;li&gt;average position&lt;/li&gt;
&lt;li&gt;backlinks or referring-domain signal&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Page type and buyer stage are especially useful. They expose gaps that a flat keyword comparison misses.&lt;/p&gt;

&lt;p&gt;Imagine competitors cover &lt;code&gt;SEO API template&lt;/code&gt; with an implementation template while your only matching asset is a high-level API guide. You do not have a completely missing topic. You may have a format or implementation-stage gap.&lt;/p&gt;

&lt;p&gt;Now imagine you already have a guide ranking for the same query, but it is weaker than the competing pages. The likely action is to inspect and refresh that URL, not create another guide and manufacture cannibalization.&lt;/p&gt;

&lt;p&gt;Treat third-party traffic, volume, difficulty, and backlink numbers as estimates. They help sort the work; they do not prove that a page will rank, convert, or deserve production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Classify every gap before scoring it
&lt;/h2&gt;

&lt;p&gt;Use four practical gap types.&lt;/p&gt;

&lt;h3&gt;
  
  
  Missing topic
&lt;/h3&gt;

&lt;p&gt;Competitors cover a relevant topic and no supplied owned page clearly matches it.&lt;/p&gt;

&lt;p&gt;Possible action: validate the SERP and create a new page only if the audience, intent, and conversion path fit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Weak coverage
&lt;/h3&gt;

&lt;p&gt;An owned page matches the topic, but the supplied performance or coverage signals are weaker.&lt;/p&gt;

&lt;p&gt;Possible action: compare the live pages, check Search Console, and create a focused refresh brief.&lt;/p&gt;

&lt;h3&gt;
  
  
  Format gap
&lt;/h3&gt;

&lt;p&gt;You cover the topic, but the useful competing format differs. Your article may face templates, tools, comparison pages, or documentation.&lt;/p&gt;

&lt;p&gt;Possible action: decide whether the format genuinely helps the reader. Do not convert a guide into a tool merely because one tool ranks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Buyer-stage gap
&lt;/h3&gt;

&lt;p&gt;Your coverage serves awareness while competitors answer consideration, decision, or implementation questions.&lt;/p&gt;

&lt;p&gt;Possible action: add the missing decision support when it belongs on an existing page, or brief a distinct asset when the search task and conversion are genuinely different.&lt;/p&gt;

&lt;p&gt;This classification prevents the most expensive mistake in gap analysis: assuming that every difference requires another URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a matrix that forces an action decision
&lt;/h2&gt;

&lt;p&gt;Create a table with one row per normalized topic.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Topic&lt;/th&gt;
&lt;th&gt;Gap type&lt;/th&gt;
&lt;th&gt;Page type&lt;/th&gt;
&lt;th&gt;Buyer stage&lt;/th&gt;
&lt;th&gt;Existing match&lt;/th&gt;
&lt;th&gt;Product fit&lt;/th&gt;
&lt;th&gt;SERP validated&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SEO API templates&lt;/td&gt;
&lt;td&gt;Format gap&lt;/td&gt;
&lt;td&gt;Template&lt;/td&gt;
&lt;td&gt;Implementation&lt;/td&gt;
&lt;td&gt;API guide&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Pending&lt;/td&gt;
&lt;td&gt;Validate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Generic marketing plan&lt;/td&gt;
&lt;td&gt;Missing topic&lt;/td&gt;
&lt;td&gt;Guide&lt;/td&gt;
&lt;td&gt;Awareness&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Ignore&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SEO API comparison&lt;/td&gt;
&lt;td&gt;Weak coverage&lt;/td&gt;
&lt;td&gt;Comparison&lt;/td&gt;
&lt;td&gt;Consideration&lt;/td&gt;
&lt;td&gt;Comparison page&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Refresh&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The important columns are near the end. A high gap score can still produce &lt;code&gt;Ignore&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Use the following action rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;New page:&lt;/strong&gt; no same-intent page exists, product fit is clear, and the current SERP supports the proposed task and format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Refresh:&lt;/strong&gt; an existing URL serves substantially the same intent and can be made more complete, useful, or current.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Differentiate:&lt;/strong&gt; the topic overlaps, but a different audience task or buyer stage deserves deliberate separation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ignore:&lt;/strong&gt; the query lacks audience fit, product fit, a credible conversion, or a useful angle AgentSEO can support.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Google says its systems prioritize helpful, reliable content created to benefit people. Its guidance does not grant value to a page merely because competitors have one. &lt;a href="https://developers.google.com/search/docs/fundamentals/creating-helpful-content" rel="noopener noreferrer"&gt;Review Google's guidance&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn supplied exports into an AgentSEO gap matrix
&lt;/h2&gt;

&lt;p&gt;AgentSEO's competitor gap matrix accepts owned pages and competitor pages, then groups the supplied evidence by topic, page type, and buyer stage.&lt;/p&gt;

&lt;p&gt;Here is a minimal reproducible request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://www.agentseo.dev/api/v1/content/competitor-gap-matrix?sync=true"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: sk_live_REPLACE_ME"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "target": "AgentSEO",
    "focus_topics": ["seo api templates"],
    "own_pages": [
      {
        "url": "https://www.agentseo.dev/docs/api-reference",
        "title": "AgentSEO API Reference",
        "keywords": ["seo api"],
        "ranking_queries": ["seo api docs"],
        "page_type": "docs",
        "buyer_stage": "implementation"
      }
    ],
    "competitors": [
      {
        "domain": "competitor.example",
        "pages": [
          {
            "url": "https://competitor.example/templates/seo-api-template",
            "title": "SEO API Template Library",
            "keywords": ["seo api templates", "seo workflow template"],
            "ranking_queries": ["seo api templates"],
            "page_type": "template",
            "buyer_stage": "implementation",
            "estimated_traffic": 500,
            "search_volume": 900,
            "avg_position": 4,
            "backlinks": 8
          }
        ]
      }
    ],
    "max_opportunities": 10
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace the example domain and estimates with your own exports. The endpoint returns prioritized opportunities, matching owned URLs, competitor coverage, suggested page types, buyer stages, next endpoints, a matrix, and explicit limitations.&lt;/p&gt;

&lt;p&gt;At the time of writing, the request costs three AgentSEO credits and does not call a paid SERP provider. Verify current behavior and pricing in the &lt;a href="https://www.agentseo.dev/docs/api-reference" rel="noopener noreferrer"&gt;AgentSEO API reference&lt;/a&gt; before production use.&lt;/p&gt;

&lt;p&gt;The result is a triage layer, not an instruction to publish. The endpoint uses the data you supply. It does not crawl the full web or verify current rankings, and its scores are sorting inputs rather than forecasts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate the top candidates against current search reality
&lt;/h2&gt;

&lt;p&gt;Do not validate every row. Validate the small group you might actually produce.&lt;/p&gt;

&lt;p&gt;For each candidate, inspect the current SERP and answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the query mean what the export suggests?&lt;/li&gt;
&lt;li&gt;Which page types are visible now?&lt;/li&gt;
&lt;li&gt;Is intent mixed across guides, tools, products, videos, or discussions?&lt;/li&gt;
&lt;li&gt;Does an existing owned URL already satisfy the task?&lt;/li&gt;
&lt;li&gt;Can you add real proof, a working template, data, screenshots, or a better workflow?&lt;/li&gt;
&lt;li&gt;Is there a natural next step into the product?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Search Console can then check owned-page reality. Filter the Performance report by query and page to see clicks, impressions, position, and the URLs currently receiving visibility. Google notes that Performance data is subject to processing and privacy limitations, so use it as observed site evidence rather than a complete record of every query. &lt;a href="https://developers.google.com/search/blog/2022/10/performance-data-deep-dive" rel="noopener noreferrer"&gt;Read Google's Performance data guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If one owned page already receives impressions for the topic, investigate that page before approving a new URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automate sorting, not editorial judgment
&lt;/h2&gt;

&lt;p&gt;Automation is good at repetitive comparison:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;owned page export + competitor page exports
                       ↓
normalize topics, page types, and buyer stages
                       ↓
classify and score gaps
                       ↓
human validates audience, intent, proof, and conversion
                       ↓
new-page brief, refresh brief, differentiate, or ignore
                       ↓
human edits and approves publication
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keep the human gate where context changes the decision.&lt;/p&gt;

&lt;p&gt;An agent can identify that three competitors have template pages. It cannot infer that your team has original template data, implementation experience, permission to make a product claim, or capacity to maintain the asset. Those constraints determine whether the gap is real for your business.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common failure modes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Chasing every competitor-exclusive keyword
&lt;/h3&gt;

&lt;p&gt;Competitor exclusivity tells you only that another domain ranks and yours does not. Filter for audience, product, intent, and conversion fit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparing only direct competitors
&lt;/h3&gt;

&lt;p&gt;Direct competitors reveal commercial positioning. SERP competitors reveal what currently satisfies the query. You need both views.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a new page when one already owns the intent
&lt;/h3&gt;

&lt;p&gt;Check Search Console and the existing site before briefing. Refreshing a relevant URL is often cleaner than adding another overlapping page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Copying the ranking format without checking its usefulness
&lt;/h3&gt;

&lt;p&gt;A dominant format is evidence, not a command. Use a template, video, or tool only when it improves task completion and you can execute it credibly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Treating a score as predicted traffic
&lt;/h3&gt;

&lt;p&gt;Gap scores compress supplied signals for prioritization. They cannot establish ranking probability, click-through rate, conversion rate, or business value.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asking an LLM to invent the missing expertise
&lt;/h3&gt;

&lt;p&gt;If the accepted gap requires benchmark data, customer evidence, product screenshots, or implementation experience, collect it. Fluent text is not a substitute for proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  The publication gate is deliberately small
&lt;/h2&gt;

&lt;p&gt;Approve a gap only when you can answer yes to all five questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does a named AgentSEO audience own this job?&lt;/li&gt;
&lt;li&gt;Does the current SERP support the intended task and page type?&lt;/li&gt;
&lt;li&gt;Is there no stronger same-intent owned URL to refresh?&lt;/li&gt;
&lt;li&gt;Can the page add original proof, experience, or a better working asset?&lt;/li&gt;
&lt;li&gt;Is the next product step useful rather than forced?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If one answer is no, the right decision may be to refresh, differentiate, or ignore.&lt;/p&gt;

&lt;p&gt;That is the point of the workflow. Competitor research should reduce the content queue, not inflate it.&lt;/p&gt;

&lt;p&gt;AgentSEO can turn supplied page exports into a buyer-stage gap matrix, then route accepted opportunities into a &lt;a href="https://www.agentseo.dev/docs/workflows" rel="noopener noreferrer"&gt;content brief or refresh workflow&lt;/a&gt;. Start with the &lt;a href="https://www.agentseo.dev/docs/quickstart" rel="noopener noreferrer"&gt;API quickstart&lt;/a&gt; if you want to make the analysis repeatable through REST or an agent.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: This draft was prepared with AI assistance for research organization, drafting, and editing. Daniel Martin should review the claims, examples, links, product details, and final publication decision.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>seo</category>
      <category>tutorial</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to Create an SEO Content Brief From Live SERP Data</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Mon, 24 Aug 2026 10:37:53 +0000</pubDate>
      <link>https://dev.to/agentseodev/how-to-create-an-seo-content-brief-from-live-serp-data-5d8n</link>
      <guid>https://dev.to/agentseodev/how-to-create-an-seo-content-brief-from-live-serp-data-5d8n</guid>
      <description>&lt;p&gt;A keyword, a word count, and a list of competitor headings is not an SEO content brief.&lt;/p&gt;

&lt;p&gt;It is a request for the writer to reverse-engineer the strategy.&lt;/p&gt;

&lt;p&gt;That usually produces one of two drafts: a generic article that covers everything around the topic, or a close imitation of the pages already ranking. Both can look complete in a document while failing the actual job of the page.&lt;/p&gt;

&lt;p&gt;A useful brief makes five decisions before anyone drafts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;who the page is for&lt;/li&gt;
&lt;li&gt;what the searcher needs to do or decide&lt;/li&gt;
&lt;li&gt;which page type fits the current result set&lt;/li&gt;
&lt;li&gt;what this page will add that competing pages do not&lt;/li&gt;
&lt;li&gt;what evidence must exist before a claim can ship&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial shows how to make those decisions from live SERP evidence, turn them into a writer-ready template, and preserve a human review gate when an AI agent helps with the research.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;Build the brief in this order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define the page job and target reader.&lt;/li&gt;
&lt;li&gt;Inspect the live SERP for intent, format, features, and competing angles.&lt;/li&gt;
&lt;li&gt;Separate required coverage from opportunities to differentiate.&lt;/li&gt;
&lt;li&gt;Specify proof, sources, internal links, and the conversion path.&lt;/li&gt;
&lt;li&gt;Give the writer an outline with decisions, not a keyword checklist.&lt;/li&gt;
&lt;li&gt;Validate the finished draft against the brief and the current SERP.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The output should be specific enough that a writer does not need to repeat the SEO research, but open enough that they can still make the article useful and original.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with the page job, not the outline
&lt;/h2&gt;

&lt;p&gt;The same keyword can support several superficially plausible pages.&lt;/p&gt;

&lt;p&gt;Take &lt;code&gt;SEO content brief template&lt;/code&gt;. You could publish a definition, a downloadable template, a step-by-step tutorial, a software landing page, or a comparison of briefing tools. Those formats do not serve the same reader or buyer stage.&lt;/p&gt;

&lt;p&gt;Before opening the SERP, write one sentence:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This page helps [specific reader] do or decide [specific job]
after searching [target query], and the useful next step is [conversion].
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this article, that sentence is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This page helps technical marketers build a repeatable SEO content brief
from current search evidence, and the useful next step is to run the workflow
manually or with an SEO agent.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This constraint prevents a common briefing failure: adding every related topic until a focused tutorial becomes an unfocused guide.&lt;/p&gt;

&lt;p&gt;Google's people-first content guidance asks whether a site has an intended audience, whether a reader will learn enough to achieve their goal, and whether the content adds original information or analysis. It also states that Google does not have a preferred word count. That makes audience, task completion, and added value stronger briefing inputs than a copied competitor average. &lt;a href="https://developers.google.com/search/docs/fundamentals/creating-helpful-content" rel="noopener noreferrer"&gt;Read Google's people-first content guidance&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read the live SERP as evidence, not as an outline to copy
&lt;/h2&gt;

&lt;p&gt;The result page helps answer four different questions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;SERP observation&lt;/th&gt;
&lt;th&gt;Decision it supports&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dominant intent&lt;/td&gt;
&lt;td&gt;What the searcher is trying to accomplish&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dominant page type&lt;/td&gt;
&lt;td&gt;Whether the page should be a guide, comparison, tool, landing page, or something else&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repeated useful coverage&lt;/td&gt;
&lt;td&gt;What a credible page probably needs to address&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weak or missing coverage&lt;/td&gt;
&lt;td&gt;Where the new page can add something distinct&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Review at least the leading relevant results, but do not treat every ranking URL as a model. A marketplace page, video, forum thread, product result, and editorial guide may coexist because the query has mixed intent.&lt;/p&gt;

&lt;p&gt;Record what is visible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;result type and page format&lt;/li&gt;
&lt;li&gt;likely audience and buyer stage&lt;/li&gt;
&lt;li&gt;title promise&lt;/li&gt;
&lt;li&gt;questions answered&lt;/li&gt;
&lt;li&gt;proof used: examples, screenshots, data, templates, or expert review&lt;/li&gt;
&lt;li&gt;freshness requirements&lt;/li&gt;
&lt;li&gt;SERP features such as videos, discussions, snippets, or an AI Overview&lt;/li&gt;
&lt;li&gt;obvious gaps or repeated weaknesses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last two fields matter. A brief that only records what competitors include can produce a competent clone. The brief needs a reason for this page to exist.&lt;/p&gt;

&lt;p&gt;Recent community discussions expose the same tension. One r/SEO commenter described useful brief fields such as goal, persona, pain point, target keyword, format, metadata, and outline. A newer discussion pushed back on keyword-checklist briefs and argued that writers also need the reader's problem, the decision the page should enable, what current results miss, and natural internal-link opportunities. Treat these as practitioner observations, not ranking factors. &lt;a href="https://www.reddit.com/r/SEO/comments/183t9ab/" rel="noopener noreferrer"&gt;See the r/SEO production-framework discussion&lt;/a&gt; and &lt;a href="https://www.reddit.com/r/SEO_Xpert/comments/1v5k5b5/content_brief_that_helps_rank_faster/" rel="noopener noreferrer"&gt;the content-brief critique&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn observations into three buckets
&lt;/h2&gt;

&lt;p&gt;Do not paste raw research into the writer's document. Classify it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Required coverage
&lt;/h3&gt;

&lt;p&gt;These are questions a reader reasonably expects the page to answer. Missing them would make the page incomplete for its stated job.&lt;/p&gt;

&lt;p&gt;For an SEO content brief tutorial, required coverage might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;audience and page goal&lt;/li&gt;
&lt;li&gt;primary query and intent&lt;/li&gt;
&lt;li&gt;page type&lt;/li&gt;
&lt;li&gt;title and metadata direction&lt;/li&gt;
&lt;li&gt;recommended sections&lt;/li&gt;
&lt;li&gt;internal links&lt;/li&gt;
&lt;li&gt;sources and proof&lt;/li&gt;
&lt;li&gt;draft QA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Required does not mean “every competitor has an H2 with this phrase.” It means the information helps the intended reader complete the task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Differentiation opportunities
&lt;/h3&gt;

&lt;p&gt;These are useful additions that the current results handle weakly or not at all.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a copy-paste brief template&lt;/li&gt;
&lt;li&gt;a real API or MCP workflow&lt;/li&gt;
&lt;li&gt;explicit failure modes&lt;/li&gt;
&lt;li&gt;a proof-requirements field instead of vague E-E-A-T advice&lt;/li&gt;
&lt;li&gt;a pre-publish validation gate&lt;/li&gt;
&lt;li&gt;a decision rule for mixed-intent SERPs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write one differentiation sentence in the brief:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Unlike generic templates, this page shows how to convert live SERP observations
into coverage, differentiation, and proof decisions, then validate the draft.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you cannot complete that sentence without adjectives, the idea probably needs more research.&lt;/p&gt;

&lt;h3&gt;
  
  
  Exclusions
&lt;/h3&gt;

&lt;p&gt;Good briefs also say what the page should not become.&lt;/p&gt;

&lt;p&gt;For this topic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;do not promise rankings&lt;/li&gt;
&lt;li&gt;do not prescribe keyword density&lt;/li&gt;
&lt;li&gt;do not copy competitor headings&lt;/li&gt;
&lt;li&gt;do not invent a universal word count&lt;/li&gt;
&lt;li&gt;do not turn the tutorial into a list of content-optimization tools&lt;/li&gt;
&lt;li&gt;do not let an agent publish without editorial review&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Exclusions reduce revision time because they define the edges of the assignment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use a brief template that carries decisions
&lt;/h2&gt;

&lt;p&gt;The following template is deliberately prose-first. It gives the writer context and constraints without writing the article for them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# SEO content brief&lt;/span&gt;

&lt;span class="gu"&gt;## Assignment&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Working title:
&lt;span class="p"&gt;-&lt;/span&gt; Primary query:
&lt;span class="p"&gt;-&lt;/span&gt; Target location and device:
&lt;span class="p"&gt;-&lt;/span&gt; Intended reader:
&lt;span class="p"&gt;-&lt;/span&gt; Reader's job to be done:
&lt;span class="p"&gt;-&lt;/span&gt; Business goal and next step:
&lt;span class="p"&gt;-&lt;/span&gt; Page type:
&lt;span class="p"&gt;-&lt;/span&gt; Search intent:

&lt;span class="gu"&gt;## SERP evidence&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Checked at:
&lt;span class="p"&gt;-&lt;/span&gt; Dominant result types:
&lt;span class="p"&gt;-&lt;/span&gt; Important SERP features:
&lt;span class="p"&gt;-&lt;/span&gt; Repeated questions or expectations:
&lt;span class="p"&gt;-&lt;/span&gt; Competing angles:
&lt;span class="p"&gt;-&lt;/span&gt; Evidence used by current results:
&lt;span class="p"&gt;-&lt;/span&gt; Mixed-intent or freshness risks:

&lt;span class="gu"&gt;## Editorial direction&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; One-sentence angle:
&lt;span class="p"&gt;-&lt;/span&gt; What this page must cover:
&lt;span class="p"&gt;-&lt;/span&gt; What this page should add:
&lt;span class="p"&gt;-&lt;/span&gt; What to exclude:
&lt;span class="p"&gt;-&lt;/span&gt; Tone and assumed reader knowledge:

&lt;span class="gu"&gt;## Proof requirements&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Claims that need first-party evidence:
&lt;span class="p"&gt;-&lt;/span&gt; Claims that need authoritative sources:
&lt;span class="p"&gt;-&lt;/span&gt; Example, command, screenshot, or dataset required:
&lt;span class="p"&gt;-&lt;/span&gt; Limitations or uncertainty to disclose:

&lt;span class="gu"&gt;## Structure&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; H1:
&lt;span class="p"&gt;-&lt;/span&gt; Opening tension:
&lt;span class="p"&gt;-&lt;/span&gt; Recommended H2/H3 outline:
&lt;span class="p"&gt;-&lt;/span&gt; Questions that need direct answers:
&lt;span class="p"&gt;-&lt;/span&gt; Pattern interrupt or decision frame:
&lt;span class="p"&gt;-&lt;/span&gt; Conclusion action:

&lt;span class="gu"&gt;## Page elements&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Meta-description direction:
&lt;span class="p"&gt;-&lt;/span&gt; Internal links and suggested context:
&lt;span class="p"&gt;-&lt;/span&gt; External sources:
&lt;span class="p"&gt;-&lt;/span&gt; Image or diagram brief:
&lt;span class="p"&gt;-&lt;/span&gt; Schema candidate, if supported by visible content:

&lt;span class="gu"&gt;## Review gate&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Does the draft satisfy the reader's job?
&lt;span class="p"&gt;-&lt;/span&gt; Does it match the intended page type and current intent?
&lt;span class="p"&gt;-&lt;/span&gt; Does it add value beyond the sampled results?
&lt;span class="p"&gt;-&lt;/span&gt; Are material claims supported and limitations explicit?
&lt;span class="p"&gt;-&lt;/span&gt; Are links useful and natural?
&lt;span class="p"&gt;-&lt;/span&gt; Has a human reviewed the final judgment?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice what is missing: a mandatory keyword density and an arbitrary instruction to write 2,000 words. The writer has a job, evidence, and boundaries instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let an agent collect evidence without handing it editorial control
&lt;/h2&gt;

&lt;p&gt;An agent is useful for repetitive parts of the workflow: reading result patterns, grouping questions, formatting a brief, and checking whether a draft missed an agreed requirement.&lt;/p&gt;

&lt;p&gt;It should not silently make irreversible editorial decisions.&lt;/p&gt;

&lt;p&gt;A safe workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;target query + reader + page job
                ↓
live SERP evidence
                ↓
agent proposes intent, format, expectations, gaps, and brief
                ↓
human approves the angle, proof requirements, exclusions, and conversion path
                ↓
writer drafts
                ↓
agent checks the draft against the approved brief and current SERP
                ↓
human edits and publishes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With AgentSEO's REST API, a brief request can be expressed as one reproducible call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://www.agentseo.dev/api/v1/content/brief?sync=true"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"x-api-key: sk_live_REPLACE_ME"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "keyword": "how to create an SEO content brief",
    "target": "AgentSEO",
    "audience": "technical marketers and growth engineers",
    "location": "United States",
    "device": "desktop",
    "brand_voice": "expert",
    "page_type": "guide",
    "brief_depth": "detailed",
    "include_serp_outline": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The endpoint is designed to return audience guidance, metadata, SERP expectations, competitor patterns, differentiators, proof requirements, a conversion plan, a QA checklist, and an optional outline. It costs six AgentSEO credits at the time of writing. Verify current parameters and pricing in the &lt;a href="https://www.agentseo.dev/docs/api-reference" rel="noopener noreferrer"&gt;AgentSEO API reference&lt;/a&gt; before building the call into production.&lt;/p&gt;

&lt;p&gt;If you use MCP in Claude Code, Codex, or another compatible client, ask for the same boundaries explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use AgentSEO to create a detailed content brief for
"how to create an SEO content brief" in the United States.

Audience: technical marketers and growth engineers.
Page type: guide.

Return:
1. dominant intent and page-format evidence,
2. required coverage,
3. differentiation opportunities,
4. proof requirements,
5. exclusions,
6. a writer-ready outline,
7. internal-link opportunities,
8. risks that need human review.

Do not draft or publish the article.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last instruction matters. Brief creation and article approval are different permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review the brief before the writer sees it
&lt;/h2&gt;

&lt;p&gt;An automatically generated brief can sound decisive while resting on weak evidence. Review it for four failure modes.&lt;/p&gt;

&lt;h3&gt;
  
  
  The SERP is mixed
&lt;/h3&gt;

&lt;p&gt;If the result set contains several page types, do not average them into a hybrid page. Choose the reader and job that best fit your product, then record the competing intent as a risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  The outline is a competitor collage
&lt;/h3&gt;

&lt;p&gt;Repeated headings may reveal expected coverage. They do not justify copying another publisher's structure. Rebuild the outline around the reader's sequence: what they need to understand, decide, do, and verify.&lt;/p&gt;

&lt;h3&gt;
  
  
  The brief confuses coverage with proof
&lt;/h3&gt;

&lt;p&gt;“Discuss how automation saves time” is coverage. It is not evidence.&lt;/p&gt;

&lt;p&gt;A proof requirement would say:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If the article claims time savings, provide a dated test with the manual baseline,
automated workflow, sample size, measurement unit, and limitations.
Otherwise remove the quantitative claim.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The brief optimizes the snippet but forgets the page
&lt;/h3&gt;

&lt;p&gt;Titles matter, but Google generates title links automatically from multiple signals, including the page title, prominent headings, and other page text. Write a descriptive title that matches the page; do not treat one suggested title as a guaranteed SERP output. &lt;a href="https://developers.google.com/search/docs/appearance/title-link" rel="noopener noreferrer"&gt;See Google's title-link documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate the draft against the agreement
&lt;/h2&gt;

&lt;p&gt;The final check is not “Did the writer use every keyword?”&lt;/p&gt;

&lt;p&gt;Use this review order:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Task completion:&lt;/strong&gt; Can the intended reader now do or decide the promised job?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intent and format:&lt;/strong&gt; Does the draft still fit the target query's current result set?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Original value:&lt;/strong&gt; Is the differentiating element present and useful?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Evidence:&lt;/strong&gt; Are important claims sourced, demonstrated, or qualified?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structure:&lt;/strong&gt; Can a scanning reader find the direct answer and next step?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Links:&lt;/strong&gt; Do internal links move the reader to a relevant deeper action?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Restraint:&lt;/strong&gt; Did the draft avoid the exclusions in the approved brief?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;An agent can flag gaps. A human still needs to decide whether the page is accurate, useful, appropriately differentiated, and ready to represent the company.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The brief is successful when the writer no longer has to guess at strategy—and still has room to write.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Start with one page you already plan to publish. Write the page-job sentence, inspect the live SERP, and fill only the fields you can support. If the angle or proof requirement is still vague, do more research before generating prose.&lt;/p&gt;

&lt;p&gt;AgentSEO can supply the live SERP and structured briefing steps through REST or MCP. See the &lt;a href="https://www.agentseo.dev/docs/workflows" rel="noopener noreferrer"&gt;workflow guide&lt;/a&gt;, &lt;a href="https://www.agentseo.dev/docs/api-reference" rel="noopener noreferrer"&gt;API reference&lt;/a&gt;, or &lt;a href="https://www.agentseo.dev/seo-mcp-server" rel="noopener noreferrer"&gt;SEO MCP server guide&lt;/a&gt; when you are ready to make the process repeatable.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: AI assisted with research organization, drafting, and cover-image creation. Daniel Martin reviewed and approved the editorial direction and publication decision.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>tutorial</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to Catch MCP Tool Schema Drift Before an Agent Calls Production</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Sat, 22 Aug 2026 17:04:06 +0000</pubDate>
      <link>https://dev.to/agentseodev/how-to-catch-mcp-tool-schema-drift-before-an-agent-calls-production-5698</link>
      <guid>https://dev.to/agentseodev/how-to-catch-mcp-tool-schema-drift-before-an-agent-calls-production-5698</guid>
      <description>&lt;p&gt;&lt;em&gt;Editorial illustration. It explains the concept; it is not experimental evidence.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An MCP server can pass a happy-path demo and still ship a contract change that makes an agent less predictable. A tool name gains a space. An &lt;code&gt;inputSchema&lt;/code&gt; disappears during a refactor. A generated list comes back in a different order than the build you reviewed.&lt;/p&gt;

&lt;p&gt;The hard part is not writing another unit test. It is deciding what must stay stable before an agent is allowed to discover tools that can touch a real system.&lt;/p&gt;

&lt;p&gt;My recommendation is small: validate each tool declaration structurally, then keep a reviewed snapshot of the ordered tool surface. The snapshot is not a substitute for integration tests or human approval. It is a cheap tripwire for a class of deployment drift that ordinary handler tests often miss.&lt;/p&gt;

&lt;p&gt;The current MCP tools specification says a tool has a unique name and an &lt;code&gt;inputSchema&lt;/code&gt;, and it recommends a deterministic tool order so clients can cache tool lists reliably. It also calls for a human to be able to deny tool invocations. &lt;a href="https://modelcontextprotocol.io/specification/draft/server/tools" rel="noopener noreferrer"&gt;MCP Tools specification&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fltb4kvla9you5paga57s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fltb4kvla9you5paga57s.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The gate I would put before deployment
&lt;/h2&gt;

&lt;p&gt;Run this after generating or assembling your server's &lt;code&gt;tools/list&lt;/code&gt; output, not only against TypeScript types. It checks the payload an MCP client will actually see.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;toolName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Za-z0-9_.-&lt;/span&gt;&lt;span class="se"&gt;]{1,128}&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;assertToolContract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Tool&lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="nx"&gt;approvedNames&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tool&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;toolName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Invalid MCP tool name: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputSchema&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputSchema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;object&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Tool &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; needs an object-root inputSchema`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tools&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;approvedNames&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Tool surface changed: review the ordered tools/list snapshot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This deliberately does not decide whether a tool is &lt;em&gt;safe&lt;/em&gt;. It only makes a declared interface change visible. Authorization, output validation, test data, rate limits, and human approval still need their own controls.&lt;/p&gt;

&lt;h2&gt;
  
  
  A controlled drift study
&lt;/h2&gt;

&lt;p&gt;I generated 240 synthetic three-tool server surfaces, then applied five deliberate mutations to each one: a name containing a space, a missing schema, a &lt;code&gt;null&lt;/code&gt; schema, an array-root schema, and a changed tool order. That produced 1,200 injected contract changes.&lt;/p&gt;

&lt;p&gt;The study compares two checks:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;th&gt;Caught&lt;/th&gt;
&lt;th&gt;Missed&lt;/th&gt;
&lt;th&gt;What it misses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basic name + schema check&lt;/td&gt;
&lt;td&gt;960 / 1,200 (80%)&lt;/td&gt;
&lt;td&gt;240&lt;/td&gt;
&lt;td&gt;Order-only drift&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Basic check + ordered snapshot&lt;/td&gt;
&lt;td&gt;1,200 / 1,200 (100%)&lt;/td&gt;
&lt;td&gt;0 in this study&lt;/td&gt;
&lt;td&gt;Semantic or runtime problems&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Evidence image generated from the saved deterministic study output. It is a synthetic mutation study, not production telemetry.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The result is not surprising once you define the test: the basic check was not designed to flag order changes. That is exactly the point. If order matters to your clients, deployment review needs to compare it. If it does not, omit that rule and say so explicitly.&lt;/p&gt;

&lt;p&gt;The complete method, seed, rows, and limitations are included with this draft in &lt;code&gt;research/mcp-contract-drift-2026-08-22/&lt;/code&gt;. Rerun it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node scripts/run-mcp-contract-drift-study.mjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why an ordered snapshot can be useful
&lt;/h2&gt;

&lt;p&gt;MCP does not turn list order into a universal correctness rule. A client can choose its own behavior. But deterministic declarations reduce accidental churn in a few practical places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;build reviews become smaller because a real surface change is visible;&lt;/li&gt;
&lt;li&gt;cached prompts or tool registries do not receive a different ordering for the same server build;&lt;/li&gt;
&lt;li&gt;a generated tool list cannot quietly add, remove, or rename an operation without a reviewer seeing the diff.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The specification explicitly recommends deterministic ordering when the underlying set has not changed. Treat that as an operational affordance, not a security guarantee. &lt;a href="https://modelcontextprotocol.io/specification/draft/server/tools" rel="noopener noreferrer"&gt;MCP Tools specification&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep structural drift separate from behavior drift
&lt;/h2&gt;

&lt;p&gt;One common mistake is to call all of this “MCP testing.” It is only one layer.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Example evidence&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Contract&lt;/td&gt;
&lt;td&gt;Did the client-facing declaration change?&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;tools/list&lt;/code&gt; snapshot and schema check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Handler&lt;/td&gt;
&lt;td&gt;Does the tool reject invalid input safely?&lt;/td&gt;
&lt;td&gt;unit tests with invalid payloads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integration&lt;/td&gt;
&lt;td&gt;Does the server negotiate and serve the intended tool?&lt;/td&gt;
&lt;td&gt;protocol session test&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authorization&lt;/td&gt;
&lt;td&gt;Can the caller perform only allowed actions?&lt;/td&gt;
&lt;td&gt;scope and approval tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent behavior&lt;/td&gt;
&lt;td&gt;Does a model choose and interpret the tool correctly?&lt;/td&gt;
&lt;td&gt;scoped evaluation set&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The July 2026 MCP release candidate also describes the move to full JSON Schema 2020-12 for tool input and output schemas. That raises the value of testing the serialized declaration rather than assuming a source type tells the whole story. &lt;a href="https://blog.modelcontextprotocol.io/posts/2026-07-28-release-candidate/" rel="noopener noreferrer"&gt;MCP release-candidate notes&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Exact prompt, input, and observed output
&lt;/h2&gt;

&lt;p&gt;For the review step, I use this prompt with a bounded task:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Given this &lt;code&gt;tools/list&lt;/code&gt; JSON and the approved ordered-name snapshot, identify only contract drift. Return &lt;code&gt;PASS&lt;/code&gt; or a list of changed names, missing schemas, invalid root types, and order changes. Do not recommend calling any tool.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Input: the candidate &lt;code&gt;tools/list&lt;/code&gt; payload plus &lt;code&gt;approvedNames&lt;/code&gt; from version control.&lt;/p&gt;

&lt;p&gt;Observed output from the deterministic run: the structural checker detected 960 of 1,200 mutations; adding the ordered-name snapshot detected 1,200 of 1,200. The agent prompt is a review aid, not a source of truth—the code gate remains authoritative.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this approach fails
&lt;/h2&gt;

&lt;p&gt;The study is intentionally narrow. It does not prove that a tool produces the right answer, that a client understands a complex schema, or that authorization is correct. It does not use live servers or real-model task completion. It also treats order drift as relevant by design; a team whose client does not care about order should not manufacture noise by enforcing it.&lt;/p&gt;

&lt;p&gt;The more important failure mode is social: a green contract gate can create confidence that nobody has reviewed the action itself. Keep the human approval boundary close to consequential tool calls, as the protocol’s interaction guidance recommends.&lt;/p&gt;

&lt;p&gt;Start with the tool surface you already have. Save one reviewed snapshot. Fail the build on unexpected drift. Then add behavior and authorization evaluations where the tool can change customer data, spend money, or ship code.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: Human strategy, research design, code review, and editorial judgment led this article. AI assisted drafting and editing.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Google Search Console Content Decay: A Weekly Workflow That Does Not Rewrite the Wrong Pages</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Thu, 20 Aug 2026 08:08:50 +0000</pubDate>
      <link>https://dev.to/agentseodev/google-search-console-content-decay-a-weekly-workflow-that-does-not-rewrite-the-wrong-pages-10me</link>
      <guid>https://dev.to/agentseodev/google-search-console-content-decay-a-weekly-workflow-that-does-not-rewrite-the-wrong-pages-10me</guid>
      <description>&lt;h1&gt;
  
  
  Google Search Console Content Decay: A Weekly Workflow That Does Not Rewrite the Wrong Pages
&lt;/h1&gt;

&lt;p&gt;If a page loses organic clicks, do not immediately rewrite it.&lt;/p&gt;

&lt;p&gt;That is the mistake behind most content-refresh backlogs. A decline in Google Search Console can mean the page is stale. It can also mean demand is seasonal, a competitor changed the SERP, another page on your site is competing, or people are getting the answer before they click.&lt;/p&gt;

&lt;p&gt;Those are different problems. They need different actions.&lt;/p&gt;

&lt;p&gt;This is the weekly workflow I would use to find genuine content decay, decide what is worth refreshing, and keep an AI agent useful without letting it turn every small fluctuation into a rewrite.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;p&gt;Use Search Console to find pages with a meaningful decline in clicks, impressions, CTR, or average position. Then diagnose the loss at the &lt;strong&gt;page and query&lt;/strong&gt; level before making a change.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Signal&lt;/th&gt;
&lt;th&gt;Likely explanation&lt;/th&gt;
&lt;th&gt;First move&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Clicks down, impressions and position stable&lt;/td&gt;
&lt;td&gt;CTR or SERP-layout change&lt;/td&gt;
&lt;td&gt;Inspect title, snippet, and current SERP before rewriting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Impressions and clicks down for a small query set&lt;/td&gt;
&lt;td&gt;Intent shift, stronger competitors, or stale coverage&lt;/td&gt;
&lt;td&gt;Compare the page against the live SERP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Position down across most important queries&lt;/td&gt;
&lt;td&gt;Ranking loss or page-quality gap&lt;/td&gt;
&lt;td&gt;Create a focused refresh brief&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;One page down while a second owned page is up&lt;/td&gt;
&lt;td&gt;Cannibalization&lt;/td&gt;
&lt;td&gt;Investigate URL ownership before editing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Decline matches the same period last year&lt;/td&gt;
&lt;td&gt;Seasonality or lower demand&lt;/td&gt;
&lt;td&gt;Monitor; do not manufacture a refresh&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The point is not to produce more edits. It is to make the next edit defensible.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Search Console is the right starting point
&lt;/h2&gt;

&lt;p&gt;Search Console is first-party evidence of how Google Search exposed your pages. Its Search Analytics data can be grouped by page, query, country, device, and date, with clicks, impressions, CTR, and average position in each row. &lt;a href="https://developers.google.com/webmaster-tools/v1/searchanalytics/query" rel="noopener noreferrer"&gt;Google's Search Analytics API documentation&lt;/a&gt; is also clear about a limitation worth remembering: results are sorted by clicks and the API does not guarantee every possible row.&lt;/p&gt;

&lt;p&gt;That makes it excellent for prioritization, not a substitute for judgment.&lt;/p&gt;

&lt;p&gt;Google's own traffic-drop guide makes the same practical point: break a decline down by query, page, country, and device before deciding what changed. It specifically calls out the possibility that higher-ranking pages are newer or better. &lt;a href="https://support.google.com/webmasters/answer/9079473" rel="noopener noreferrer"&gt;Read the guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The useful unit of work is therefore not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This URL lost 23% of clicks. Refresh it.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;This URL lost clicks from three non-seasonal commercial queries.
Position declined while impressions stayed useful.
The current SERP now emphasizes comparison tables and implementation detail that the page lacks.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have an actual assignment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Build a small candidate set
&lt;/h2&gt;

&lt;p&gt;Start weekly, not daily. Search data moves, reporting is delayed, and a short time window creates noise.&lt;/p&gt;

&lt;p&gt;For a small site, compare the last 28 days against the prior 28 days. For a seasonal business, compare against the matching period last year as well. Keep the first shortlist to 10–20 pages.&lt;/p&gt;

&lt;p&gt;I use four filters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The page had enough prior clicks to matter.&lt;/li&gt;
&lt;li&gt;The decline is large enough to be more than routine variance.&lt;/li&gt;
&lt;li&gt;At least one important query still has meaningful impressions.&lt;/li&gt;
&lt;li&gt;The page is a page we would actually want to improve—not an expired campaign, obsolete documentation, or thin archive page.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This avoids the classic bad backlog: 200 URLs that technically declined, none of which deserves a writer's week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Split the loss into four diagnoses
&lt;/h2&gt;

&lt;p&gt;This is the step most automation skips.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyrfi91oajgth47z5k55u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fyrfi91oajgth47z5k55u.png" alt="Decision flow for diagnosing a content-decline event before changing the page" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The page still ranks, but clicks fell
&lt;/h3&gt;

&lt;p&gt;If average position is broadly stable while clicks fall, do not assume the content went bad. Check CTR by query and device first.&lt;/p&gt;

&lt;p&gt;Possible explanations include a worse title match, a new SERP feature, an AI Overview, ads pushing results down, or a demand shift. A refresh may still help, but rewriting body copy is not the default answer.&lt;/p&gt;

&lt;h3&gt;
  
  
  The page lost position for a narrow query cluster
&lt;/h3&gt;

&lt;p&gt;This is the best content-refresh candidate. The page has proven that it can earn impressions, but it no longer satisfies the current SERP as well as it used to.&lt;/p&gt;

&lt;p&gt;Compare the live results for the lost queries. Look for changes in page format, definitions, proof, freshness, product detail, comparisons, or the questions competitors now answer directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  The page lost position everywhere
&lt;/h3&gt;

&lt;p&gt;Do not edit until you rule out broader causes: technical changes, indexability, canonical changes, internal-link loss, a major SERP shift, or a domain-level quality problem.&lt;/p&gt;

&lt;p&gt;If a page is weak everywhere, a new H2 is unlikely to save it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Another owned page gained at the same time
&lt;/h3&gt;

&lt;p&gt;That is a cannibalization warning. Two pages may be competing for the same intent, or Google may be reassigning the query to a more suitable URL. Choose the URL that should own the job before changing either one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Give the agent evidence, not a vague command
&lt;/h2&gt;

&lt;p&gt;An AI agent can make this weekly review faster. It should not decide to rewrite pages from a top-level traffic chart.&lt;/p&gt;

&lt;p&gt;Give it the comparison export, the candidate URL, the affected queries, and the business context. Then ask it to classify the decline and recommend the smallest useful next action.&lt;/p&gt;

&lt;p&gt;Here is a prompt worth saving in your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are reviewing a possible content-decay event.

Inputs:
- URL: {{url}}
- Last 28 days vs previous 28 days: {{gsc_page_metrics}}
- Top declining queries: {{query_comparison}}
- Same period last year: {{seasonality_comparison}}
- Current page summary: {{page_summary}}
- Live SERP notes for the three highest-value declining queries: {{serp_notes}}

First, classify the event as exactly one of:
1. refresh_candidate
2. ctr_or_serp_layout_change
3. seasonality_or_demand_change
4. cannibalization_risk
5. technical_or_indexing_risk
6. insufficient_evidence

Then return:
- evidence for the classification
- the smallest safe next action
- what must be reviewed by a human
- what would falsify the recommendation

Do not recommend a rewrite unless the evidence points to a page-specific
content or intent gap.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last line is the guardrail. It turns the agent from an eager copy generator into an analyst.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Use live SERP evidence only for the winners
&lt;/h2&gt;

&lt;p&gt;Pulling SERP data for every declining URL is a waste of time and credits. Use your Search Console shortlist first, then investigate only the pages that have an actionable query cluster.&lt;/p&gt;

&lt;p&gt;A tight workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Search Console comparison
        ↓
candidate page and query shortlist
        ↓
live SERP + competitor pattern check
        ↓
refresh, consolidate, fix, or monitor
        ↓
human review before any publication
        ↓
same query/page monitoring after the change
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With AgentSEO, the first agent call can identify declining or stalled pages, then a narrower workflow can use ranked-keyword, cannibalization, refresh-brief, technical-QA, and SERP-volatility checks only where they are needed. That keeps the model grounded in current search context instead of treating every GSC export as an editorial instruction.&lt;/p&gt;

&lt;p&gt;For a tracked keyword and URL, the content-decay endpoint can also make the threshold explicit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST &lt;span class="s2"&gt;"https://www.agentseo.dev/api/v1/content-decay/detect"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer &lt;/span&gt;&lt;span class="nv"&gt;$AGENTSEO_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "url": "https://example.com/seo-api",
    "keyword": "seo api",
    "lookback_days": 30,
    "threshold": 3
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That should create a review candidate, not an automatic publish task. The API's job is to return a consistent signal; the operator's job is to decide whether the signal deserves action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Make a narrow refresh brief
&lt;/h2&gt;

&lt;p&gt;The best refresh briefs do not say "improve the article." They name the delta.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Keep the existing URL and primary intent.

Add a short comparison table near the top because the current top results
all answer the selection question before explaining implementation.

Replace the 2024 examples with verified 2026 examples.

Add the two missing implementation questions that appear in the current SERP.

Do not expand into a broader beginner guide; that would dilute the commercial intent.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is an assignment a writer, marketer, or coding agent can execute and review.&lt;/p&gt;

&lt;h2&gt;
  
  
  What not to automate
&lt;/h2&gt;

&lt;p&gt;Reddit discussions about content decay often collapse into a single rule: declining pages should be refreshed. The better operator question is &lt;em&gt;why did this page decline?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Do not automate these decisions without evidence and approval:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;publishing or rewriting a page;&lt;/li&gt;
&lt;li&gt;changing canonical tags, redirects, or URL ownership;&lt;/li&gt;
&lt;li&gt;treating lower CTR as proof of lower quality;&lt;/li&gt;
&lt;li&gt;deleting pages because a short comparison window looks bad;&lt;/li&gt;
&lt;li&gt;assuming that an AI-result click loss can be fixed with extra word count.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent can detect, compare, summarize, and draft a proposal. A person should approve actions that affect a live URL, brand claim, spend, or measurement history.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple weekly operating rhythm
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Day&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Monday&lt;/td&gt;
&lt;td&gt;Compare 28-day page and query data&lt;/td&gt;
&lt;td&gt;10–20 candidate URLs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tuesday&lt;/td&gt;
&lt;td&gt;Classify candidates and inspect live SERPs for the best five&lt;/td&gt;
&lt;td&gt;Refresh, monitor, consolidate, or technical-investigation decisions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Wednesday&lt;/td&gt;
&lt;td&gt;Create narrow refresh briefs&lt;/td&gt;
&lt;td&gt;Reviewed work queue&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Thursday&lt;/td&gt;
&lt;td&gt;Ship approved changes&lt;/td&gt;
&lt;td&gt;Before-state record&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Following weeks&lt;/td&gt;
&lt;td&gt;Monitor the same URL/query/location/device set&lt;/td&gt;
&lt;td&gt;Evidence of recovery, no change, or a new diagnosis&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not mistake consistency for bureaucracy. The point of a weekly rhythm is to create enough history to distinguish a trend from a bad Tuesday.&lt;/p&gt;

&lt;h2&gt;
  
  
  The practical takeaway
&lt;/h2&gt;

&lt;p&gt;Content decay is not a content-production problem first. It is a diagnosis problem.&lt;/p&gt;

&lt;p&gt;Google Search Console gives you the first-party signals. Live SERP intelligence tells you whether the page, the result page, or the market changed. An agent can turn that evidence into a small, repeatable review loop—but it should be designed to recommend the next safe move, not to rewrite everything that turns red.&lt;/p&gt;

&lt;p&gt;If you are building this into an agent workflow, start with one page type and one review cadence. Then make the loop reliable before you make it autonomous.&lt;/p&gt;

&lt;p&gt;AgentSEO provides the LLM-ready SERP, content-refresh, cannibalization, QA, and monitoring steps for that loop. Start with the &lt;a href="https://www.agentseo.dev/docs/workflows" rel="noopener noreferrer"&gt;workflow guide&lt;/a&gt; or the &lt;a href="https://www.agentseo.dev/docs/quickstart" rel="noopener noreferrer"&gt;quickstart&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>ai</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>MCP vs REST APIs for SEO Agents: A Practical Decision Framework</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Tue, 18 Aug 2026 16:07:37 +0000</pubDate>
      <link>https://dev.to/agentseodev/mcp-vs-rest-apis-for-seo-agents-a-practical-decision-framework-1o13</link>
      <guid>https://dev.to/agentseodev/mcp-vs-rest-apis-for-seo-agents-a-practical-decision-framework-1o13</guid>
      <description>&lt;h1&gt;
  
  
  MCP vs REST APIs for SEO Agents: A Practical Decision Framework
&lt;/h1&gt;

&lt;p&gt;If you are building an SEO agent, do not start with the question: “Should this use MCP or REST?”&lt;/p&gt;

&lt;p&gt;That framing makes the decision sound like a protocol fight.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;REST and MCP usually belong in the same system. They serve different callers and different moments in a workflow.&lt;/p&gt;

&lt;p&gt;Use REST when your application already knows the operation it needs to run. Use MCP when an AI client needs to discover the available operations and choose among them while working.&lt;/p&gt;

&lt;p&gt;For SEO agents, that distinction is practical. A nightly rank-monitoring job is normally a REST job. A Claude Code session that needs to inspect a SERP, find a content gap, and decide what to do next is a good MCP job.&lt;/p&gt;

&lt;p&gt;This is the decision framework I use when exposing search intelligence to agents.&lt;/p&gt;

&lt;h2&gt;
  
  
  The short answer
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If your system needs to…&lt;/th&gt;
&lt;th&gt;Start with&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Run a known job on a schedule&lt;/td&gt;
&lt;td&gt;REST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Process a high-volume batch predictably&lt;/td&gt;
&lt;td&gt;REST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Power a dashboard, web app, or internal backend&lt;/td&gt;
&lt;td&gt;REST&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Let Claude Code, Codex, or Cursor discover tools&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Let an agent choose the next SEO action from live context&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Make one capability work across multiple MCP clients&lt;/td&gt;
&lt;td&gt;MCP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Support both scripted automation and interactive agents&lt;/td&gt;
&lt;td&gt;Both&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The useful architecture is not “MCP instead of API.”&lt;/p&gt;

&lt;p&gt;It is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SEO data providers → REST API / job layer → MCP tools → AI clients
                                      └→ scheduled automation / product backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The API is the dependable execution layer. MCP is the agent-facing interface on top.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F117kanfodoev0pl2kozz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F117kanfodoev0pl2kozz.png" alt="A shared SEO data foundation feeding both scheduled automation and interactive AI-agent tools" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What changes when an agent is the caller
&lt;/h2&gt;

&lt;p&gt;A developer calling a REST API has already made most of the decisions.&lt;/p&gt;

&lt;p&gt;They know which endpoint to use, which parameters it accepts, what authentication is required, and what the response should look like. Their code can retry, paginate, and branch on an error explicitly.&lt;/p&gt;

&lt;p&gt;An AI agent starts somewhere else.&lt;/p&gt;

&lt;p&gt;It is often given a job such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find the highest-impact organic growth opportunity for this page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is not one API request. The right next action could be SERP analysis, a content-gap check, backlink research, local visibility analysis, or a page QA pass.&lt;/p&gt;

&lt;p&gt;MCP gives the client a structured way to ask what tools exist and then call one with typed inputs. The MCP specification defines &lt;code&gt;tools/list&lt;/code&gt; for tool discovery and uses JSON-RPC for messages. Its current standard transports are local &lt;code&gt;stdio&lt;/code&gt; and Streamable HTTP. &lt;a href="https://modelcontextprotocol.io/specification/draft/server/tools" rel="noopener noreferrer"&gt;MCP tools specification&lt;/a&gt; · &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/basic/transports" rel="noopener noreferrer"&gt;MCP transport specification&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That does not make REST less useful. It means the interface is optimized for a different caller.&lt;/p&gt;

&lt;h2&gt;
  
  
  A real SEO example: one goal, two interfaces
&lt;/h2&gt;

&lt;p&gt;Say you want to monitor a set of pages for content decay.&lt;/p&gt;

&lt;h3&gt;
  
  
  REST is better for the scheduled workflow
&lt;/h3&gt;

&lt;p&gt;Your system knows the pages, check frequency, target country, and alert threshold before the job begins.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Every Monday at 08:00:
  for each tracked page
    request the current SERP and ranking data
    compare against the saved baseline
    create an alert only if the threshold is crossed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This needs predictable input, idempotency, job status, retries, and a clean audit trail. A REST API or asynchronous job endpoint is a natural fit.&lt;/p&gt;

&lt;p&gt;The model can still be involved later—perhaps to summarize an alert—but it does not need to choose the underlying operation at every step.&lt;/p&gt;

&lt;h3&gt;
  
  
  MCP is better for the investigative workflow
&lt;/h3&gt;

&lt;p&gt;Now imagine a growth operator in Claude Code sees the alert and asks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Our /seo-api page lost clicks. Use live search data to find the likely cause,
identify the most defensible page update, and flag anything that needs human review.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The order of operations is not known in advance. The agent may need to inspect the SERP, compare competing page formats, check whether an AI Overview is present, review the target page, then create a content brief.&lt;/p&gt;

&lt;p&gt;That is where a focused tool catalog helps.&lt;/p&gt;

&lt;p&gt;With AgentSEO, those jobs are exposed through MCP tools for SERP analysis, content gaps, local audits, rank tracking, backlinks, page QA, and AI Overview checks. The client can discover the available tools rather than relying on a human to paste reports between products.&lt;/p&gt;

&lt;h2&gt;
  
  
  The four questions that make the choice clear
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Is the next operation known before the workflow runs?
&lt;/h3&gt;

&lt;p&gt;If yes, choose REST first.&lt;/p&gt;

&lt;p&gt;A known operation has a stable request shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Check keyword positions for these 200 URLs in the United States.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The program already knows the action, parameters, and success condition. An MCP layer adds little by itself.&lt;/p&gt;

&lt;p&gt;If no, MCP is a stronger candidate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Investigate why this page stopped earning qualified organic traffic.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent needs to reason over the available tools before it can decide what to call.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Does a human need to use the same capability inside an AI client?
&lt;/h3&gt;

&lt;p&gt;If the capability must work interactively in Claude Code, Codex, Cursor, or another MCP client, MCP makes the integration reusable.&lt;/p&gt;

&lt;p&gt;Without it, each client tends to need a bespoke wrapper, prompt convention, or function definition. MCP does not remove authentication or product design work, but it does give clients a common discovery and invocation pattern.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Do you need high-volume, deterministic execution?
&lt;/h3&gt;

&lt;p&gt;Use REST for the hot path.&lt;/p&gt;

&lt;p&gt;Batch keyword collection, large crawls, scheduled refreshes, and usage-sensitive background jobs should remain explicit and observable. Give them ordinary API contracts, queueing, rate limits, retries, and cost controls.&lt;/p&gt;

&lt;p&gt;An agent can trigger one of those workflows, but it should not become the scheduler by accident.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Is the tool list small enough for an agent to choose well?
&lt;/h3&gt;

&lt;p&gt;This is the MCP question teams skip.&lt;/p&gt;

&lt;p&gt;More exposed tools are not automatically better. Every tool name, description, and input schema becomes part of the agent’s choice problem. A long, overlapping catalog makes the agent slower and less reliable.&lt;/p&gt;

&lt;p&gt;Before exposing an API operation as an MCP tool, ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this a complete user job, not merely an internal endpoint?&lt;/li&gt;
&lt;li&gt;Can I explain when to use it in one sentence?&lt;/li&gt;
&lt;li&gt;Does its input schema prevent common mistakes?&lt;/li&gt;
&lt;li&gt;Is it meaningfully different from the other tools?&lt;/li&gt;
&lt;li&gt;Would a user recognize its result as actionable?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is no, keep the operation behind the REST layer for now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trap: auto-generating an MCP tool for every endpoint
&lt;/h2&gt;

&lt;p&gt;It is tempting to put an OpenAPI file through a generator and call the result an agent integration.&lt;/p&gt;

&lt;p&gt;You may get a working server. You may also get a tool catalog full of low-level actions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;create-serp-task
get-serp-task
list-serp-task-results
normalize-serp-result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those operations can be right inside your backend. They are rarely the right mental model for an agent user.&lt;/p&gt;

&lt;p&gt;An agent-facing tool should name the job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;analyze_serp
find_content_gap
audit_local_visibility
create_content_brief
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is not cosmetic.&lt;/p&gt;

&lt;p&gt;The first list asks the model to understand your internal plumbing. The second list lets it select a meaningful piece of work.&lt;/p&gt;

&lt;h2&gt;
  
  
  A compact design pattern that works
&lt;/h2&gt;

&lt;p&gt;Start with a REST-backed service layer, then expose a smaller MCP surface for interactive workflows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Provider APIs
  ↓
Normalization, caching, billing, async jobs, and audit logs
  ↓
REST endpoints for product and scheduled workflows
  ↓
MCP tools designed around user jobs
  ↓
Claude Code, Codex, Cursor, and other AI clients
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you a few useful boundaries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One source of truth for data and billing.&lt;/strong&gt; Your MCP server should not become a second business backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One job model for expensive work.&lt;/strong&gt; Long-running crawls and bulk checks still need status, retries, and cancellation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A smaller agent contract.&lt;/strong&gt; You can improve tool descriptions and schemas without exposing every implementation detail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A safe place for review.&lt;/strong&gt; The agent can research and recommend; a person or explicit policy gate can approve external changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last boundary matters. Search workflows can create side effects: publishing pages, modifying metadata, spending API credits, or changing tracking configurations. Make the action that changes the outside world explicit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The operator checklist
&lt;/h2&gt;

&lt;p&gt;Use this before adding an MCP layer to an SEO API:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Keep your REST API as the stable execution contract.&lt;/li&gt;
&lt;li&gt;Pick three to five repeated, interactive jobs for the first MCP release.&lt;/li&gt;
&lt;li&gt;Give each tool a clear description, narrow inputs, and an actionable result.&lt;/li&gt;
&lt;li&gt;Test the server with a real prompt in the target client—not only an inspector.&lt;/li&gt;
&lt;li&gt;Add workflow identifiers and logging before usage grows.&lt;/li&gt;
&lt;li&gt;Put approval gates in front of publishing, spending, deletion, and permission changes.&lt;/li&gt;
&lt;li&gt;Review tool usage monthly and merge or retire overlapping tools.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For remote servers, follow the MCP transport security guidance: validate origins, use authentication, and avoid exposing a local server broadly by default. &lt;a href="https://modelcontextprotocol.io/specification/2025-11-25/basic/transports" rel="noopener noreferrer"&gt;MCP Streamable HTTP security guidance&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision is not MCP &lt;em&gt;or&lt;/em&gt; REST
&lt;/h2&gt;

&lt;p&gt;If you are building a product that agents use, REST remains your system contract.&lt;/p&gt;

&lt;p&gt;MCP is how you make the useful parts of that contract discoverable and usable when the caller is an AI client.&lt;/p&gt;

&lt;p&gt;For SEO work, that usually means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;REST for monitoring, batches, jobs, dashboards, and product backends.&lt;/li&gt;
&lt;li&gt;MCP for investigation, tool discovery, interactive research, and agent-assisted decisions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use both where they fit.&lt;/p&gt;

&lt;p&gt;That is how you avoid building a brittle agent wrapper—and avoid forcing every automation through a conversational interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the workflow
&lt;/h2&gt;

&lt;p&gt;AgentSEO provides both an API layer and a hosted MCP server for Claude Code, Codex, Cursor, and other compatible clients. Start with one live workflow: inspect a SERP, find the content gap, and decide what to change before you write another page.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.agentseo.dev/seo-mcp-server" rel="noopener noreferrer"&gt;AgentSEO MCP server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.agentseo.dev/docs/quickstart" rel="noopener noreferrer"&gt;Quickstart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://registry.modelcontextprotocol.io/servers/dev.agentseo.www/agentseo-mcp" rel="noopener noreferrer"&gt;MCP Registry entry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>seo</category>
      <category>ai</category>
      <category>devtools</category>
    </item>
    <item>
      <title>How to Add an SEO MCP Server to Claude Code</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Sat, 25 Jul 2026 15:23:20 +0000</pubDate>
      <link>https://dev.to/agentseodev/how-to-add-an-seo-mcp-server-to-claude-code-45nh</link>
      <guid>https://dev.to/agentseodev/how-to-add-an-seo-mcp-server-to-claude-code-45nh</guid>
      <description>&lt;h1&gt;
  
  
  How to add an SEO MCP server to Claude Code
&lt;/h1&gt;

&lt;p&gt;Claude Code can already edit files, run commands, and reason through a codebase.&lt;/p&gt;

&lt;p&gt;The gap shows up when the work depends on a live external system.&lt;/p&gt;

&lt;p&gt;SEO is a good example. If you ask Claude Code to improve a landing page, it can inspect the page and suggest better copy. But it cannot know the current SERP, the competing page formats, the AI Overview behavior, or the backlink context unless you paste that data in.&lt;/p&gt;

&lt;p&gt;That is exactly the job MCP is built for.&lt;/p&gt;

&lt;p&gt;Claude Code’s MCP docs describe MCP servers as a way to connect Claude Code to external tools, databases, and APIs so Claude can read and act on those systems directly instead of working from copied data.&lt;/p&gt;

&lt;p&gt;In this guide, we will add an SEO MCP server to Claude Code and run the first useful prompts.&lt;/p&gt;

&lt;p&gt;I will use AgentSEO as the example server because it exposes a hosted Streamable HTTP MCP endpoint and a local npm package. The setup pattern is the important part.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get from an SEO MCP server
&lt;/h2&gt;

&lt;p&gt;An SEO MCP server gives Claude Code tool access to live search workflows.&lt;/p&gt;

&lt;p&gt;Instead of asking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here is a SERP export. Can you summarize it?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use the SEO MCP server to analyze the SERP for "best seo api" in the United States.
Then identify the search intent and draft a content brief for a comparison page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference is small in wording and large in workflow.&lt;/p&gt;

&lt;p&gt;The first prompt makes you the data pipeline.&lt;/p&gt;

&lt;p&gt;The second prompt lets Claude Code call the tool directly.&lt;/p&gt;

&lt;p&gt;For AgentSEO, the live server card currently lists 45 MCP tools, including SERP analysis, keyword ideas, content briefs, local SEO checks, backlink analysis, rank tracking, and AI Overview extraction.&lt;/p&gt;

&lt;p&gt;You can verify that yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://www.agentseo.dev/.well-known/mcp/server-card.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hosted endpoint is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.agentseo.dev/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Before you start
&lt;/h2&gt;

&lt;p&gt;You need three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code installed.&lt;/li&gt;
&lt;li&gt;An AgentSEO API key.&lt;/li&gt;
&lt;li&gt;A project where you want the MCP server available.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use a server-side API key. Do not use a browser-restricted key for local agent tooling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 1: add the hosted SEO MCP server
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fufor3byvw1i1gt3cr4qm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fufor3byvw1i1gt3cr4qm.png" alt=" " width="799" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Claude Code supports remote HTTP MCP servers with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http &amp;lt;name&amp;gt; &amp;lt;url&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For AgentSEO:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http agentseo https://www.agentseo.dev/mcp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer sk_live_your_key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"x-project-id: client-alpha"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"x-workflow-id: seo-mcp-test"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;sk_live_your_key&lt;/code&gt; with your AgentSEO API key.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;x-project-id&lt;/code&gt; and &lt;code&gt;x-workflow-id&lt;/code&gt; headers are optional, but I like adding them early. Once an agent workflow starts making real API calls, traceability matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Option 2: add the local npm MCP server
&lt;/h2&gt;

&lt;p&gt;If you prefer a local stdio server, use the npm package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agentseo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@agentseo/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AGENTSEO_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sk_live_your_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AGENTSEO_API_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.agentseo.dev/api/v1"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful when your MCP client expects a local subprocess instead of a hosted HTTP endpoint.&lt;/p&gt;

&lt;p&gt;For Claude Code, I would start with the hosted HTTP version unless you have a reason to keep everything local.&lt;/p&gt;

&lt;h2&gt;
  
  
  Verify the server in Claude Code
&lt;/h2&gt;

&lt;p&gt;After adding the server, open Claude Code and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code’s &lt;code&gt;/mcp&lt;/code&gt; panel lets you inspect connected MCP servers. It should show the server and its tools.&lt;/p&gt;

&lt;p&gt;If the server does not appear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;restart Claude Code&lt;/li&gt;
&lt;li&gt;check the API key header&lt;/li&gt;
&lt;li&gt;confirm the endpoint URL is exactly &lt;code&gt;https://www.agentseo.dev/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;run &lt;code&gt;claude mcp list&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;run &lt;code&gt;claude mcp get agentseo&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The setup is not done until Claude Code can see the tools.&lt;/p&gt;

&lt;h2&gt;
  
  
  First prompt: analyze a live SERP
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fttc2fc9jtlalzhcs4tbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fttc2fc9jtlalzhcs4tbh.png" alt=" " width="799" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Start with one bounded workflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use AgentSEO to analyze the SERP for "best seo api" in the United States.

Return:
1. the dominant search intent
2. the common page formats
3. the SERP features that matter
4. what kind of page I should build
5. three risks before publishing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is better than asking for “SEO advice.” The prompt names the keyword, location, output shape, and decision you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  Second prompt: create a content brief
&lt;/h2&gt;

&lt;p&gt;Once the SERP analysis works, ask for something closer to production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use AgentSEO to create a content brief for the keyword "seo api for ai agents".

Audience: developers building agent workflows.
Page type: educational comparison page.
Goal: explain when an SEO API should be exposed as MCP tools.

Include:
- search intent
- suggested H2 structure
- entities and subtopics to cover
- internal link ideas
- title and meta options
- what not to claim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The phrase “what not to claim” is important. Agent-generated SEO content gets risky when it turns every tool output into marketing confidence.&lt;/p&gt;

&lt;p&gt;Ask Claude Code to preserve the review step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Third prompt: check AI Overview visibility
&lt;/h2&gt;

&lt;p&gt;If your SEO work touches AI search, use a narrower prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use AgentSEO to check AI Overview visibility for "best seo api".

Tell me:
1. whether an AI Overview appears
2. what source patterns show up
3. whether AgentSEO or competing pages are citation candidates
4. what page changes would improve citation likelihood
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Treat this as directional research, not a magic ranking button.&lt;/p&gt;

&lt;p&gt;AI Overview behavior changes. The point is to create a repeatable check, not a one-time screenshot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common setup mistakes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0vp4v08qkij4zpiia46.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0vp4v08qkij4zpiia46.png" alt=" " width="799" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The annoying MCP failures are usually small.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrong header format
&lt;/h3&gt;

&lt;p&gt;Use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer sk_live_your_key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not paste the header as JSON into the CLI command.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrong transport
&lt;/h3&gt;

&lt;p&gt;For the hosted AgentSEO endpoint, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nt"&gt;--transport&lt;/span&gt; http
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The MCP spec calls the current HTTP transport Streamable HTTP. Claude Code accepts &lt;code&gt;http&lt;/code&gt; in the CLI and also recognizes &lt;code&gt;streamable-http&lt;/code&gt; in JSON configuration.&lt;/p&gt;

&lt;h3&gt;
  
  
  No restart after configuration
&lt;/h3&gt;

&lt;p&gt;If Claude Code was already open, restart it or check &lt;code&gt;/mcp&lt;/code&gt; again after adding the server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt is too vague
&lt;/h3&gt;

&lt;p&gt;This is a bad first prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Improve my SEO.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a better first prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use AgentSEO to analyze the SERP for "best seo api" in the United States and tell me what page type I should build.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP gives Claude Code tools. You still need to give it a job.&lt;/p&gt;

&lt;h2&gt;
  
  
  When not to use an SEO MCP server
&lt;/h2&gt;

&lt;p&gt;Do not use an SEO MCP server for every writing task.&lt;/p&gt;

&lt;p&gt;You probably do not need live SEO tools when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you are editing brand voice&lt;/li&gt;
&lt;li&gt;you are cleaning grammar&lt;/li&gt;
&lt;li&gt;you are writing internal docs&lt;/li&gt;
&lt;li&gt;you already have the source data in the repo&lt;/li&gt;
&lt;li&gt;the page is not search-led&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use the server when the decision depends on current search context.&lt;/p&gt;

&lt;p&gt;That includes SERP intent, competitor page shape, keyword opportunities, AI Overview visibility, rank tracking, local visibility, or backlink signals.&lt;/p&gt;

&lt;h2&gt;
  
  
  The operator checklist
&lt;/h2&gt;

&lt;p&gt;Before you call the setup done:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the MCP server.&lt;/li&gt;
&lt;li&gt;Confirm it appears in &lt;code&gt;/mcp&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run one live SERP prompt.&lt;/li&gt;
&lt;li&gt;Run one production-shaped content brief prompt.&lt;/li&gt;
&lt;li&gt;Save the working prompt in your repo or team docs.&lt;/li&gt;
&lt;li&gt;Add project/workflow metadata if multiple people will use it.&lt;/li&gt;
&lt;li&gt;Decide who reviews the SEO recommendation before it ships.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The last step matters.&lt;/p&gt;

&lt;p&gt;An SEO MCP server gives Claude Code fresher context. It does not remove judgment.&lt;/p&gt;

&lt;p&gt;The best workflow is not “agent writes, human publishes.”&lt;/p&gt;

&lt;p&gt;The better workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;agent gathers live SEO context
agent drafts the recommendation
human checks the tradeoffs
agent helps implement the approved changes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is where MCP starts to feel useful.&lt;/p&gt;

&lt;p&gt;Not as another dashboard.&lt;/p&gt;

&lt;p&gt;As a tool layer inside the place where the work is already happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code MCP docs: &lt;a href="https://code.claude.com/docs/en/mcp" rel="noopener noreferrer"&gt;https://code.claude.com/docs/en/mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MCP transport spec: &lt;a href="https://modelcontextprotocol.io/specification/2025-06-18/basic/transports" rel="noopener noreferrer"&gt;https://modelcontextprotocol.io/specification/2025-06-18/basic/transports&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AgentSEO Claude Code integration: &lt;a href="https://www.agentseo.dev/integrations/claude-code" rel="noopener noreferrer"&gt;https://www.agentseo.dev/integrations/claude-code&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AgentSEO MCP landing page: &lt;a href="https://www.agentseo.dev/seo-mcp-server" rel="noopener noreferrer"&gt;https://www.agentseo.dev/seo-mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AgentSEO npm package: &lt;a href="https://www.npmjs.com/package/@agentseo/mcp-server" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@agentseo/mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>seo</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Building an SEO MCP server for Claude Code and Codex</title>
      <dc:creator>AgentSEO-dev</dc:creator>
      <pubDate>Mon, 20 Jul 2026 16:18:18 +0000</pubDate>
      <link>https://dev.to/agentseodev/building-an-seo-mcp-server-for-claude-code-and-codex-ghj</link>
      <guid>https://dev.to/agentseodev/building-an-seo-mcp-server-for-claude-code-and-codex-ghj</guid>
      <description>&lt;h1&gt;
  
  
  Building an SEO MCP server for Claude Code and Codex
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftvmxcs4x1h75z8b2lo0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftvmxcs4x1h75z8b2lo0d.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most SEO APIs were built for dashboards.&lt;/p&gt;

&lt;p&gt;That is not a criticism. Dashboards are useful. A marketer opens a report, checks rankings, reviews keywords, exports a CSV, and decides what to do next.&lt;/p&gt;

&lt;p&gt;But that is not how work feels inside Claude Code, Codex, Cursor, or a custom AI agent.&lt;/p&gt;

&lt;p&gt;Inside an agent workflow, the shape is different. You do not want to stop, open a separate SEO tool, copy data into the chat, ask the model to reason over it, then move back to your editor.&lt;/p&gt;

&lt;p&gt;You want the agent to ask for live search data directly.&lt;/p&gt;

&lt;p&gt;That is why we shipped AgentSEO as an MCP server.&lt;/p&gt;

&lt;p&gt;This post is a practical breakdown of what changed, how the server is installed, and why I think SEO APIs are going to move from dashboard-first products to agent-native workflow tools.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1raxczihu9yngz4bdchx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1raxczihu9yngz4bdchx.png" alt=" " width="799" height="434"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The buyer problem is not only data access
&lt;/h2&gt;

&lt;p&gt;SEO teams already have data.&lt;/p&gt;

&lt;p&gt;They have rank trackers, backlink tools, keyword databases, crawl reports, and a growing pile of AI visibility screenshots. The problem is that the data often stops one step before the work.&lt;/p&gt;

&lt;p&gt;A typical SEO API gives you a payload.&lt;/p&gt;

&lt;p&gt;Then your team still has to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which result matters?&lt;/li&gt;
&lt;li&gt;Which page should we update first?&lt;/li&gt;
&lt;li&gt;What is the intent behind this SERP?&lt;/li&gt;
&lt;li&gt;What should the writer or developer actually change?&lt;/li&gt;
&lt;li&gt;Is this useful for an agent, or does it need another parser layer?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last question is the one more API teams should ask.&lt;/p&gt;

&lt;p&gt;If the output still needs a parser layer, a polling layer, and a summarization layer before an agent can act, the API is not finished for agent workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an SEO MCP server should do
&lt;/h2&gt;

&lt;p&gt;MCP gives clients a standard way to discover and call tools. The official MCP registry describes itself as a list of MCP servers for clients, like an app store for MCP servers.&lt;/p&gt;

&lt;p&gt;That matters because the install surface is moving closer to the place where developers already work.&lt;/p&gt;

&lt;p&gt;For SEO, I do not think the best MCP server is just a thin wrapper around raw endpoints. That is a start, but it misses the point.&lt;/p&gt;

&lt;p&gt;A useful SEO MCP server should expose workflow-shaped tools.&lt;/p&gt;

&lt;p&gt;Instead of only returning raw SERP data, it should help an agent do jobs like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;analyze SERP intent&lt;/li&gt;
&lt;li&gt;find content gaps&lt;/li&gt;
&lt;li&gt;draft a content brief&lt;/li&gt;
&lt;li&gt;check local visibility&lt;/li&gt;
&lt;li&gt;review title and meta opportunities&lt;/li&gt;
&lt;li&gt;inspect AI Overview presence&lt;/li&gt;
&lt;li&gt;identify backlink opportunities&lt;/li&gt;
&lt;li&gt;QA a draft before publishing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent should be able to move from question to action without making the user become the integration layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we built into AgentSEO
&lt;/h2&gt;

&lt;p&gt;AgentSEO now exposes 45 MCP tools for live SEO workflows.&lt;/p&gt;

&lt;p&gt;The tools cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SERP analysis&lt;/li&gt;
&lt;li&gt;keyword research&lt;/li&gt;
&lt;li&gt;content briefs&lt;/li&gt;
&lt;li&gt;content refresh briefs&lt;/li&gt;
&lt;li&gt;backlink analysis&lt;/li&gt;
&lt;li&gt;rank tracking&lt;/li&gt;
&lt;li&gt;local SEO checks&lt;/li&gt;
&lt;li&gt;sitemap and technical QA&lt;/li&gt;
&lt;li&gt;AI Overview extraction&lt;/li&gt;
&lt;li&gt;AI search visibility monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is not the number. A big tool count can become noise fast.&lt;/p&gt;

&lt;p&gt;The important part is that the tools map to repeatable SEO jobs. A developer, growth engineer, or technical SEO should be able to give the agent a real task and get back something useful enough to act on.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Use AgentSEO to analyze the SERP for "best seo api" in the United States.
Identify the dominant intent, list the strongest competing angles,
and create a content brief for a comparison page.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is different from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Fetch the SERP payload and make me figure out the rest.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second version is data access. The first version is closer to workflow infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install path: hosted MCP
&lt;/h2&gt;

&lt;p&gt;For clients that support remote MCP servers, AgentSEO can run over hosted Streamable HTTP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http agentseo https://www.agentseo.dev/mcp &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer sk_live_your_key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"x-project-id: client-alpha"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"x-workflow-id: nightly-refresh"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extra headers are optional workflow metadata. I like keeping them in the example because production agent workflows need traceability. When an agent calls a paid or rate-limited API, you eventually want to know which project and workflow made the call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install path: local stdio MCP
&lt;/h2&gt;

&lt;p&gt;For local MCP clients, the npm package works through stdio.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"agentseo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"-y"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@agentseo/mcp-server"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AGENTSEO_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sk_live_your_key"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"AGENTSEO_API_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://www.agentseo.dev/api/v1"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That gives teams a clean local path without forcing every client through the hosted endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  The GTM lesson: MCP directories are becoming agent app stores
&lt;/h2&gt;

&lt;p&gt;The product work was only half the launch.&lt;/p&gt;

&lt;p&gt;The other half was distribution.&lt;/p&gt;

&lt;p&gt;If you ship an MCP server and only mention it in your docs, you are making discovery too hard. Developers are already browsing MCP directories to find tools their agents can use.&lt;/p&gt;

&lt;p&gt;For AgentSEO, we published or submitted to:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Surface&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Official MCP Registry&lt;/td&gt;
&lt;td&gt;Live as &lt;code&gt;dev.agentseo.www/agentseo-mcp&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;npm&lt;/td&gt;
&lt;td&gt;Live as &lt;code&gt;@agentseo/mcp-server&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smithery&lt;/td&gt;
&lt;td&gt;Live, 45 tools detected&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Glama&lt;/td&gt;
&lt;td&gt;Hosted connector live, 45 tools verified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mcp.so&lt;/td&gt;
&lt;td&gt;Submitted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;awesome-mcp-servers&lt;/td&gt;
&lt;td&gt;PR submitted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PulseMCP&lt;/td&gt;
&lt;td&gt;Waiting on official registry sync&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP Market&lt;/td&gt;
&lt;td&gt;Submitted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MCP Server Spot&lt;/td&gt;
&lt;td&gt;Submitted&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is the new shelf space.&lt;/p&gt;

&lt;p&gt;Not all of it will convert. Some directories will send little traffic. Some will take weeks to index. Some will matter mostly as trust signals.&lt;/p&gt;

&lt;p&gt;But the intent is unusually clean.&lt;/p&gt;

&lt;p&gt;Someone browsing an MCP directory is not vaguely interested in AI. They are looking for a tool their agent can install.&lt;/p&gt;

&lt;p&gt;That is a better starting point than most launch traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  The product lesson: expose jobs, not endpoints
&lt;/h2&gt;

&lt;p&gt;This is the part I would underline for any API company.&lt;/p&gt;

&lt;p&gt;Do not start by asking, "How do we expose every endpoint through MCP?"&lt;/p&gt;

&lt;p&gt;Start with a smaller question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What are the 5 jobs an agent should be able to complete without leaving the workflow?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For an SEO API, those jobs might be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Analyze a live SERP.&lt;/li&gt;
&lt;li&gt;Find keyword or content gaps.&lt;/li&gt;
&lt;li&gt;Create an implementation-ready brief.&lt;/li&gt;
&lt;li&gt;QA a draft before publishing.&lt;/li&gt;
&lt;li&gt;Track whether visibility moved.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is enough for a useful first version.&lt;/p&gt;

&lt;p&gt;The raw endpoint map can come later. If you start with the endpoint map, you risk shipping a server that is technically complete and practically annoying.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple checklist for API teams
&lt;/h2&gt;

&lt;p&gt;If you are thinking about turning your API into an MCP server, I would start here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pick one user: developer, agency operator, growth engineer, analyst.&lt;/li&gt;
&lt;li&gt;Pick one repeatable workflow.&lt;/li&gt;
&lt;li&gt;Expose the few tools needed to complete that workflow.&lt;/li&gt;
&lt;li&gt;Make the install command copy-pasteable.&lt;/li&gt;
&lt;li&gt;Publish to the official MCP registry.&lt;/li&gt;
&lt;li&gt;Add one directory listing where your buyers already browse.&lt;/li&gt;
&lt;li&gt;Test with a real prompt, not only a protocol inspector.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The inspector can tell you the server works.&lt;/p&gt;

&lt;p&gt;A real prompt tells you whether the product works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The larger shift
&lt;/h2&gt;

&lt;p&gt;APIs used to feed dashboards.&lt;/p&gt;

&lt;p&gt;Now they can feed agents.&lt;/p&gt;

&lt;p&gt;That does not make dashboards obsolete. It does mean API products need a second interface: one designed for software agents that can plan, call tools, inspect results, and continue the workflow.&lt;/p&gt;

&lt;p&gt;For AgentSEO, MCP is that interface.&lt;/p&gt;

&lt;p&gt;The bet is simple: if AI agents are where more technical SEO and growth work happens, then SEO infrastructure should be available inside those agents.&lt;/p&gt;

&lt;p&gt;Not as a pasted export.&lt;/p&gt;

&lt;p&gt;As a tool the agent can actually use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;AgentSEO MCP landing page: &lt;a href="https://www.agentseo.dev/seo-mcp-server" rel="noopener noreferrer"&gt;https://www.agentseo.dev/seo-mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;AgentSEO quickstart: &lt;a href="https://www.agentseo.dev/docs/quickstart" rel="noopener noreferrer"&gt;https://www.agentseo.dev/docs/quickstart&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm package: &lt;a href="https://www.npmjs.com/package/@agentseo/mcp-server" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@agentseo/mcp-server&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Official MCP registry docs: &lt;a href="https://github.com/modelcontextprotocol/registry/tree/main/docs" rel="noopener noreferrer"&gt;https://github.com/modelcontextprotocol/registry/tree/main/docs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Glama connector: &lt;a href="https://glama.ai/mcp/connectors/dev.agentseo.www/agentseo-mcp" rel="noopener noreferrer"&gt;https://glama.ai/mcp/connectors/dev.agentseo.www/agentseo-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Smithery listing: &lt;a href="https://smithery.ai/servers/agentseo/agentseo-mcp" rel="noopener noreferrer"&gt;https://smithery.ai/servers/agentseo/agentseo-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>mcp</category>
      <category>seo</category>
      <category>ai</category>
      <category>devtools</category>
    </item>
  </channel>
</rss>
