If no URL was provided in the arguments ($ARGUMENTS), ask the user for the site URL before proceeding.
Once you have the URL, execute the full diagnostic pipeline below and write the final report to a markdown file in the current working directory. Name the file diagnostic-{domain}.md (e.g. diagnostic-example-com.md, replacing dots with hyphens). Confirm the file path to the user when done.
Your reports have two purposes:
- Give the brand a clear, honest picture of their site's health and its effect on business outcomes — revenue, organic traffic, conversion, brand perception.
- Quantify the scale of execution required to close the gaps, making it evident that this volume of work demands automation and continuous delivery.
Every finding connects to a business outcome. Every claim traces to a data source. When data is missing, say so.
FRAMING: Always frame as opportunity, never failure.
- Banned → alternative: "zero X" / "0 X found" → "X not detected" "completely absent" → "not included" "critical failure" → "structural opportunity" "massive" / "devastating" → "significant" / "material" / "measurable"
- When something is genuinely bad, the data speaks for itself. An 11MB homepage needs no adjectives.
CONCISION:
- Each finding stated ONCE in its own section. Not restated elsewhere.
- "What This Requires" and "Strategic Context" reference TOTALS only — never re-list individual findings by name.
- Depth proportional to impact: HIGH (structured data, meta, reviews, weight/TTFB): 2-3 paragraphs. MEDIUM (editorial sitemaps, cache, cross-sell): 1-2 paragraphs. LOW (HSTS, robots, encoding): 1 paragraph, grouped.
WHY: The raw tool outputs are enormous (discover: ~70K chars, research: ~400K chars). If loaded into the main context, they crowd out the analytical and writing work. Subagents absorb the raw data, extract what matters, and return ~2-5K of structured findings each.
PHASE 1 — Discovery subagent: Launch ONE Task agent (subagent_type: "general-purpose") with the discovery prompt below. Wait for it to return.
Parse the returned summary to extract: - samples object (needed for phase 2) - discovery object (needed for phase 2) - site inventory numbers - editorial status - platform / CDN
PHASE 2 — Analysis subagents (parallel): Launch FOUR Task agents in a SINGLE message (all subagent_type: "general-purpose"), passing each the samples and discovery from phase 1: - Performance agent - SEO agent - Content agent - Research agent
Each returns a compact structured summary. Wait for all four.
PHASE 3 — Report: You now have 5 compact summaries in context (~15K total instead of ~500K). Synthesize into the report per . Run through before finalizing. Write the report to the markdown file.
DISCOVERY AGENT
You are a data extraction agent. Call the MCP tool `discover` with the URL
provided, then extract and return a COMPACT summary. Do NOT return raw data.
URL: {url}
Call: mcp__site-diag-steps__discover({ url: "{url}" })
The output will be large (50-70K chars). Most of it is `crawl.allUrls` and
`homepage.links` which you do NOT need. Extract using jq or by reading
selectively.
Return EXACTLY this structure as a fenced JSON block:
```json
{
"samples": { ... }, // copy verbatim from output — needed by other agents
"discovery_passthrough": { // minimal discovery for content/research agents
"crawl": {
"totalPages": N,
"pageCounts": { "pdp": N, "plp": N, "blog": N, "institutional": N, "other": N },
"sampleUrls": { "pdp": [...], "plp": [...], "blog": [...], "institutional": [...] }
},
"sitemap": {
"exists": bool,
"totalProductUrls": N,
"productSitemapUrls": [...]
},
"robots": { "exists": bool, "sitemapUrls": [...] },
"homepage": {
"status": N,
"platform": "...",
"cdn": "...",
"seoMeta": { ... } // copy verbatim
},
"editorial": { "paths": [...] }, // copy verbatim
"samples": { ... } // copy verbatim (yes, duplicated — needed)
},
"summary": {
"totalPages": N,
"pageCounts": { "pdp": N, "plp": N, "blog": N, "institutional": N, "other": N },
"sitemapProductCount": N,
"sitemapExists": bool,
"sitemapFiles": ["list of sitemap URLs"],
"platform": "...",
"cdn": "...",
"homepageTitle": "...",
"homepageDescription": "...",
"homepageCanonical": "...",
"homepageJsonLdTypes": "...",
"editorialPaths": [
{ "path": "/blog", "exists": true, "linkCount": 0 }
],
"editorialActive": bool, // true ONLY if any path has linkCount > 0
"robotsExists": bool,
"robotsHasCustomRules": bool // true if rules beyond basic defaults
}
}
IMPORTANT:
- The
discovery_passthroughmust includecrawl.sampleUrls— other agents need it. - Do NOT include
crawl.allUrlsorhomepage.linksorhomepage.headers— they are huge and unused. editorialActiveis true ONLY if at least one editorial path has linkCount > 0. Paths returning 200 with linkCount=0 are catch-all routes, not real content.
## PERFORMANCE AGENT
You are a data extraction agent. Call the MCP tool analyze_perf with the
samples provided, then extract and return a COMPACT summary.
Samples: {samples_json}
Call: mcp__site-diag-steps__analyze_perf({ samples: {samples_json} })
Return EXACTLY this structure as a fenced JSON block:
{
"homepage": {
"ttfbMs": N,
"totalRequests": N,
"totalKB": N,
"jsKB": N,
"cssKB": N,
"imageKB": N,
"htmlKB": N,
"fontKB": N,
"cacheHits": N,
"cacheMisses": N,
"cacheHitRate": "N%",
"thirdParties": [
{ "domain": "...", "requests": N, "kb": N }
],
"failedRequests": []
},
"lighthouse_homepage": {
"scores": { "performance": N, "accessibility": N, "best-practices": N, "seo": N },
"webVitals": {
"lcp": { "value": N, "display": "..." },
"cls": { "value": N, "display": "..." },
"tbt": { "value": N, "display": "..." },
"fcp": { "value": N, "display": "..." },
"si": { "value": N, "display": "..." },
"tti": { "value": N, "display": "..." }
},
"diagnostics": [
{ "id": "...", "title": "...", "displayValue": "...", "numericValue": N }
]
},
"lighthouse_pdp": {
"url": "...",
"scores": { ... },
"webVitals": { ... },
"diagnostics": [ ... ]
},
"screenshots": [
{ "url": "...", "imageUrl": "...", "device": "..." }
]
}
IMPORTANT:
- Include ALL third parties from the inventory.
- Include ALL diagnostics from Lighthouse.
- Include ALL lighthouse results (homepage + any PDPs).
- For screenshots, only include entries that have a non-null imageUrl.
## SEO AGENT
You are a data extraction agent. Call the MCP tool analyze_seo with the URL
and samples provided, then return a COMPACT summary.
URL: {url} Samples: {samples_json}
Call: mcp__site-diag-steps__analyze_seo({ url: "{url}", samples: {samples_json} })
Return EXACTLY this structure as a fenced JSON block:
{
"audit": {
"score": N,
"brokenLinks": N,
"duplicateMeta": N,
"missingMetadata": N,
"structuredDataCoverage": N,
"issues": [
{ "type": "...", "count": N, "severity": "..." }
]
},
"pageMeta": [
{
"url": "...",
"title": "...",
"description": "...(first 200 chars)...",
"h1": "...",
"canonical": "...",
"jsonLd": ["..."],
"ogTags": { "og:title": "...", "og:type": "..." }
}
],
"sitemapHealth": {
"productCount": N,
"indexable": bool,
"orphanedEstimate": N
},
"domainSignals": {
"ssl": bool,
"sitemap": bool,
"robotsTxt": bool,
"http2": bool,
"cms": "..."
}
}
IMPORTANT:
- Include ALL issues from the audit.
- For pageMeta, include ALL sampled pages. Truncate descriptions to 200 chars.
- For ogTags, include only og:title, og:type, og:image — skip og:description (redundant with description field).
## CONTENT AGENT
You are a data extraction agent. Call the MCP tool analyze_content with the
samples and discovery provided, then return a COMPACT summary.
Samples: {samples_json} Discovery: {discovery_passthrough_json}
Call: mcp__site-diag-steps__analyze_content({ samples: {samples_json}, discovery: {discovery_passthrough_json} })
Return EXACTLY this structure as a fenced JSON block:
{
"pdpScrapes": [
{
"url": "...",
"hasReviews": bool,
"hasCrossSell": bool,
"hasJsonLd": bool,
"jsonLdTypes": ["..."],
"descriptionLength": N,
"imageCount": N,
"imageAlts": N
}
],
"editorialScrapes": [
{
"url": "...",
"wordCount": N,
"publishDate": "..." or null,
"hasAuthor": bool,
"hasSeoMeta": bool
}
],
"screenshots": [
{ "url": "...", "imageUrl": "...", "device": "..." }
],
"aggregated": {
"pdpCount": N,
"reviewsDetected": "N/N PDPs",
"crossSellDetected": "N/N PDPs",
"jsonLdDetected": "N/N PDPs",
"avgDescriptionLength": N,
"avgImageCount": N,
"totalImageAlts": N,
"totalImages": N
}
}
IMPORTANT:
- Include ALL PDP scrapes and editorial scrapes — do not summarize away individual entries.
- The
aggregatedsection gives quick counts so the main agent doesn't need to recompute. - For screenshots, only include entries with non-null imageUrl.
## RESEARCH AGENT
You are a data extraction agent. Call the MCP tool research with the URL and
discovery provided, then return a COMPACT summary.
The raw output can be 300-400K chars (mostly keyword data). You MUST filter aggressively.
URL: {url} Discovery: {discovery_passthrough_json}
Call: mcp__site-diag-steps__research({ url: "{url}", discovery: {discovery_passthrough_json} })
If the output is saved to a file due to size, use Bash with jq to extract fields. Do NOT try to read the entire file at once.
Extraction queries: jq '.traffic' → traffic object (may be null) jq '.business' → business context jq '.serp[] | {keyword, resultsCount: (.results | length)}' → SERP summary jq '.serp[].results[:5]' → top 5 results per keyword jq '[.keywords[] | select(.volume >= 500)] | sort_by(-.volume) | .[:20]' → top keywords
Return EXACTLY this structure as a fenced JSON block:
{
"traffic": {
"globalRank": N or null,
"countryRank": N or null,
"totalVisits": N or null,
"bounceRate": N or null,
"pagesPerVisit": N or null,
"trafficSources": { ... } or null,
"topCountries": [ ... ] or null,
"monthlyVisits": [ ... ] or null,
"aiTraffic": N or null
},
"business": {
"summary": "...(full text)...",
"marketPosition": "...",
"competitors": ["..."],
"recentNews": ["..."],
"businessContext": "...(full text, preserve citations)..."
},
"serp": [
{
"keyword": "...",
"topResults": [
{ "position": N, "title": "...", "url": "..." }
]
}
],
"topKeywords": [
{ "keyword": "...", "volume": N, "cpc": N or null, "difficulty": N }
],
"keywordsTotalCount": N
}
IMPORTANT:
- If traffic is null, return
"traffic": null— do NOT fabricate. - For business, preserve the FULL summary and businessContext text including citation markers like [1][2][3] — the main agent needs these for footnotes.
- For SERP, include only the top 5 results per keyword.
- For keywords, include only the top 20 by volume (minimum 500 volume). Also return the total count of all keywords returned by the tool.
- Do NOT include monthly trends per keyword — too verbose.
</subagent-prompts>
<graceful-degradation>
When a subagent errors or returns malformed data: omit the dependent sections,
continue with the rest. Add one footnote at end if needed:
"*Some sections may reflect partial data due to tool availability.*"
Performance + SEO subagents are load-bearing; others can be absent.
</graceful-degradation>
<opportunity-counting>
Frame each opportunity as "what needs to change" + "how many pages are affected."
Do NOT classify as template/per-page/config — implementation path is unknown.
Good: "Add Product JSON-LD to product pages | 2,358 PDPs"
Bad: "1 template change → 2,358 pages"
COUNTING:
- Each distinct action = 1 opportunity. Scope column = pages affected.
- {N} = distinct actions.
- {total_page_improvements} = sum of all Pages Affected.
- {unique_urls} = deduplicated page count across all actions.
Present all three transparently. Ongoing work (content production, review
collection) noted separately, excluded from {N}.
</opportunity-counting>
<report-template>
# Diagnostic report: {Brand} ({Parent Company if known})
> **Date:** {YYYY-MM-DD} **URL:** {domain} **Platform:** {homepage.platform}
> **Monthly visits:** ~{traffic.totalVisits} **Category:** {detected or traffic}
> **Ranking global:** #{traffic.globalRank} | **Ranking Brasil:** #{traffic.countryRank}
**Health Score: {score}/100** — Structured Data {X}/20 | Content Engine {X}/15 |
Product SEO {X}/15 | Performance {X}/20 | Social Proof {X}/10 | Cross-sell {X}/10 |
Domain Signals {X}/10
**Site inventory:** {Measured counts with sources.}[^inventory]
[^inventory]: {Methodology.}
---
## {total_page_improvements} improvement opportunities identified on {domain}
We identified **{N} areas of improvement** representing **{total_page_improvements}
page-level improvements** across **{unique_urls} unique URLs**. {2-3 sentences on
the most impactful findings — stated once, not repeated.}
---
## Opportunities
Each section: finding with inline source references → scope table → business
implication.
| Action | Pages affected |
|---|---|
| {what needs to change} | {number or "site-wide"} |
Number sequentially (### 1., ### 2., ...). Group minor fixes in "Technical hygiene".
Screenshots inline where they belong:
- Homepage screenshot → after headline/summary.
- PLP screenshot → after the last PLP finding.
- PDP screenshot → after the last PDP opportunity.
Use . Omit silently if missing.
---
## Opportunity summary
| Opportunity | Action | Pages affected |
|---|---|---|
| {each section} | {description} | {count} |
| **Total** | **{N} areas** | **{total_page_improvements} improvements across {unique_urls} URLs** |
Then one paragraph (no finding names):
"What each improvement requires depends on the platform and team. The volume —
{total_page_improvements} individual improvements across {unique_urls} URLs —
and the ongoing nature of the work make automated execution essential."
---
## What this requires
6-8 sentences, three short paragraphs:
1. Scale — improvements touch thousands of pages; catalog is not static; new
products inherit the same gaps. TOTALS only.
2. Nature of the work — some fixes one-time; content and monitoring continuous,
granular, time-sensitive.
3. deco AI Agents — specialized agents that execute continuously. What takes
weeks elsewhere, deco delivers in minutes, on autopilot.
Close with: "Run your digital strategy on autopilot." (or equivalent in
report language)
Do NOT name specific findings. Do NOT claim agencies are slow. Do NOT quote prices.
---
## Strategic context
3-4 focused paragraphs of EXTERNAL context (market, competition, timing). Do NOT
rehash technical findings. Footnote all research.business claims. Caveat SERP
positions with source/location/date.
---
## References and methodology
**Industry benchmarks cited:** {list with sources}
**Data sources:** {tool, scope, date for each}
**Source URLs:** {footnoted references}
---
*Report generated by the deco AI diagnostic pipeline.*
</report-template>
<data-integrity>
A single fabricated stat destroys the report.
PROVENANCE: every number traces to a named step tool's output field.
Good: "2,358 PDPs measured from discover().sitemap.totalProductUrls"
Bad: "~3,000 products estimated"
ABSENCE vs NON-DETECTION: blackbox — always say "not detected" / "not found in
our analysis". Never "zero" / "none whatsoever" / "does not exist".
SITEMAPS ≠ REALITY: content can exist without being in a sitemap. Never conclude
content doesn't exist from sitemap data alone.
SERP POSITIONS: include source (DataForSEO), location, date on every claim.
SAMPLING: state the sample size. "Of 3 PDPs sampled, none contained reviews."
Never extrapolate a 3-sample finding to the whole catalog.
OBSERVATION vs INFERENCE:
Observation: "Homepage weighs 11.2 MB" (measured)
Inference: "likely an undeferred video embed" (use "likely", "suggests")
RESEARCH.BUSINESS: AI-synthesized — hedge ("approximately", "segundo pesquisa de
mercado") and footnote citation URLs.
RESEARCH.TRAFFIC (Similarweb panel):
- "approximately" / "estimated" — never exact figures.
- Always footnote the data source and its limitations.
- Traffic sources are percentages summing to ~100%. Present as percentages.
- aiTraffic shares may be null → show "—", not "zero".
- Keyword CPC may be null → "—", not "free" / "zero".
- Competitor comparisons: both numbers must come from research.traffic (same
snapshot). Never mix sources.
- If research.traffic is null: omit the Traffic Intelligence section entirely.
CATALOG SIZE: sitemap.totalProductUrls = fact. crawl.pageCounts.pdp = stated
with crawl limit. Never extrapolate. Every catalog reference uses the same
number from the same source.
BENCHMARKS — safe list (use freely):
* "Every 0.1s mobile speed improvement → +8.4% conversion (retail), +10.1%
(travel)" (Deloitte, "Milliseconds Make Millions", 2020)
* "Product recommendations drive 10-30% of e-commerce revenue" (McKinsey)
* "Rich snippets increase CTR by 20-40%" (SEJ / Ahrefs)
* "Products with 50+ reviews convert at 2-3x vs. zero" (Bazaarvoice / Spiegel)
* "Unique PDP descriptions increase organic traffic 30-50%" (Ahrefs)
* "Post-purchase review emails: 5-15% response rate" (industry avg)
* "AOV uplift with cross-sell: 8-15%" (Baymard)
* "Companies with active blogs generate ~55% more visitors" (HubSpot)
Any benchmark NOT on this list must be attributed to a verifiable source.
If unsure: use a range or remove.
COMPETITORS: only name those present in research.business.competitors. Traffic
comparisons require both numbers from research.traffic.
MISSING DATA: omit the section. 5 solid sections beat 8 with 3 padded.
</data-integrity>
<health-score-rubric>
Calculate from measured data. If a category has no data, score N/A and redistribute.
1. STRUCTURED DATA (0-20) — from SEO agent: audit.structuredDataCoverage +
Content agent: pdpScrapes[].hasJsonLd/jsonLdTypes.
0: no JSON-LD | 5: <25% or partial | 10: 25-75% with Product
15: >75% with Product + BreadcrumbList | 20: full coverage
2. CONTENT ENGINE (0-15) — from Discovery agent: editorialPaths/editorialActive +
Content agent: editorialScrapes.
"Exists" requires: linkCount>0 on at least one editorial path, OR
editorialScrapes showing multiple distinct articles with publishDates.
Paths returning 200 with linkCount=0 and no post structure = NOT existing.
0: no editorial (or paths respond but no identifiable posts/links) |
3: editorial section with identifiable articles, but not in sitemaps |
5: in sitemaps, <10 posts | 10: 10-50 posts some SEO |
15: 50+ posts active, SEO-optimized
3. PRODUCT SEO (0-15) — from SEO agent: pageMeta for PDPs + audit.duplicateMeta.
0: all generic | 5: <25% unique | 8: 25-50% | 12: 50-90% | 15: >90% unique
4. PERFORMANCE (0-20) — from Performance agent: homepage HAR + lighthouse.
= TTFB+Weight (0-10) + Caching (0-10)
TTFB+Weight: 0 if >3s or >10MB | 3 if 2-3s or 5-10MB | 6 if 1-2s & 3-5MB
8 if 600ms-1s & 1.5-3MB | 10 if <600ms & <1.5MB
Caching: 0 if no-cache | 3 homepage only | 6 most pages, low TTL
10 proper headers all types
5. SOCIAL PROOF (0-10) — from Content agent: aggregated.reviewsDetected.
0: no reviews | 3: <5 avg | 6: 5-50 avg | 10: 50+ on most
6. CROSS-SELL (0-10) — from Content agent: aggregated.crossSellDetected.
0: none | 3: API detected not rendered | 5: some PDPs | 10: all sampled
7. DOMAIN SIGNALS (0-10) — from SEO agent: domainSignals.
SSL +2 | sitemap +2 | robotsTxt +2 | canonicals correct +2 | no conflicting meta +2
</health-score-rubric>
<checklist>
Before finalizing:
1. LANGUAGE: .br → pt-BR. Else → English.
2. NO EMOJIS anywhere.
3. STRUCTURE follows <report-template> exactly. No invented sections.
4. HEALTH SCORE max values: /20, /15, /15, /20, /10, /10, /10. Recalculated
from rubric using subagent outputs.
5. DATA PROVENANCE: every number names the step tool + field it came from.
6. SAMPLING: every sampled finding states sample size. No extrapolation.
7. BENCHMARKS: safe list or verifiably attributed.
8. TONE: "Not detected" not "zero". Opportunity framing.
9. NO REPETITION: findings in their section only. Totals in summaries.
10. DEPTH: high-impact 2-3¶, low-impact 1¶ grouped.
11. SITE-SPECIFICITY: every path, example, URL comes from THIS site's subagent
outputs. No content carried over from other sites.
12. TRAFFIC DATA: header monthly visits, category, rankings from Research agent.
If null, fall back to research.business and state source.
13. SERP: source + location + date on every position claim.
14. RESEARCH.BUSINESS claims hedged and footnoted.
</checklist>