# Positioning Map

> Build a positioning map for 3–5 competitors and identify the empty quadrant the founder could own. Use when a founder asks "where's the positioning gap?", "how do I position against X?", "what's the competitive landscape look like on hero / pricing / hiring / customers?", or needs a structured comparison before a launch, repositioning, or fundraise. Combines Anysite MCP (LinkedIn company entity +…

- **Type:** Skill
- **Install:** `agentstack add skill-anysiteio-agent-skills-positioning-map`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [anysiteio](https://agentstack.voostack.com/s/anysiteio)
- **Installs:** 0
- **Category:** [Search](https://agentstack.voostack.com/c/search)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [anysiteio](https://github.com/anysiteio)
- **Source:** https://github.com/anysiteio/agent-skills/tree/main/skills/positioning-map

## Install

```sh
agentstack add skill-anysiteio-agent-skills-positioning-map
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Positioning Map

Positioning isn't marketing copy — it's a **product decision about who you say no to**. This skill makes that choice visible by mapping competitors on 5 signal axes, locating the empty space, and forcing you to pick between 3 candidate moves rather than defaulting to the first one that sounds good.

Founders consistently underweight four things on competitor positioning: hero copy is the most-curated surface (so trust it least), pricing reveals who they actually sell to, what they ship reveals what they think matters, and **who they hire reveals where they're going next quarter** (the leakiest signal of all). Customer logos reveal who they actually catch, which often contradicts who they pitch.

## Frameworks this skill draws from

This skill is the operational version of three positioning frameworks, executed against real public data:

1. **April Dunford — *Obviously Awesome* (5 components):** competitive alternatives, unique attributes, value (and proof), target market characteristics, market category. Dunford's #1 insight: **start with competitive alternatives, not with what you do.** This skill operationalizes that by always grounding "the empty quadrant" against the actual competitor set, not against an abstract market.
2. **Geoffrey Moore — *Crossing the Chasm* (positioning statement template):** "For [target customer] who [need], the [product] is a [category] that [benefit]. Unlike [primary alternative], our product [primary differentiation]." This is the format of the deliverable — the one-sentence positioning move.
3. **Ries & Trout — *Positioning: The Battle for Your Mind* (mental real-estate):** you can only own ONE word/concept in the customer's mind. The "empty quadrant" framing inherits from this: the position you can own is the one nobody else is claiming AND that customers care about.

Adjacent frameworks worth knowing but not directly encoded here: **Treacy & Wiersema's three value disciplines** (product leadership / operational excellence / customer intimacy — pick one, do the others adequately) and **Ulwick's outcome-driven JTBD** (positioning aligned to unmet desired outcomes). If the founder uses these in their own thinking, fold them into the axis choices.

## When this skill applies

- Founder asks where the positioning gap is
- Pre-launch — choosing what to say no to
- Pre-fundraise — proving positioning is defensible
- Post-`customer-pain-mining` — synthesizing what you found with what competitors actually claim

## What you need (inputs)

1. **3–5 competitors with URLs** — fewer than 3 isn't a map; more than 5 is noise.
2. **The job-to-be-done** — one line. Without it, "axis" has no meaning.
3. **Customer pain themes — REQUIRED, not optional.** Output from `customer-pain-mining`. Positioning without pain context is just rearranging marketing copy. The gap lives where pain ≠ competitor claims. If the founder hasn't run pain-mining, refuse to produce a positioning sentence — produce only a descriptive map and flag this in the executive summary.
4. **(Optional) Founder's current positioning** — if doing a repositioning exercise.

If you don't have item 1, run `competitor-discovery`. If you don't have item 3, run `customer-pain-mining` first.

## Tools

**Exa MCP** (primary for axes 1, 2, 4 — modern SaaS marketing sites are JS-rendered SPAs):
- `mcp__claude_ai_Exa__web_fetch_exa(urls)` — pull homepage / pricing / customers / changelog pages. Batch multiple URLs per call.
- `mcp__claude_ai_Exa__web_search_exa(query, numResults)` — find case studies, changelog blogs, "X review" comparison posts.

**Anysite MCP**:
- `mcp__claude_ai_Anysite__execute(source="linkedin", category="company", endpoint="company", params={"company": ""})` — company entity + URN + employee count + specialities[] + short_description.
- `mcp__claude_ai_Anysite__execute(source="linkedin", category="search", endpoint="search_posts", params={"keywords": " ", "date_posted": "past-month", "count": 10})` — what they're posting and what's being said about them in the last month. Use this for the "recent shipping" axis; it covers the same ground as `linkedin/company/company_posts` but with richer engagement filtering via `query_cache`.
- `mcp__claude_ai_Anysite__execute(source="linkedin", category="search", endpoint="search_jobs", params={"keywords": "", "count": 20})` — open roles. Filter response by `company.alias` matching the actual target (keyword search can catch namesakes — e.g. a keyword search for one competitor may return a different competitor's roles that mention it in the JD).
- `mcp__claude_ai_Anysite__execute(source="sec", category="search", endpoint="search_companies", params={"entity_name": "", "forms": ["10-K","S-1","D"], "count": 5})` — only for late-stage / public competitors. For early-stage consumer SaaS, returns nothing useful.
- `mcp__claude_ai_Anysite__execute(source="webparser", category="parse", endpoint="parse", params={...})` — only for static-HTML competitor sites. Modern SaaS marketing pages (Next.js / Vercel) return empty; use Exa instead.

Budget: ~3 Anysite calls per competitor (LinkedIn company + post search + jobs search) + ~2 Exa fetches per competitor. For 5 competitors: ~15 Anysite + ~10 Exa.

## How to run

For each competitor, run the same 5 axes. Capture as a row in a growing table.

### Axis 1 — Hero copy (who they pitch)

`mcp__claude_ai_Exa__web_fetch_exa(urls=["https://.com"])`

Extract: H1 headline, sub-headline, the verb (build / write / cite / extract / scrape / etc.), explicit audience callout if any ("for academic researchers," "for indie devs," "for teams 10–500", "for AI agents").

Validated on the web-scraping niche: a single batched Exa fetch on `["brightdata.com", "apify.com", "firecrawl.dev", "scrapingbee.com", "anysite.io"]` returns hero + subhead + pricing summary + customer-logo trust bar for all 5 competitors in one call. The hero is the most curated surface — trust it least for "what the product actually does" and most for "who the company is currently pitching."

Webparser tends to fail on JS-rendered SPAs (Next.js / Vercel marketing sites) — Exa fetch is the reliable primary.

### Axis 2 — Pricing (who they actually sell to)

`mcp__claude_ai_Exa__web_fetch_exa(urls=["https://.com/pricing"])`

If `/pricing` returns `CRAWL_NOT_FOUND` (it sometimes does for Next.js sites), the pricing is usually on the homepage from Axis 1 — search for "$" in the body text.

Extract: tier names, lowest paid tier (in $), highest published tier, gating (seats / usage / features / credits). Convert everything to monthly USD for comparability. The lowest tier reveals their floor; the highest reveals ambition.

Web-scraping API niche pricing spread (validated): Firecrawl $0 → $16 Hobby → $83 Standard → $333 Growth (credit-based, 5x multiplier on extract). Apify $5 free → $49 Starter (compute-unit). Bright Data product-by-product: Crawl $1/1K req; Unlocker $1/1K; Browser API $5/GB; Web Scraper $0.001/record; effective $499/mo for 510K records. ScrapingBee $49/mo Freelance → $99 Startup → $599 Business+. The whole category is in pricing turmoil — the dominant pain in `customer-pain-mining` is the credit-multiplier surprise, so the pricing axis has positioning leverage right now.

### Axis 3 — LinkedIn company entity (the org's verbatim self-positioning)

`mcp__claude_ai_Anysite__execute(source="linkedin", category="company", endpoint="company", params={"company": ""})`

Returns: `short_description`, `description`, `employee_count`, `founded_on`, `specialities[]`, `headquarter_location`.

What to extract:
- `short_description` — often a single positioning sentence the company curates for LinkedIn (different from their homepage hero — useful contrast).
- `specialities[]` — explicit, comma-separated list of what they claim to do. Rare verbatim self-positioning. In Dunford's terms, this is their stated "unique attributes" list.
- `employee_count` — sets the stage size (e.g. Bright Data=355, Apify=231, Firecrawl=48, ScrapingBee=17).
- `founded_on` — for stage context.

Validated on the web-scraping niche: Bright Data's `specialities[]` is 13 terms long, dominated by use-cases (price intelligence, brand monitoring, market research, AI Agents). Apify's is 8 terms, platform-shaped ("Web scraping, Browser automation, AI agents, API integration, Data pipelines, No-code tools, Actor marketplace, Developer platform"). Firecrawl + ScrapingBee both ship empty `specialities[]` (small pages, content-marketing-led) — that absence is itself a signal.

Skip `company_employee_stats` for competitors under ~200 employees — the endpoint returns empty arrays for small organizations.

For the "what did they ship lately" axis, prefer `linkedin/search/search_posts` from Axis 4 over `linkedin/company/company_posts` because Axis 4's keyword + `mentioned[]` filter gives richer engagement-based filtering via `query_cache`.

### Axis 4 — Recent shipping / signal (what they think matters now)

What did they ship or signal in the last 30 days?

`mcp__claude_ai_Anysite__execute(source="linkedin", category="search", endpoint="search_posts", params={"keywords": " ", "sort": "recent", "date_posted": "past-month", "count": 10})`

Filter for signal — many results will be SEO listicles. Keep posts where (a) the author is the company itself (mentioned[] contains the company), or (b) `comment_count + sum(reactions[].count) >= 10`. Use `query_cache`.

Alternative: Exa for changelogs / feature blog posts:

`mcp__claude_ai_Exa__web_search_exa(query=" new feature release 2025 — changelog blog post — what's new", numResults=5)`

Then fetch the top URL if promising. Some products have explicit `/changelog`, `/whats-new`, `/blog` pages.

What to extract: count feature-release posts vs customer-story posts vs marketing posts in the last 30 days. The ratio tells you the company's stage and what they think the buyer cares about.

Validated on the web-scraping niche: Firecrawl ships fastest on AI-agent affordances (Onboarding-Skill flow, CLI launch, MCP server, "Highlights and Question formats are now live"). Bright Data ships compliance/enterprise content (DataDome partnership, Web MCP "now free"). Apify ships marketplace breadth (native MCP highlight, Creator Growth program, LangChain/n8n integrations). The recent-shipping axis reveals which company believes the buyer cares about which thing this quarter.

### Axis 5 — Hiring signal (where they're going next quarter)

`mcp__claude_ai_Anysite__execute(source="linkedin", category="search", endpoint="search_jobs", params={"keywords": "", "count": 20})`

Hiring is the leakiest competitive signal. Companies can curate hero copy, hide pricing, lawyer up customer logos. They cannot hide that they just opened 5 enterprise sales reqs.

What to extract: count of open roles filtered by `company.alias` matching the actual target (keyword search can catch namesakes — a keyword search for one competitor can return roles at another company that mentions it in the JD). Then group by function:

- Eng / AI / R&D → product surface expansion incoming
- Growth / Performance Marketing / SEO → optimizing the paid funnel; scaling existing model
- Enterprise Sales / AE / Customer Success → moving upmarket
- Partnerships / Channel / Solutions → going institutional / channel-led
- Product Marketing / Product Enablement → revenue-stage execution, not net-new product
- Developer Relations / Creator Growth → developer-ecosystem / platform play

The function MIX, not the count, is the signal. Validated on the web-scraping niche: Bright Data has 20+ open roles skewed Enterprise Sales (Overlay Sales Director, AI Account Executive UK, BDR NYC) + CS + global Solutions Architects → scaling enterprise GTM + global presence. Apify has 20+ skewed developer-platform (Senior Backend for proxy/unblocking, Fraud Prevention Eng, Product Marketing, Creator Growth Lead) → scaling developer + creator/Actor-publisher side. Firecrawl shows 0 results on LinkedIn jobs → small (~48 employees) and content-marketing-led, not hiring publicly. ScrapingBee shows 1 (Sr PM Vilnius) → stable, lean.

Mark "no signal" for very-small competitors ( customer case study OR testimonial 2024 2025 — ", numResults=5)`

### Axis 7 (skip unless competitor is public / late-stage) — SEC filings

`mcp__claude_ai_Anysite__execute(source="sec", category="search", endpoint="search_companies", params={"entity_name": "", "forms": ["10-K","S-1","D"], "count": 5})`

Only meaningful when the competitor has filed (e.g. Grammarly has Form D filings under CIK 0002033975). Returns canonical positioning language they've committed to in legal filings — rigid, lawyered, but unedited.

For early-stage / private consumer SaaS this returns nothing useful. Skip.

### Synthesize — the positioning table

Build a markdown table with axes × N competitors + the founder's own product as the last column. The point of including yourself is to make the gap visible relative to where you stand now.

### Cross-reference with pain themes (the load-bearing step)

This is what makes positioning real rather than wishful: only positions that map onto a top-3 customer pain theme are worth considering. Take the pain themes from `customer-pain-mining` and rank them by signal density (upvotes, reactions, mention count). For each empty quadrant you spot in the table, check: is there a pain theme that backs this position? If no, drop it.

Validated on the web-scraping niche: the top pain theme was "scrapers break every time the website changes" (2,045-like LinkedIn launch post for Scrapling + cross-platform Reddit + Exa-blog confirmation). The empty quadrant "agent-native + predictable pricing" maps directly onto this pain combined with the credit-multiplier complaints from cluster 2. That alignment is what makes the move defensible.

### Generate three candidate positioning moves (not one)

April Dunford's empirical observation: founders who write ONE candidate positioning statement default to the first one that sounds good. The fix is to write 3 and force a choice. For each candidate, use Moore's template:

> "For [target customer] who [need], [product] is a [category] that [benefit]. Unlike [primary alternative], our product [primary differentiation]."

Pick 3 candidates that genuinely differ on **competitive alternative** (per Dunford). Concretely:
- **Candidate A** — position against the obvious primary competitor.
- **Candidate B** — position against the "do nothing / DIY" alternative.
- **Candidate C** — position against a category-adjacent tool (something not in the named competitor set but that customers actually use).

For each candidate, evaluate on 3 criteria:
1. **Pain coverage** — does it map to a top-3 pain theme from `customer-pain-mining`?
2. **Defensibility** — does the founder have a structural advantage to hold this position (data, team, integrations, customer base)? Or is it just marketing copy?
3. **Empty-quadrant evidence** — how many of the 5 axes show this position as unclaimed?

Score each 1–3, pick the highest total. State why the other two lose. **Show the work.**

## Output

Markdown report, ~900–1100 words:

```
# Positioning Map — 

## Executive summary
3 sentences: dominant positioning pattern, the empty quadrant the founder could own, the single positioning move that creates the most contrast (the WINNER of the candidate-3).

## Comparison table

|  |  |  |  |  |
|---|---|---|---|---|
| **Hero copy** | "..." (verbatim H1) | "..." | "..." | "..." |
| **Pricing floor / ceiling** | $X / $Y per mo | ... | ... | ... |
| **LinkedIn specialities (top 3)** | A, B, C | ... | ... | ... |
| **Last 30 days shipped** | 3 features + 2 case studies | 1 feature + 5 SEO posts | ... | ... |
| **Hiring (function mix)** | 4 Eng / 2 Sales / 1 CS — moving upmarket | "no signal" (early-stage) | ... | ... |

## The empty quadrant
1–2 paragraphs naming the position no one currently occupies. Quote evidence from at least 2 of the 5 axes AND tie it to a named pai

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [anysiteio](https://github.com/anysiteio)
- **Source:** [anysiteio/agent-skills](https://github.com/anysiteio/agent-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-anysiteio-agent-skills-positioning-map
- Seller: https://agentstack.voostack.com/s/anysiteio
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
