Tutorial

How to Build Custom Claude Code SEO Skill

Create a reusable Claude Code skill for SEO audits. Rank checks, SERP analysis, and competitor gaps in one command.

Claude Code skills let you package repeatable workflows into one-command tools. This tutorial builds an SEO skill that checks rankings, analyzes SERP features, finds keyword gaps, and generates optimization recommendations. Once built, run it with a single slash command on any domain.

Prerequisites

  • Claude Code installed
  • Scavio MCP configured
  • A Scavio API key from scavio.dev
  • Basic understanding of Claude Code skills

Walkthrough

Step 1: Define the SEO skill structure

Create the skill file with input parameters and workflow steps.

Python
import os, requests, json

API_KEY = os.environ['SCAVIO_API_KEY']
SH = {'x-api-key': API_KEY, 'Content-Type': 'application/json'}

# Claude Code skill definition
seo_skill = {
    'name': 'seo-audit',
    'description': 'Run a quick SEO audit on a domain: rank check, SERP features, keyword gaps.',
    'inputs': {
        'domain': 'Target domain to audit',
        'keywords': 'Comma-separated keywords to check (optional)',
        'competitors': 'Comma-separated competitor domains (optional)'
    }
}

def rank_check(domain, keywords):
    """Check domain position for each keyword."""
    results = []
    for kw in keywords:
        data = requests.post('https://api.scavio.dev/api/v1/search',
            headers=SH, json={'query': kw, 'country_code': 'us'}).json()
        organic = data.get('organic_results', [])
        position = None
        for i, r in enumerate(organic):
            if domain in r.get('link', ''):
                position = i + 1
                break
        results.append({'keyword': kw, 'position': position})
        pos_str = f'#{position}' if position else 'Not found'
        print(f'  {kw:40} | {pos_str}')
    return results

print('SEO Skill: rank_check')
rank_check('scavio.dev', ['search api', 'serp api python', 'mcp search tool'])
print(f'Cost: $0.015')

Step 2: Add SERP feature analysis

Detect AI Overviews, PAA, featured snippets, and local packs for each keyword.

Python
def serp_analysis(keywords):
    """Analyze SERP features for each keyword."""
    print(f'\n=== SERP Feature Analysis ===')
    for kw in keywords:
        data = requests.post('https://api.scavio.dev/api/v1/search',
            headers=SH, json={'query': kw, 'country_code': 'us'}).json()
        features = []
        if data.get('ai_overview') or data.get('answer_box'):
            features.append('AIO')
        if data.get('people_also_ask'):
            features.append(f'PAA({len(data["people_also_ask"])})')
        if data.get('featured_snippet'):
            features.append('Featured')
        if data.get('local_results'):
            features.append('Local')
        if data.get('shopping_results'):
            features.append('Shopping')
        feature_str = ' | '.join(features) if features else 'Organic only'
        print(f'  {kw:40} | {feature_str}')
    return features

def keyword_gaps(domain, competitors, keywords):
    """Find keywords where competitors rank but you do not."""
    print(f'\n=== Keyword Gaps ===')
    gaps = []
    for kw in keywords:
        data = requests.post('https://api.scavio.dev/api/v1/search',
            headers=SH, json={'query': kw, 'country_code': 'us'}).json()
        organic = data.get('organic_results', [])
        domain_found = any(domain in r.get('link', '') for r in organic)
        comp_found = [c for c in competitors if any(c in r.get('link', '') for r in organic)]
        if not domain_found and comp_found:
            gaps.append({'keyword': kw, 'competitors_ranking': comp_found})
            print(f'  GAP: "{kw}" - {len(comp_found)} competitors rank, you do not')
    if not gaps:
        print(f'  No gaps found - you rank for all checked keywords.')
    return gaps

serp_analysis(['search api', 'serp api comparison'])
keyword_gaps('scavio.dev', ['tavily.com', 'serpapi.com'], ['web scraping api', 'data extraction api'])

Step 3: Package as a complete skill

Combine all checks into one skill function with a summary report.

Python
def seo_audit_skill(domain, keywords=None, competitors=None):
    """Complete SEO audit skill for Claude Code."""
    if keywords is None:
        keywords = [domain.replace('.com', '').replace('.dev', ''), f'{domain} alternative']
    if competitors is None:
        competitors = []
    print(f'\n{"=" * 60}')
    print(f'  SEO AUDIT: {domain}')
    print(f'  Date: 2026-05-20')
    print(f'  Keywords: {len(keywords)} | Competitors: {len(competitors)}')
    print(f'{"=" * 60}')
    # 1. Rank check
    print(f'\n--- Rankings ---')
    ranks = rank_check(domain, keywords)
    ranked = sum(1 for r in ranks if r['position'])
    # 2. SERP features
    print(f'\n--- SERP Features ---')
    serp_analysis(keywords)
    # 3. Keyword gaps
    if competitors:
        keyword_gaps(domain, competitors, keywords)
    # Summary
    total_queries = len(keywords) * 2 + (len(keywords) if competitors else 0)
    print(f'\n--- Summary ---')
    print(f'  Ranking: {ranked}/{len(keywords)} keywords')
    avg_pos = sum(r['position'] for r in ranks if r['position']) / ranked if ranked else 0
    print(f'  Avg position: #{avg_pos:.1f}' if ranked else '  Avg position: N/A')
    print(f'  Cost: ${total_queries * 0.005:.3f}')
    print(f'\n  Usage: /seo-audit {domain}')

seo_audit_skill('scavio.dev', 
    keywords=['search api', 'serp api python', 'mcp search tool'],
    competitors=['tavily.com', 'serpapi.com'])

Python Example

Python
import os, requests
SH = {'x-api-key': os.environ['SCAVIO_API_KEY'], 'Content-Type': 'application/json'}

def quick_seo(domain, keyword):
    data = requests.post('https://api.scavio.dev/api/v1/search',
        headers=SH, json={'query': keyword, 'country_code': 'us'}).json()
    for i, r in enumerate(data.get('organic_results', [])):
        if domain in r.get('link', ''):
            print(f'{domain} ranks #{i+1} for "{keyword}"')
            return
    print(f'{domain} not in top 10 for "{keyword}"')

quick_seo('scavio.dev', 'search api for ai agents')
print('Cost: $0.005')

JavaScript Example

JavaScript
const SH = { 'x-api-key': process.env.SCAVIO_API_KEY, 'Content-Type': 'application/json' };
const data = await fetch('https://api.scavio.dev/api/v1/search', {
  method: 'POST', headers: SH,
  body: JSON.stringify({ query: 'search api for ai agents', country_code: 'us' })
}).then(r => r.json());
const pos = (data.organic_results || []).findIndex(r => r.link?.includes('scavio.dev'));
console.log(pos >= 0 ? `scavio.dev ranks #${pos+1}` : 'Not in top 10');

Expected Output

JSON
============================================================
  SEO AUDIT: scavio.dev
  Date: 2026-05-20
  Keywords: 3 | Competitors: 2
============================================================

--- Rankings ---
  search api                               | #2
  serp api python                          | #5
  mcp search tool                          | #3

--- SERP Features ---
  search api                               | AIO | PAA(4)
  serp api python                          | Featured
  mcp search tool                          | AIO

--- Summary ---
  Ranking: 3/3 keywords
  Avg position: #3.3
  Cost: $0.045

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

Claude Code installed. Scavio MCP configured. A Scavio API key from scavio.dev. Basic understanding of Claude Code skills. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Create a reusable Claude Code skill for SEO audits. Rank checks, SERP analysis, and competitor gaps in one command.