---
title: "AI Keyword Research Tools"
description: "MCP tools for keyword research and SERP analysis. Find long-tail keywords, analyze competition, and discover content gaps—through your AI assistant."
canonical_url: "https://nuxtseo.com/pro/docs/reference/mcp/keyword-research"
last_updated: "2026-05-06T21:34:39.303Z"
---

Keyword research and competitive analysis through your AI. Ask for keywords, analyze SERPs, check what competitors rank for - all powered by DataForSEO. Requires a Pro API key.

## keyword_research

Unified keyword research tool. Use the `type` parameter to select research mode.

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        type
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        research
      </code>
    </td>
    
    <td>
      <code>
        research
      </code>
      
      , <code>
        serp
      </code>
      
      , or <code>
        rankings
      </code>
    </td>
  </tr>
</tbody>
</table>

### type: research

Find long-tail keywords with search volume, difficulty, and CPC.

<callout type="info">

Works best with consumer-facing search terms. Technical or niche developer topics may return limited data. For those, use `type: 'serp'` to see what content ranks.

</callout>

<table>
<thead>
  <tr>
    <th>
      Extra Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        topic
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      required
    </td>
    
    <td>
      Seed topic or keyword
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        minVolume
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      Minimum monthly search volume
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maxVolume
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        10000
      </code>
    </td>
    
    <td>
      Maximum monthly search volume
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maxDifficulty
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        60
      </code>
    </td>
    
    <td>
      Maximum keyword difficulty (0-100)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        includeRelated
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Include "searches related to" keywords
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        verbose
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Return full data including trends and SERP features
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        limit
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        20
      </code>
    </td>
    
    <td>
      Max keywords to return (1-50)
    </td>
  </tr>
</tbody>
</table>

```ts
keyword_research({
  type: 'research',
  topic: 'nuxt meta tags',
  maxDifficulty: 30,
  limit: 10
})
```

Returns:

```json
{
  "topic": "nuxt meta tags",
  "keywords": [
    {
      "keyword": "nuxt 4 meta tags",
      "vol": 320,
      "diff": 24,
      "intent": "informational",
      "cpc": 0.45
    }
  ],
  "totalFound": 156,
  "filters": {
    "minVolume": 10,
    "maxVolume": 10000,
    "maxDifficulty": 30
  }
}
```

#### Keyword Difficulty Scale

<table>
<thead>
  <tr>
    <th>
      Difficulty
    </th>
    
    <th>
      Meaning
    </th>
    
    <th>
      Strategy
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      0-20
    </td>
    
    <td>
      Easy
    </td>
    
    <td>
      New sites can rank with quality content
    </td>
  </tr>
  
  <tr>
    <td>
      21-40
    </td>
    
    <td>
      Medium
    </td>
    
    <td>
      Needs solid content + some authority
    </td>
  </tr>
  
  <tr>
    <td>
      41-60
    </td>
    
    <td>
      Hard
    </td>
    
    <td>
      Requires established domain + links
    </td>
  </tr>
  
  <tr>
    <td>
      61-100
    </td>
    
    <td>
      Extreme
    </td>
    
    <td>
      Only high-authority sites compete
    </td>
  </tr>
</tbody>
</table>

### type: serp

Analyze SERP competition for a keyword. Returns top results with domain rank and SERP features present.

<table>
<thead>
  <tr>
    <th>
      Extra Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        topic
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      required
    </td>
    
    <td>
      Keyword to analyze
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        depth
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        10
      </code>
    </td>
    
    <td>
      Number of results (1-20)
    </td>
  </tr>
</tbody>
</table>

```ts
keyword_research({
  type: 'serp',
  topic: 'nuxt schema.org',
  depth: 10
})
```

Returns:

```json
{
  "keyword": "nuxt schema.org",
  "results": [
    {
      "position": 1,
      "url": "https://nuxtseo.com/docs/schema-org/getting-started",
      "title": "Getting Started - Schema.org",
      "domain": "nuxtseo.com",
      "domainRank": 45
    }
  ],
  "serpFeatures": ["featured_snippet", "people_also_ask"],
  "hasAiOverview": false,
  "hasFeaturedSnippet": true,
  "hasPeopleAlsoAsk": true
}
```

