Skills Agentes

Search Console

Extrae datos de Google Search Console y analiza rendimiento en búsqueda: rankings, clics, impresiones, CTR, cobertura de índice, Core Web Vitals y estado de sitemaps.

Estrellas
688

en todo el repo

Actividad
25

0–100, la ruta de este skill

Actualizado
hace 7 meses

último commit aquí

Commits
0

últimos 90 días

Contexto
3.1k tok

106 tok en reposo

Paquete
1 archivo

12 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add OpenClaudia/openclaudia-skills --skill search-console --agent claude-code

Se instala solo en este repositorio.

Este skill makes network requests, needs API credentials.

Qué hace

  • Consulta la API de Google Search Console para clics, impresiones, CTR y posición media
  • Inspecciona el estado de indexación de URLs concretas mediante la URL Inspection API
  • Lista y verifica el estado de los sitemaps enviados
  • Detecta oportunidades SEO: baja CTR con muchas impresiones, keywords en 'striking distance' y canibalización
  • Genera un informe completo de auditoría de Search Console con métricas comparadas

Úsalo cuando

  • Se pregunta por rankings de búsqueda, clics, impresiones o CTR
  • Se necesita cobertura de índice, Core Web Vitals o estado de sitemap
  • Se pide inspección de URL o datos de posición de keywords
  • Se solicita una auditoría completa de rendimiento en buscadores

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • Dame las queries con más impresiones y bajo CTR del último trimestre
    • Revisa el estado de indexación de esta URL en Search Console
    • Haz una auditoría completa de Search Console para example.com
    • Encuentra canibalización de keywords entre páginas del blog

    SKILL.md

    En inglés

    Google Search Console

    Pull search performance data, index coverage, and Core Web Vitals from Google Search Console API.

    Prerequisites

    Requires Google OAuth credentials:

    • GOOGLE_CLIENT_ID
    • GOOGLE_CLIENT_SECRET
    • A valid OAuth access token with https://www.googleapis.com/auth/webmasters.readonly scope

    Set credentials in .env, .env.local, or ~/.claude/.env.global.

    Getting an Access Token

    # Step 1: Authorization URL (user visits in browser)
    echo "https://accounts.google.com/o/oauth2/v2/auth?client_id=${GOOGLE_CLIENT_ID}&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=https://www.googleapis.com/auth/webmasters.readonly&response_type=code&access_type=offline"
    
    # Step 2: Exchange code for tokens
    curl -s -X POST "https://oauth2.googleapis.com/token" \
      -d "code={AUTH_CODE}" \
      -d "client_id=${GOOGLE_CLIENT_ID}" \
      -d "client_secret=${GOOGLE_CLIENT_SECRET}" \
      -d "redirect_uri=urn:ietf:wg:oauth:2.0:oob" \
      -d "grant_type=authorization_code"
    
    # Step 3: Refresh expired token
    curl -s -X POST "https://oauth2.googleapis.com/token" \
      -d "refresh_token={REFRESH_TOKEN}" \
      -d "client_id=${GOOGLE_CLIENT_ID}" \
      -d "client_secret=${GOOGLE_CLIENT_SECRET}" \
      -d "grant_type=refresh_token"
    

    Listing Available Sites

    curl -s -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      "https://www.googleapis.com/webmasters/v3/sites" \
      | python3 -c "
    import json, sys
    data = json.load(sys.stdin)
    for site in data.get('siteEntry', []):
        print(f\"{site['siteUrl']}  |  Permission: {site['permissionLevel']}\")
    "
    

    The site URL format is either https://example.com/ (URL prefix) or sc-domain:example.com (domain property).


    1. Search Performance Report

    The core report: queries, pages, clicks, impressions, CTR, and average position.

    API Endpoint

    POST https://www.googleapis.com/webmasters/v3/sites/{siteUrl}/searchAnalytics/query
    

    Note: The {siteUrl} must be URL-encoded (e.g., https%3A%2F%2Fexample.com%2F or sc-domain%3Aexample.com).

    Top Queries

    curl -s -X POST \
      "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
      -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "startDate": "2024-01-01",
        "endDate": "2024-03-31",
        "dimensions": ["query"],
        "rowLimit": 50,
        "startRow": 0
      }'
    

    Top Pages

    curl -s -X POST \
      "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
      -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "startDate": "2024-01-01",
        "endDate": "2024-03-31",
        "dimensions": ["page"],
        "rowLimit": 50
      }'
    

    Query + Page Combination

    curl -s -X POST \
      "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
      -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "startDate": "2024-01-01",
        "endDate": "2024-03-31",
        "dimensions": ["query", "page"],
        "rowLimit": 100,
        "dimensionFilterGroups": [{
          "filters": [{
            "dimension": "page",
            "operator": "contains",
            "expression": "/blog/"
          }]
        }]
      }'
    

    Available Dimensions

    Dimension Description
    query Search query
    page URL
    country Country code (ISO 3166-1 alpha-3)
    device DESKTOP, MOBILE, TABLET
    date Individual date
    searchAppearance Rich result type

    Response Parsing

    curl -s -X POST "..." | python3 -c "
    import json, sys
    data = json.load(sys.stdin)
    print(f\"{'Query':<50} {'Clicks':>8} {'Impr':>8} {'CTR':>8} {'Pos':>6}\")
    print('-' * 82)
    for row in data.get('rows', []):
        keys = ' + '.join(row.get('keys', []))
        print(f\"{keys:<50} {row['clicks']:>8} {row['impressions']:>8} {row['ctr']*100:>7.1f}% {row['position']:>6.1f}\")
    "
    

    2. Search Performance by Date

    Track daily trends for queries and pages.

    curl -s -X POST \
      "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
      -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "startDate": "2024-01-01",
        "endDate": "2024-03-31",
        "dimensions": ["date"],
        "rowLimit": 1000
      }'
    

    To track a specific query over time:

    curl -s -X POST \
      "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
      -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "startDate": "2024-01-01",
        "endDate": "2024-03-31",
        "dimensions": ["date"],
        "dimensionFilterGroups": [{
          "filters": [{
            "dimension": "query",
            "operator": "equals",
            "expression": "your target keyword"
          }]
        }]
      }'
    

    3. Index Coverage (URL Inspection API)

    Check if a specific URL is indexed.

    Endpoint

    POST https://searchconsole.googleapis.com/v1/urlInspection/index:inspect
    

    Example curl

    curl -s -X POST \
      "https://searchconsole.googleapis.com/v1/urlInspection/index:inspect" \
      -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "inspectionUrl": "https://example.com/page-to-check",
        "siteUrl": "sc-domain:example.com"
      }'
    

    Response Fields

    Field Description
    inspectionResult.indexStatusResult.coverageState Submitted and indexed, Crawled - currently not indexed, etc.
    inspectionResult.indexStatusResult.robotsTxtState ALLOWED or DISALLOWED
    inspectionResult.indexStatusResult.indexingState INDEXING_ALLOWED or INDEXING_NOT_ALLOWED
    inspectionResult.indexStatusResult.lastCrawlTime When Googlebot last crawled
    inspectionResult.indexStatusResult.crawledAs DESKTOP or MOBILE
    inspectionResult.mobileUsabilityResult.verdict PASS, FAIL, or VERDICT_UNSPECIFIED

    4. Sitemaps

    List and check sitemap status.

    List Sitemaps

    curl -s -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/sitemaps" \
      | python3 -c "
    import json, sys
    data = json.load(sys.stdin)
    for sm in data.get('sitemap', []):
        print(f\"URL: {sm['path']}\")
        print(f\"  Type: {sm.get('type','')}  |  Submitted: {sm.get('lastSubmitted','')}\")
        print(f\"  URLs discovered: {sm.get('contents',[{}])[0].get('submitted','?')}  |  Indexed: {sm.get('contents',[{}])[0].get('indexed','?')}\")
        print()
    "
    

    Submit a Sitemap

    curl -s -X PUT -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/sitemaps/https%3A%2F%2Fexample.com%2Fsitemap.xml"
    

    5. Opportunity Identification

    Use Search Console data to find SEO opportunities.

    Low-Hanging Fruit: High Impressions, Low CTR

    Queries with many impressions but low CTR suggest the title/description needs optimization.

    # Pull queries, then filter for: impressions > 100 AND ctr < 0.03 AND position < 20
    curl -s -X POST \
      "https://www.googleapis.com/webmasters/v3/sites/sc-domain%3Aexample.com/searchAnalytics/query" \
      -H "Authorization: Bearer ${GSC_ACCESS_TOKEN}" \
      -H "Content-Type: application/json" \
      -d '{
        "startDate": "2024-01-01",
        "endDate": "2024-03-31",
        "dimensions": ["query", "page"],
        "rowLimit": 1000
      }' | python3 -c "
    import json, sys
    data = json.load(sys.stdin)
    print('== Low CTR Opportunities (High impressions, low CTR, good position) ==')
    print(f\"{'Query':<40} {'Page':<40} {'Impr':>6} {'CTR':>7} {'Pos':>5}\")
    for row in data.get('rows', []):
        if row['impressions'] > 100 and row['ctr'] < 0.03 and row['position'] < 20:
            print(f\"{row['keys'][0]:<40} {row['keys'][1][-40:]:<40} {row['impressions']:>6} {row['ctr']*100:>6.1f}% {row['position']:>5.1f}\")
    "
    

    Striking Distance: Position 5-20

    Queries ranking on page 1-2 that could be pushed to top 5 with content optimization.

    # Filter for position between 5 and 20 with decent impressions
    curl -s -X POST "..." | python3 -c "
    import json, sys
    data = json.load(sys.stdin)
    print('== Striking Distance Keywords (Position 5-20) ==')
    opps = [r for r in data.get('rows',[]) if 5 <= r['position'] <= 20 and r['impressions'] > 50]
    opps.sort(key=lambda x: x['impressions'], reverse=True)
    for row in opps[:30]:
        print(f\"{row['keys'][0]:<50} Pos: {row['position']:>5.1f}  Impr: {row['impressions']:>6}  Clicks: {row['clicks']:>4}\")
    "
    

    Cannibalization Detection

    Find queries where multiple pages compete for the same keyword.

    # Pull query+page data, then group by query to find duplicates
    curl -s -X POST "..." | python3 -c "
    import json, sys
    from collections import defaultdict
    data = json.load(sys.stdin)
    query_pages = defaultdict(list)
    for row in data.get('rows', []):
        query_pages[row['keys'][0]].append({
            'page': row['keys'][1],
            'clicks': row['clicks'],
            'impressions': row['impressions'],
            'position': row['position']
        })
    print('== Keyword Cannibalization (multiple pages for same query) ==')
    for query, pages in sorted(query_pages.items(), key=lambda x: -sum(p['impressions'] for p in x[1])):
        if len(pages) > 1:
            total_impr = sum(p['impressions'] for p in pages)
            if total_impr > 100:
                print(f\"\nQuery: {query} ({total_impr} total impressions)\")
                for p in sorted(pages, key=lambda x: -x['impressions']):
                    print(f\"  {p['page'][-60:]}  Pos: {p['position']:.1f}  Impr: {p['impressions']}  Clicks: {p['clicks']}\")
    "
    

    Workflow: Full Search Performance Audit

    When asked for a complete GSC audit:

    1. Overall Metrics: Total clicks, impressions, avg CTR, avg position for last 90 days vs previous 90 days
    2. Top 30 Queries: By clicks, with CTR and position
    3. Top 20 Pages: By clicks, with CTR and position
    4. Device Breakdown: Desktop vs mobile performance
    5. Low-Hanging Fruit: High impressions + low CTR opportunities
    6. Striking Distance: Position 5-20 keywords with optimization potential
    7. Cannibalization: Queries with multiple competing pages
    8. Index Coverage: Spot-check important URLs
    9. Sitemap Health: Verify sitemaps are submitted and indexed

    Report Format

    ## Search Console Audit: {domain}
    ### Period: {date range}
    
    ### Summary
    | Metric | Current | Previous | Change |
    |--------|---------|----------|--------|
    | Clicks | X | Y | +Z% |
    | Impressions | X | Y | +Z% |
    | Avg CTR | X% | Y% | +Z pp |
    | Avg Position | X | Y | +Z |
    
    ### Top Queries
    | Query | Clicks | Impressions | CTR | Position |
    |-------|--------|-------------|-----|----------|
    | ...   | ...    | ...         | ... | ...      |
    
    ### Optimization Opportunities
    
    #### Title/Description Optimization (High Impressions, Low CTR)
    1. "{query}" - {impressions} impressions, {ctr}% CTR, position {pos}
       - Page: {url}
       - Recommendation: ...
    
    #### Content Optimization (Striking Distance)
    1. "{query}" - position {pos}, {impressions} impressions
       - Action: Add {query} to H2, expand section on {topic}
    
    #### Cannibalization Fixes
    1. "{query}" appears on {n} pages
       - Consolidate to: {best_url}
       - Redirect/noindex: {other_urls}
    

    Rate Limits

    • Search Analytics API: 1,200 queries per minute
    • URL Inspection API: 2,000 inspections per day per property
    • Data freshness: Search data is typically 2-3 days behind

    Common Errors

    Error Cause Fix
    403 No access to this property Verify ownership in GSC
    400 Invalid date range Dates must be within last 16 months
    Empty rows No data matching filters Broaden date range or remove filters

    Reproducido de OpenClaudia/openclaudia-skills bajo licencia MIT. Leer esta página en markdown.

    Archivos

    1 archivo en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Antes de instalar

    Requiere credenciales OAuth de Google (GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET) y un token de acceso con el scope webmasters.readonly.

    Necesita en el PATH:curlpython3

    Variables de entorno:GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRETGSC_ACCESS_TOKEN

    Detalles

    Categoría
    SEO y GEO
    Licencia
    MIT
    Recursos incluidos
    Solo SKILL.md
    Código fuente
    Ver SKILL.md

    Más de OpenClaudia/openclaudia-skills

    Este repo incluye 76 skills. Si instalas uno, normalmente ya tienes los demás. Ver el pack openclaudia-skills entero y su comando de instalación

    Genera un informe HTML autocontenible de tráfico competitivo: visitas mensuales (SimilarWeb), tráfico orgánico y Domain Rating (Ahrefs), con gráficos ranked, tendencias y tabla de datos.

    Costo de contexto al activarse
    1.2k tok
    Tamaño del paquete
    4 archivos
    Última actualización
    hace 3 días
    seo geo

    Obtiene datos de marca (nombre, descripción, logos, industria) desde la API de brand.dev y guarda los logos localmente.

    Costo de contexto al activarse
    702 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    datos analitica

    Audita TODAS las propiedades de Google Search Console a la vez: ranking por clics e impresiones con deltas, y diff de keywords por sitio (nuevas, suben, bajan, perdidas, o bien rankeadas sin clics).

    Costo de contexto al activarse
    1k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    el mes pasado
    seo geo

    Edita audio o video de podcast: recorta charla previa/posterior, quita muletillas, corta silencios, mejora el audio y aplica el mismo corte a una versión en video.

    Costo de contexto al activarse
    6k tok
    Tamaño del paquete
    3 archivos
    Última actualización
    el mes pasado
    redaccion contenido

    Clasifica y resume el feed de WeChat Moments (朋友圈) del usuario para que los eventos reales y la información genuina destaquen sobre la promoción, ponderando según cuánto le escribe el usuario a cada autor.

    Costo de contexto al activarse
    1.2k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    redes sociales

    Genera un informe de Citaciones de IA (GEO) para un dominio: qué prompts de búsqueda con IA citan el sitio en Google AI Overview y ChatGPT, con contexto de tráfico orgánico y cobertura por artículo.

    Costo de contexto al activarse
    840 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    seo geo

    Skills relacionados

    Ai Seo

    47.8k

    Úsalo cuando el usuario quiera optimizar contenido para motores de IA, ser citado por LLMs o aparecer en respuestas generadas por IA (AEO, GEO, llms.txt, agent readiness, etc.).

    Costo de contexto al activarse
    7.4k tok
    Tamaño del paquete
    10 archivos
    Última actualización
    hace 6 días
    seo geo

    Cuando el usuario quiere crear páginas orientadas a SEO a escala usando plantillas y datos, como páginas de directorio, ubicación, comparación o integración (pSEO).

    Costo de contexto al activarse
    1.8k tok
    Tamaño del paquete
    3 archivos
    Última actualización
    hace 4 meses
    seo geo

    Schema

    47.8k

    Para cuando quieras añadir, corregir u optimizar schema markup y datos estructurados: JSON-LD, rich snippets, FAQ schema, product schema, breadcrumb schema y resultados enriquecidos en Google.

    Costo de contexto al activarse
    1.3k tok
    Tamaño del paquete
    3 archivos
    Última actualización
    hace 4 meses
    seo geo