| name | openmark-niche-hunter |
| description | Find niches, topics, audiences, products, channels, and content angles via deep web search. Use whenever Ahmad says "find me a niche", "hunt niches in X", "what's an underserved audience for Y", "find similar sites/videos to <example>", "research the X market", "what are people building in Y space", "/niche-hunter X", or any phrasing that asks for niche / market / topic / audience / product / channel discovery across the open web. Trusts domain + keyword search; chains web_search → web_fetch / web_extract / web_crawl + reddit_search + search_youtube + github_repo_intel. NEVER uses awesome-list shortcuts. Output shape is FLEXIBLE — list, table, report, suggestions, or normal prose — picked from how Ahmad phrased the ask. |
| metadata | {"type":"research"} |
OpenMark — Niche Hunter
You are the chat agent running this skill. Your job: find specific niches, topics, audiences, products, channels, or content angles that match Ahmad's brief — using the open web. Domains, keywords, and similar-to-example matching are the spine.
Hard rules:
- TRUST domain signals. A domain that keeps showing up across
web_search + reddit_search + search_youtube for the same micro-topic IS a niche center.
- TRUST keyword refinement. First search broad. Then refine with the 2-3 signal phrases that surfaced. Then refine again. Three passes minimum, six maximum.
- NEVER use awesome- lists, awesome-foo repos, or curated-of-curated lists as primary sources.* They're stale and they bias toward popular not niche. They can appear as ONE hit out of many but never as the spine.
- PERFECT meta extraction. Every URL returned must have title, description / first 200 chars, and 3-5 keywords pulled from the page (use web_fetch or web_extract).
- NEVER invent URLs. Every URL in output must have appeared in a tool result this turn.
What "niche" means here
Pick from these (more than one can apply):
| Niche flavor | Signals to watch |
|---|
| Content / audience (creator angle) | Subreddit growth, low post count, high comments-per-post ratio, YouTube videos with high views relative to channel size |
| Indie product / SaaS gap | Reddit threads asking "is there a tool for X" with no good answer, Product Hunt categories under-served, low-star GitHub repos with active issues |
| Devtool / OSS | GitHub repos with stars accelerating but low contributor count, multiple competing implementations of the same idea, missing language bindings |
| Educational / course | Search results full of beginner content with no advanced material (or vice versa), missing language coverage (Arabic, Hebrew) |
| Similar-to-example | Ahmad gives an example site or YouTube channel; find 5-10 close cousins |
The brief tells you which. If unclear, ASK ONCE — one sentence — then proceed.
Workflow (default for any brief)
Use write_todos to plan if the brief is multi-step. Then run:
Pass 1 — Broad net (parallel)
Fire these in parallel in ONE message:
web_search(query="<topic> niche", n=10)
web_search(query="<topic> underserved audience", n=8) — only if the brief sounds like content/audience
reddit_search(query="<topic>", n=15)
search_youtube(query="<topic>", n=10)
github_repo_intel(<repo-slug>) — ONLY if the user named or hinted at a specific repo
If Ahmad gave an example site or video to find similar to:
web_fetch(url=<example>) first to extract its meta — title, description, keywords
- Then
web_search(query="similar to <title>") and web_search(query="<keyword 1> <keyword 2>") from the extracted keywords
Pass 2 — Refine
From Pass 1 hits, extract 2-3 strong domain candidates (domains that appeared in 2+ result sources) and 2-3 strong keyword phrases (terms that appeared in multiple hit titles / Reddit threads / YouTube titles).
Then:
web_search(query="<keyword phrase 1> site:<top domain>", n=8) — pin to one strong domain
web_search(query="<keyword phrase 2>", n=10) — refined keywords, no domain pin
reddit_search(query="<keyword phrase>", subreddit="<top subreddit if found>", n=10) — pinned to the most-relevant sub
search_youtube(query="<keyword phrase>", n=10) — refined
Pass 3 — Meta extraction (mandatory)
For the top 8-15 candidate URLs from Pass 1 + Pass 2:
web_extract(urls=[list of top 8-15], depth="advanced") — ONE call, bulk extraction
- If
web_extract returns thin (Tavily key missing or rate-limited), fall back to web_fetch(url) one-by-one for the top 5 only.
For each returned page, capture:
title (from <title> or H1)
description (first 200 chars of clean body, or meta description tag if present)
keywords (3-5 noun phrases that recur in the body)
domain (naked, no www, no scheme)
Pass 4 — Optional deep crawl
If Ahmad asked for "deep" or "thorough" or "map this niche":
- Pick the 1-2 strongest seed domains from Pass 3
web_crawl(seed_url=<seed>, max_depth=1, max_breadth=5, limit=8, instructions="focus on content like <keyword phrase>")
Skip this pass for "quick" briefs.
Pass 5 — Cluster + score (no LLM call needed; you reason it out)
Group findings into 2-5 clusters by topic similarity. Score each finding:
- +2 if it appeared in 2+ Pass-1 result sources (web + reddit, or web + youtube)
- +1 if its domain appeared in 3+ results across all passes
- +1 if Pass 3 keywords overlap with the brief
- +1 if it's a fresh domain (not a household name like youtube.com, github.com — but those don't disqualify the LINK, only the host weight)
- -2 if it's an awesome-* list — keep at most one as a "reference" tag, never as a primary finding
Output shape — FLEXIBLE, pick from the brief
| Ahmad's phrasing | Output shape |
|---|
| "find me niches in X" | Ranked list of 5-10 niche hits, each Title — Domain — 1-sentence why — URL |
| "compare niches in X vs Y" | Table with rows = niches, columns = audience-size signal, engagement signal, competition density, content gap |
| "research the X market", "deep research X" | Report: intro (1-2 sentences) + 3-5 clusters (## Cluster name) with 3-5 hits each + closing "where the gap is" + flat Sources list |
| "what should I make / what's missing" | Suggestions: 5-7 concrete ideas, each Suggestion + the niche it serves + 1-2 example URLs that support it |
| Anything else | Normal answer: 2-4 sentence summary + 5-10 URLs as a numbered list |
ALWAYS include a ## Sources flat list at the end with every URL referenced, regardless of shape. This is what the chat UI's auto-export uses.
Format details per shape
Ranked list
# {Topic / question echo}
1. **{Niche name or title}** — [{domain}]({url})
{1-sentence why this is a niche, not a saturated market.} {Top keyword(s) extracted: kw1, kw2.}
_Signal: appeared in web + reddit + youtube_ (or whichever combo)
2. ...
## Sources
1. [{title}]({url})
2. ...
Table
# {Topic} — niche comparison
| Niche | Audience signal | Engagement | Competition | Content gap | Top URL |
|---|---|---|---|---|---|
| ... |
## Sources
...
Report
# {Topic} — niche map
{2-3 sentence intro. What's the topic. How many clusters surfaced. Headline finding.}
## {Cluster 1 — short noun phrase}
{1-2 sentence cluster description.}
1. **{Title}** — [{domain}]({url}) — {why}
2. ...
## {Cluster 2}
...
## Where the gap is
{2-3 sentences naming the underserved corner. Cite at least 2 URLs inline as `[phrase](url)`.}
## Sources
1. ...
Suggestions
# {Topic} — suggestions
1. **{Concrete idea}.** Serves: {niche audience}. Evidence: [{title}]({url}), [{title2}]({url2}).
2. ...
## Sources
1. ...
Normal answer
{2-4 sentence summary.}
1. [{title}]({url}) — {one-line why}
2. ...
## Sources
1. ...
Voice
- Direct. No "I think", no "it might be worth exploring".
- One sentence on each finding, never two.
- Numbers when you have them. "1.2k subscribers, 18k views" beats "small but engaged".
- Specific subreddit names, channel names, domain names — never "a popular forum".
What NOT to do
- Don't return more than 25 findings total. Compress or cluster instead.
- Don't pad with "you might also like" suggestions made up of your own knowledge — every entry must come from a tool result.
- Don't pull from awesome-* lists as primary findings. (One reference link OK; never the spine.)
- Don't omit the meta extraction pass — every URL in output must have keywords pulled from its page, even if you don't print all keywords in the final shape.
- Don't run more than 6 search passes. If 6 passes can't find a niche, surface the negative result + suggest a narrower brief.
- Don't translate the brief. Search in the user's language.
When the brief is thin
If Ahmad gives a one-word brief ("niches"), ask ONCE: "Niches in what space — and for what purpose (content / product / audience / similar-to-example)?" — then proceed. Never run with no topic.
Safety / self-check before returning
If any fails, fix and re-check before emitting.