#### SERP Feature Types

<table>
<thead>
  <tr>
    <th>
      Feature
    </th>
    
    <th>
      What It Means
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        ai_overview
      </code>
    </td>
    
    <td>
      Google AI Overview appears - harder to get clicks
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        featured_snippet
      </code>
    </td>
    
    <td>
      Snippet opportunity - structure content for it
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        people_also_ask
      </code>
    </td>
    
    <td>
      FAQ opportunity - answer related questions
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        local_pack
      </code>
    </td>
    
    <td>
      Local results - need LocalBusiness schema
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        video
      </code>
    </td>
    
    <td>
      Video results - consider video content
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        images
      </code>
    </td>
    
    <td>
      Image pack - optimize image SEO
    </td>
  </tr>
</tbody>
</table>

### type: rankings

Check what keywords a domain ranks for. Useful for competitor analysis and finding content gaps.

<table>
<thead>
  <tr>
    <th>
      Extra Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        domain
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      required
    </td>
    
    <td>
      Domain to check (without https://)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        limit
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        50
      </code>
    </td>
    
    <td>
      Max keywords to return (1-100)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        minPosition
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        1
      </code>
    </td>
    
    <td>
      Minimum ranking position
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        maxPosition
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        20
      </code>
    </td>
    
    <td>
      Maximum ranking position
    </td>
  </tr>
</tbody>
</table>

```ts
keyword_research({
  type: 'rankings',
  domain: 'competitor.com',
  maxPosition: 10,
  limit: 30
})
```

Returns:

```json
{
  "domain": "competitor.com",
  "keywords": [
    {
      "keyword": "vue seo guide",
      "position": 3,
      "volume": 480,
      "traffic": 156,
      "url": "https://competitor.com/blog/vue-seo"
    }
  ],
  "positionRange": { "min": 1, "max": 10 }
}
```

#### Content Gap Analysis

Compare your rankings to competitors:

1. Run `keyword_research({ type: 'rankings' })` on your domain
2. Run it on 2-3 competitors
3. Find keywords they rank for that you don't
4. Create content targeting those gaps

## get_sitemap_urls

Get URLs from a verified site's sitemap. Useful for content audits and analysis.

<table>
<thead>
  <tr>
    <th>
      Parameter
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        siteUrl
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      required
    </td>
    
    <td>
      Site URL (must be verified in your Pro account)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        limit
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        15
      </code>
    </td>
    
    <td>
      Max URLs to return (1-50)
    </td>
  </tr>
</tbody>
</table>

```ts
get_sitemap_urls({
  siteUrl: 'https://mysite.com',
  limit: 10
})
```

The tool sorts URLs by path depth (deeper = more likely to be content pages). It skips sitemap indexes, API routes, and internal routes.

## Data Freshness

<table>
<thead>
  <tr>
    <th>
      Tool
    </th>
    
    <th>
      Cache Duration
    </th>
    
    <th>
      Data Source
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        keyword_research
      </code>
      
       (research)
    </td>
    
    <td>
      24 hours
    </td>
    
    <td>
      DataForSEO keyword database
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        keyword_research
      </code>
      
       (serp)
    </td>
    
    <td>
      12 hours
    </td>
    
    <td>
      Live SERP results
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        keyword_research
      </code>
      
       (rankings)
    </td>
    
    <td>
      24 hours
    </td>
    
    <td>
      DataForSEO ranking database
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        get_sitemap_urls
      </code>
    </td>
    
    <td>
      1 hour
    </td>
    
    <td>
      Live sitemap fetch
    </td>
  </tr>
</tbody>
</table>

## Troubleshooting

### Empty keyword results

If `keyword_research` with `type: 'research'` returns no keywords:

1. **Topic too niche** - Developer-focused terms like "nuxt sitemap configuration" have limited keyword data. Try broader terms like "sitemap generator" or "xml sitemap"
2. **Try type: 'serp' instead** - See what content ranks for your term, even without keyword volume data
3. **Use shorter phrases** - 2-3 word queries work better than long-tail phrases
