Claude
/ Skills / competitive-gap-mapper
competitive-gap-mapper

Competitive Gap Mapper

Map relation-level positioning gaps between a brand and 3-5 competitors using KeywordGraph. Builds a merged competitor corpus graph, then runs bidirectional difference analysis to surface shared commodity claims, competitor-owned territory, brand-owned defensive assets, and unclaimed white space. Output is an entity-level differential map.

name
competitive-gap-mapper
triggers
map competitive gaps · compare brands at entity level · identify positioning white space · run a positioning audit · "map gaps between [client] and [competitors]" · "positioning audit" · "entity-level competitive analysis" · "what do competitors say that we don't" · /competitive-gap-mapper
method
Relation-level graph differential

Competitive Gap Mapper Claude Skill

Compare a brand URL against N competitor URLs at the relation level. Build a merged competitor corpus graph, then run bidirectional difference analysis to surface positioning gaps and defensive assets. Output is an entity-level differential map.

Keyword-level competitive analysis misses positioning structure. Two brands can target the same keywords while making entirely different claims. Relation-level analysis catches what brands actually assert: their entity relationships, cluster ownership, and conceptual territory. This skill operates at that level.

Tools Required

ToolUse CaseKey Functions
KeywordGraph Relation-level graph analysis, overlap detection, difference extraction, persistent graph visualizationmerged_graph_from_texts, analyze_text, overlap_between_texts, difference_between_texts, create_knowledge_graph
Firecrawl (10% off) Pre-scrape all URLs before KeywordGraph analysis. Handles JS rendering and paywalls.firecrawl_scrape

When to Use

Input

Collect from the user:

  1. Brand URL (required): The brand's primary positioning URL. Usually homepage. May be a solutions page if targeting a specific category.
  2. Competitor URLs (required): 3-5 competitor URLs. Match URL type to the brand URL (homepages vs homepages, solutions vs solutions).
  3. Analysis scope (optional, default: "positioning"): positioning (homepage and primary positioning pages), solution (specific solution or category pages), or content (blog or resource hub comparison).
  4. Graph visuals (optional, default: no): Ask "Do you want to generate graph visuals of the competitive gap?" If yes, save persistent named graphs to KeywordGraph and render an inline territory diagram via the Visualizer.

The brand URL and competitor URLs can be provided as web URLs, pasted text content, or file paths to scraped content. If the user provides only a brand URL, ask for competitor URLs before proceeding.


Workflow

Step 1 — Scrape all URLs with Firecrawl

Scrape every URL (brand + all competitors) with Firecrawl before passing anything to KeywordGraph. This prevents KeywordGraph from fetching URLs directly, which causes timeouts on JS-heavy or slow-loading sites.

firecrawl-mcp:firecrawl_scrape
  url: [URL]
  formats: ["markdown"]
  onlyMainContent: true

Run this for each URL. Store the returned markdown content. These scraped texts are passed to all subsequent KeywordGraph calls via the text parameter instead of url. After scraping, validate:

Step 2 — Build the merged competitor corpus

Use merged_graph_from_texts to build a single combined positioning graph from all competitor content scraped in Step 1. Always pass content via the text parameter, never via url.

KeywordGraph:merged_graph_from_texts
  context: "Building merged competitor corpus graph from multiple competitor URLs to establish field positioning baseline."
  contexts:
    - { text: "[scraped content from competitor 1]" }
    - { text: "[scraped content from competitor 2]" }
    - { text: "[scraped content from competitor 3]" }
  includeStatements: true

From the response capture mainTopicalClusters, topRelations, mainConcepts, contentGaps, graphSummary, and statements. Save this as the competitor field baseline.

If the user requested graph visuals, persist the merged corpus as a named KeywordGraph graph:

KeywordGraph:create_knowledge_graph
  context: "Persisting merged competitor corpus as named graph for interactive visual exploration on KeywordGraph."
  graphName: "gap-map-competitors-[brand-slug]-[date]"
  text: "[concatenated statements from merged_graph_from_texts response]"

Capture the returned graph URL. This link goes in the final output. If merged_graph_from_texts times out, fall back to individual analyze_text calls per scraped text, manually aggregate clusters and relations, and note the degradation.

Step 3 — Build the brand graph

KeywordGraph:analyze_text
  context: "Analyzing brand URL to extract entity-level positioning graph for bidirectional competitive comparison."
  text: "[scraped content from brand URL]"
  includeGraph: true
  modifyAnalyzedText: "extractEntitiesOnly"

Capture brand topical clusters, top relations, main concepts, and structural gaps. This is the brand positioning baseline. If the user requested graph visuals, persist the brand graph with create_knowledge_graph (graphName gap-map-brand-[brand-slug]-[date]) and capture the returned graph URL.

Step 4 — Surface shared positioning territory

Run overlap analysis to find what the brand and the competitor field share.

KeywordGraph:overlap_between_texts
  context: "Extracting shared entity relations between brand and competitor field to identify commodity positioning claims."
  contexts:
    - { text: "[scraped content from brand URL]" }
    - { text: "[scraped content from competitor 1]" }
    - { text: "[scraped content from competitor 2]" }
    - { text: "[scraped content from competitor 3]" }
  includeStatements: true

