본문으로 건너뛰기
cccskills
무료GitHub에 공개

search-console

Pull Google Search Console data and perform search performance analysis. Use when asked about search rankings, clicks, impressions, CTR, index coverage, Core Web Vitals, or sitemap status. Trigger phrases: "search console", "GSC", "search performance", "clicks and impressions", "CTR analysis", "index coverage", "core web vitals", "URL inspection", "sitemap status", "ranking data", "search queries", "keyword positions".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

연동 도구Search Console
설치 방법 보기

포함된 파일(1)

  • SKILL.md12.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

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

DimensionDescription
querySearch query
pageURL
countryCountry code (ISO 3166-1 alpha-3)
deviceDESKTOP, MOBILE, TABLET
dateIndividual date
searchAppearanceRich 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

FieldDescription
inspectionResult.indexStatusResult.coverageStateSubmitted and indexed, Crawled - currently not indexed, etc.
inspectionResult.indexStatusResult.robotsTxtStateALLOWED or DISALLOWED
inspectionResult.indexStatusResult.indexingStateINDEXING_ALLOWED or INDEXING_NOT_ALLOWED
inspectionResult.indexStatusResult.lastCrawlTimeWhen Googlebot last crawled
inspectionResult.indexStatusResult.crawledAsDESKTOP or MOBILE
inspectionResult.mobileUsabilityResult.verdictPASS, 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

ErrorCauseFix
403No access to this propertyVerify ownership in GSC
400Invalid date rangeDates must be within last 16 months
Empty rowsNo data matching filtersBroaden date range or remove filters

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Design, plan, and analyze A/B tests with statistical rigor. Use when the user asks about A/B testing, split testing, experiment design, statistical significance, sample size calculation, test duration, multivariate testing, or conversion experiments. Trigger phrases include "A/B test", "split test", "experiment", "statistical significance", "sample size", "test duration", "which version wins", "conversion experiment", "hypothesis test", "variant testing".

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OpenClaudia/openclaudia-skills7172026년 10월 11일 업데이트

Build and manage an affiliate marketing program. Use when the user says "affiliate program", "affiliate marketing", "affiliate partners", "referral commissions", "affiliate network", "partner program", "affiliate tracking", or asks about creating, managing, or growing an affiliate or partner program.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OpenClaudia/openclaudia-skills7172026년 10월 11일 업데이트

Manages Ahrefs API usage in Python using `ahrefs-python` library. Use when working with SEO / marketing related tasks or with data including backlinks, keywords, domain ratings, organic traffic, site audits, rank tracking, and brand monitoring. Covers `ahrefs-python` usage including AhrefsClient / AsyncAhrefsClient, typed request/response models, error handling, and all API sections.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OpenClaudia/openclaudia-skills7172026년 10월 11일 업데이트

Generate an AI Citations Report (GEO) for a domain — which AI-search prompts cite the site across Google AI Overview and ChatGPT, plus organic-traffic context and per-article citation coverage. Use when the user asks for an 'AI citations report', 'GEO citations report', or 'which AI prompts cite <domain>'.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OpenClaudia/openclaudia-skills7172026년 10월 11일 업데이트

Research and enrich B2B leads using the Apollo.io API. Use when the user says "find leads", "prospect research", "company enrichment", "find decision makers", "B2B leads", "lead research", "enrich contacts", "find VP of marketing at", or asks about finding people at specific companies or in specific roles.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OpenClaudia/openclaudia-skills7172026년 10월 11일 업데이트

Audit a domain's backlink profile using the SemRush API. Use when the user says "audit backlinks", "check my backlinks", "backlink analysis", "link profile", "toxic links", "disavow", "link building opportunities", "referring domains", "anchor text", or asks about a site's link authority.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

OpenClaudia/openclaudia-skills7172026년 10월 11일 업데이트

OpenClaudia의 스킬 모두 보기

이 스킬의 문제 신고