CrawlForge
HomePlaygroundUse CasesIntegrationsPricingDocumentationBlog
Automate SEO Audits with CrawlForge MCP
Use Cases
Back to Blog
Use Cases

Automate SEO Audits with CrawlForge MCP

C
CrawlForge Team
Engineering Team
April 6, 2026
9 min read
Updated April 14, 2026

On this page

Running a technical SEO audit manually on a 500-page site takes 6-8 hours. Checking meta tags, validating heading hierarchy, finding broken links, analyzing content quality -- it is tedious, error-prone work that most teams do quarterly at best (Google's own Lighthouse audit tool helps, but does not scale to whole-site crawls). By the time you finish, half the issues have already cost you rankings.

CrawlForge turns a full-day SEO audit into a 15-minute automated workflow. This guide shows you how to build a complete SEO audit pipeline that checks every page on your site for 20+ ranking factors and generates a prioritized action report.

Table of Contents

  • What This SEO Audit Covers
  • Architecture Overview
  • Step 1: Crawl and Map Your Site
  • Step 2: Extract and Validate Metadata
  • Step 3: Analyze Content Quality
  • Step 4: Check Links and Site Structure
  • Step 5: Generate the Audit Report
  • Credit Cost Analysis
  • Results and Benefits
  • Frequently Asked Questions

What This SEO Audit Covers

This automated audit checks for the most impactful technical SEO factors:

CategoryChecksImpact
Meta tagsTitle length, description, Open Graph, canonicalHigh
ContentWord count, heading hierarchy, keyword densityHigh
LinksBroken links, orphan pages, redirect chainsMedium
StructureSitemap coverage, crawl depth, URL patternsMedium
PerformancePage size, response time, render-blocking resourcesMedium

What is a technical SEO audit? It is a systematic review of a website's technical health factors that affect search engine crawling, indexing, and ranking. Unlike content audits that focus on what you write, technical audits focus on how search engines discover and process your pages -- including signals like Core Web Vitals and proper robots.txt configuration.

Architecture Overview

The audit pipeline uses five CrawlForge tools:

StepToolCreditsPurpose
Site discoverymap_site3Generate complete URL inventory
Deep crawlcrawl_deep5Traverse site structure and find issues
Metadata checkextract_metadata1Validate meta tags per page
Content analysisanalyze_content3Score content quality and readability
Link auditextract_links1Find broken and orphan links

Step 1: Crawl and Map Your Site

Start with a complete inventory of every page on your site.

Typescript
import { Client } from '@modelcontextprotocol/sdk/client/index.js';

const client = new Client({
  name: 'seo-auditor',
  version: '1.0.0',
});

interface SiteAuditConfig {
  url: string;
  maxPages: number;
  maxDepth: number;
}

async function crawlSite(config: SiteAuditConfig) {
  // First, get the sitemap for a complete URL list
  const siteMap = await client.callTool({
    name: 'map_site',
    arguments: {
      url: config.url,
      max_urls: config.maxPages,
      include_sitemap: true,
      include_metadata: true,
      group_by_path: true,
    },
  });

  const mapResult = JSON.parse(siteMap.content[0].text);

  // Then crawl to discover pages not in the sitemap
  const crawlResult = await client.callTool({
    name: 'crawl_deep',
    arguments: {
      url: config.url,
      max_pages: config.maxPages,
      max_depth: config.maxDepth,
      extract_content: true,
      respect_robots: true,
    },
  });

  const crawled = JSON.parse(crawlResult.content[0].text);

  // Combine and deduplicate
  const allUrls = new Set([
    ...mapResult.urls,
    ...crawled.pages.map((p: { url: string }) => p.url),
  ]);

  // Flag pages in crawl but missing from sitemap
  const missingFromSitemap = crawled.pages
    .filter((p: { url: string }) => !mapResult.urls.includes(p.url))
    .map((p: { url: string }) => p.url);

  return {
    totalPages: allUrls.size,
    urls: Array.from(allUrls),
    missingFromSitemap,
    crawlDepthDistribution: crawled.depthDistribution,
  };
}

This step identifies orphan pages (crawlable but not in your sitemap) and gives you a depth distribution showing how many clicks it takes to reach each page.

Step 2: Extract and Validate Metadata

Check every page for meta tag issues that hurt rankings.

Typescript
interface MetaIssue {
  url: string;
  type: 'error' | 'warning';
  message: string;
}

async function auditMetadata(urls: string[]): Promise<MetaIssue[]> {
  const issues: MetaIssue[] = [];

  // Batch process metadata extraction
  const batchResult = await client.callTool({
    name: 'batch_scrape',
    arguments: {
      urls: urls.map(url => ({ url })),
      includeMetadata: true,
      maxConcurrency: 15,
    },
  });

  const results = JSON.parse(batchResult.content[0].text);

  for (const page of results.results) {
    const meta = page.metadata;
    const url = page.url;

    // Title checks
    if (!meta?.title) {
      issues.push({ url, type: 'error', message: 'Missing title tag' });
    } else if (meta.title.length > 60) {
      issues.push({ url, type: 'warning', message: `Title too long (${meta.title.length} chars, max 60)` });
    } else if (meta.title.length < 30) {
      issues.push({ url, type: 'warning', message: `Title too short (${meta.title.length} chars, min 30)` });
    }

    // Description checks
    if (!meta?.description) {
      issues.push({ url, type: 'error', message: 'Missing meta description' });
    } else if (meta.description.length > 155) {
      issues.push({ url, type: 'warning', message: `Description too long (${meta.description.length} chars)` });
    }

    // Open Graph checks
    if (!meta?.ogTitle) {
      issues.push({ url, type: 'warning', message: 'Missing og:title' });
    }
    if (!meta?.ogImage) {
      issues.push({ url, type: 'warning', message: 'Missing og:image' });
    }

    // Canonical check
    if (!meta?.canonical) {
      issues.push({ url, type: 'warning', message: 'Missing canonical URL' });
    }
  }

  return issues;
}

Step 3: Analyze Content Quality

Use analyze_content to score readability, keyword presence, and content depth for your most important pages.

Typescript
interface ContentScore {
  url: string;
  wordCount: number;
  readabilityScore: number;
  topTopics: string[];
  sentiment: string;
  issues: string[];
}

async function analyzePageContent(url: string): Promise<ContentScore> {
  // First extract clean content
  const content = await client.callTool({
    name: 'extract_content',
    arguments: { url },
  });

  const extracted = JSON.parse(content.content[0].text);

  // Then analyze it
  const analysis = await client.callTool({
    name: 'analyze_content',
    arguments: {
      text: extracted.content,
    },
  });

  const result = JSON.parse(analysis.content[0].text);
  const issues: string[] = [];

  // Flag thin content (under 300 words)
  if (result.wordCount < 300) {
    issues.push(`Thin content: only ${result.wordCount} words (recommend 800+)`);
  }

  // Flag low readability
  if (result.readabilityScore < 40) {
    issues.push('Content may be too complex for general audience');
  }

  return {
    url,
    wordCount: result.wordCount,
    readabilityScore: result.readabilityScore,
    topTopics: result.topics || [],
    sentiment: result.sentiment || 'neutral',
    issues,
  };
}

Step 4: Check Links and Site Structure

Broken links hurt both user experience and SEO. Extract all links and verify they resolve correctly.

Typescript
interface LinkIssue {
  sourceUrl: string;
  targetUrl: string;
  type: 'broken' | 'redirect' | 'external-nofollow';
  statusCode?: number;
}

async function auditLinks(urls: string[]): Promise<LinkIssue[]> {
  const issues: LinkIssue[] = [];

  for (const url of urls) {
    const linksResult = await client.callTool({
      name: 'extract_links',
      arguments: {
        url,
        base_url: urls[0], // Use site root as base
      },
    });

    const links = JSON.parse(linksResult.content[0].text);

    // Check each internal link
    for (const link of links.internal || []) {
      try {
        const check = await client.callTool({
          name: 'fetch_url',
          arguments: { url: link.href, timeout: 5000 },
        });

        const response = JSON.parse(check.content[0].text);

        if (response.statusCode >= 400) {
          issues.push({
            sourceUrl: url,
            targetUrl: link.href,
            type: 'broken',
            statusCode: response.statusCode,
          });
        } else if (response.statusCode >= 300) {
          issues.push({
            sourceUrl: url,
            targetUrl: link.href,
            type: 'redirect',
            statusCode: response.statusCode,
          });
        }
      } catch {
        issues.push({
          sourceUrl: url,
          targetUrl: link.href,
          type: 'broken',
        });
      }
    }
  }

  return issues;
}

Step 5: Generate the Audit Report

Combine all findings into a prioritized report.

Typescript
interface SEOAuditReport {
  siteUrl: string;
  auditDate: string;
  totalPages: number;
  overallScore: number;
  criticalIssues: number;
  warnings: number;
  sections: {
    metadata: MetaIssue[];
    content: ContentScore[];
    links: LinkIssue[];
    sitemapGaps: string[];
  };
}

async function generateReport(siteUrl: string): Promise<SEOAuditReport> {
  // Run all audit steps
  const site = await crawlSite({
    url: siteUrl,
    maxPages: 200,
    maxDepth: 4,
  });

  const metaIssues = await auditMetadata(site.urls);
  const linkIssues = await auditLinks(site.urls.slice(0, 50)); // Top 50 pages

  // Analyze top pages by importance
  const topPages = site.urls.slice(0, 20);
  const contentScores: ContentScore[] = [];
  for (const url of topPages) {
    contentScores.push(await analyzePageContent(url));
  }

  const criticalCount = metaIssues.filter(i => i.type === 'error').length
    + linkIssues.filter(i => i.type === 'broken').length;

  const warningCount = metaIssues.filter(i => i.type === 'warning').length
    + contentScores.reduce((sum, s) => sum + s.issues.length, 0);

  // Score: start at 100, deduct for issues
  const score = Math.max(0, 100 - (criticalCount * 5) - (warningCount * 2));

  return {
    siteUrl,
    auditDate: new Date().toISOString(),
    totalPages: site.totalPages,
    overallScore: score,
    criticalIssues: criticalCount,
    warnings: warningCount,
    sections: {
      metadata: metaIssues,
      content: contentScores,
      links: linkIssues,
      sitemapGaps: site.missingFromSitemap,
    },
  };
}

Credit Cost Analysis

For a 200-page site audit:

OperationToolCreditsQuantitySubtotal
Site mappingmap_site313
Deep crawlcrawl_deep515
Metadata (batch)batch_scrape54 batches20
Content analysisanalyze_content320 pages60
Content extractionextract_content220 pages40
Link extractionextract_links150 pages50
Link verificationfetch_url1200 checks200
Total per audit378 credits

Running monthly audits costs about 378 credits -- well within the Hobby plan's 3,000 monthly credits. The Free tier (1,000 credits) covers 2-3 full audits.

Results and Benefits

Automated SEO audits with CrawlForge deliver:

  • Speed: Complete a 200-page audit in 15 minutes instead of 8 hours
  • Consistency: Same checks every time, no human oversight gaps
  • Frequency: Move from quarterly to weekly audits without added cost
  • Prioritization: Issues ranked by severity so you fix what matters first

Teams using automated SEO auditing typically see a 15-25% improvement in technical SEO scores within 3 months, according to Ahrefs' research on technical SEO impact.

Frequently Asked Questions

How does this compare to paid SEO audit tools like Screaming Frog?

CrawlForge's audit pipeline is more flexible because you control exactly what gets checked and how issues are scored. Tools like Screaming Frog cost $259/year for a desktop license, while CrawlForge's credit model lets you run audits on-demand. CrawlForge is best for teams that want programmable, AI-integrated SEO workflows rather than a GUI tool.

Can I schedule audits to run automatically?

Yes. Wrap the generateReport function in a cron job or serverless function (Vercel Cron, AWS Lambda) and trigger it on your preferred schedule. Weekly audits are the sweet spot for most sites.

What about JavaScript-rendered pages?

CrawlForge handles JavaScript rendering automatically. For pages that require interaction (clicking tabs, expanding sections), use scrape_with_actions to render the full content before analysis.


Start auditing your site today. Get 1,000 free credits -- enough for 2-3 complete site audits. No credit card required.

Related resources:

  • 18 Web Scraping Tools in One MCP Server
  • CrawlForge Documentation
  • Use Cases

Try this yourself — no signup needed

Run any of CrawlForge's 27 scraping and extraction tools in the playground, then start free with 1,000 credits.

1,000 free credits • Refills monthly • No credit card required

Tags

seo-audittechnical-seoweb-scrapingautomationsite-crawlingmcpai-engineering

About the Author

C

CrawlForge Team

Engineering Team

Building the most comprehensive web scraping MCP server. We create tools that help developers extract, analyze, and transform web data for AI applications.

Stay updated with the latest insights

Get tutorials, product updates, and web scraping tips delivered to your inbox.

No spam. Unsubscribe anytime.

Put this into practice

Test CrawlForge's tools on any URL — free, no signup.

On this page

Related Articles

Build a Research Agent with CrawlForge Deep Research
Use Cases

Build a Research Agent with CrawlForge Deep Research

Create an AI research agent that gathers, verifies, and synthesizes information from dozens of sources in minutes using CrawlForge deep_research.

C
CrawlForge Team
|
Apr 16
|
10m
Build a Lead Enrichment Engine with CrawlForge
Use Cases

Build a Lead Enrichment Engine with CrawlForge

Enrich sales leads with company data, tech stacks, and contact details automatically. Scrape public business data to qualify leads and prioritize outreach.

C
CrawlForge Team
|
Apr 14
|
10m
Content Migration Automation with CrawlForge
Use Cases

Content Migration Automation with CrawlForge

Migrate website content between CMS platforms automatically. Extract pages, preserve structure, and rebuild content in your new system without rewrites.

C
CrawlForge Team
|
Apr 12
|
9m

Footer

CrawlForge

Enterprise web scraping for AI Agents. 27 specialized MCP tools designed for modern developers building intelligent systems.

Product

  • Features
  • Playground
  • Pricing
  • Use Cases
  • Integrations
  • Alternatives
  • Changelog

Resources

  • Getting Started
  • API Reference
  • Templates
  • Guides
  • Blog
  • Glossary
  • FAQ
  • Sitemap

Developers

  • MCP Protocol
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

Company

  • About
  • Contact
  • Privacy
  • Terms
  • Acceptable Use
  • Cookies

Stay updated

Get the latest updates on new tools and features.

Built with Next.js and MCP protocol

© 2025-2026 CrawlForge. All rights reserved.