The response surfaces relations and clusters appearing across both the brand and competitors. These are commodity claims: table stakes for category coverage, zero differentiation. For each shared cluster, record the cluster name, representative relations, and frequency across the corpus.

Step 5 — Surface competitor-owned territory (brand gaps)

Run difference analysis from the brand perspective.

KeywordGraph:difference_between_texts
  context: "Finding entity relations present in competitor field but absent from brand positioning to identify coverage gaps."
  contexts:
    - { text: "[scraped content from brand URL]" }
    - { text: "[scraped content from competitor 1]" }
    - { text: "[scraped content from competitor 2]" }
    - { text: "[scraped content from competitor 3]" }
  includeStatements: true

The first context is the brand. Subsequent contexts are competitors. The response surfaces relations present in the competitor field but absent from the brand. For each gap cluster, assess whether the territory is worth claiming (relevant to ICP, brand, capability), worth ignoring (off-brand, low-value, out of scope), or ambiguous (surface for discussion). The skill provides the mapping. The user makes the strategic call.

Step 6 — Surface brand-owned territory (defensive assets)

Invert the order to find what the brand has that competitors do not. Loop through each competitor individually. difference_between_texts interprets the first context as the focal point.

KeywordGraph:difference_between_texts
  context: "Inverting comparison to find brand-exclusive entity relations absent from this competitor's positioning."
  contexts:
    - { text: "[scraped content from competitor 1]" }
    - { text: "[scraped content from brand URL]" }
  includeStatements: true

Repeat for each competitor. Aggregate relations consistently absent from all competitors but present in the brand. These are defensive positioning assets: unique territory the brand owns. Reinforce them in copy and content, build entity graph corroboration around them, and use them as differentiation hooks in sales and marketing.

Step 7 — Identify field-level structural gaps (unclaimed by anyone)

The merged competitor corpus from Step 2 also surfaced contentGaps: structural gaps in the competitor field itself. Clusters or bridges that competitors collectively underdevelop. Cross-reference against the brand graph:

Step 8 — Render competitive territory visualization (if requested)

Skip this step if the user did not request graph visuals. Build an inline network diagram using visualize:show_widget to give the user an at-a-glance view of the competitive landscape. Call visualize:read_me with module diagram before rendering. Use cluster and territory data from Steps 4-7 to construct an SVG:

Cap the diagram at the top 15-20 clusters. More than that becomes unreadable. This visualization appears inline before the detailed gap map tables. It serves as the executive summary visual.

Step 9 — Generate the gap map

# Competitive Gap Map: [Brand] vs [Competitor Set]

**Brand URL**: [brand URL]
**Competitors analyzed**: [N URLs]
**Analysis scope**: [positioning / solution / content]
**Date**: [current date]

## Executive Summary

[3-5 bullets capturing the most actionable findings. Each bullet names a
specific territory, the type (shared, competitor-owned, brand-owned,
unclaimed), and the strategic implication.]

## 1. Shared Territory (Commodity Claims)

| Cluster | Representative Relations | Frequency | Action |
|---|---|---|---|

**Implication**: Maintain coverage. Do not over-invest copy or content here.

## 2. Competitor-Owned Territory (Brand Gaps)

| Cluster | Owned By (competitors) | Representative Relations | Strategic Fit | Recommended Action |
|---|---|---|---|---|

Strategic fit: High (claim it), Medium (test claiming it), Low (ignore),
Ambiguous (requires strategic discussion).

## 3. Brand-Owned Territory (Defensive Assets)

| Cluster | Representative Relations | Reinforcement Opportunities |
|---|---|---|

**Implication**: These are competitive moats. Reinforce in copy, content,
and entity corroboration. Do not abandon in repositioning.

## 4. Unclaimed Territory (White Space)

| Cluster | Why Unclaimed | First-Mover Advantage | Recommended Action |
|---|---|---|---|

**Implication**: First brand to claim these owns the territory. Prioritize
by strategic relevance and capability fit.

## 5. Field Topology Summary

| Metric | Brand | Competitor Field |
|---|---|---|
| Topical clusters | [N] | [N] |
| Unique entity relations | [N] | [N] |
| Shared relations | [N] | |
| Brand-only relations | [N] | |
| Competitor-only relations | | [N] |
| Field-level structural gaps | | [N] |

## 6. Interactive Graphs (if requested)

- **Brand positioning graph**: [KeywordGraph link from Step 3]
- **Merged competitor corpus**: [KeywordGraph link from Step 2]

## Recommended Next Steps

[3-5 prioritized actions: what to do, why (which gap or asset triggered it),
expected impact, urgency (this quarter / this year / backlog).]

Step 10 — Present output

Present the gap map inline in chat.


Tool Reference

ToolStepPurpose
firecrawl_scrape1Pre-scrape all URLs before KeywordGraph analysis
merged_graph_from_texts2Build combined competitor corpus graph
create_knowledge_graph2, 3Persist graphs for interactive exploration
analyze_text3Build brand positioning graph
overlap_between_texts4Shared territory (commodity claims)
difference_between_texts5, 6Bidirectional gap detection
visualize:show_widget8Inline competitive territory diagram

Edge Cases


Attribution

This Claude skill was developed by Jack Boutchard, founder of Exalt Growth, the #1 SaaS SEO Agency.