Researcher skill
The single idea-generation pipeline for marketing content.
by timscheuerai·MIT license·★ 37 Stars on the repo·GitHub ↗
npx degit timscheuerai/content-vault/skills/researcher#main ~/.claude/skills/researcherChecked ·commit main
Inside this skill
SKILL.md · the author's own words# researcher The single discovery pipeline. Three idea sources, one Notion output. Use this instead of separate /performance-check or /listening skills · they're folded in as modes here. ## When to use Trigger on: - "Find me content ideas" - "What's hot on X / LinkedIn" - "What's working for me" - "Pull from my user interviews" - "What are customers saying" - "Scan the GTM space" - "Give me ten posts to write next week"
Word-for-word excerpt, not a result. Read the full SKILL.md ↓
Files of Researcher
Show the full text428 lines
researcher
The single discovery pipeline. Three idea sources, one Notion output. Use this instead of separate /performance-check or /listening skills · they're folded in as modes here.
When to use
Trigger on:
- "Find me content ideas"
- "What's hot on X / LinkedIn"
- "What's working for me"
- "Pull from my user interviews"
- "What are customers saying"
- "Scan the GTM space"
- "Give me ten posts to write next week"
- User explicitly types
/researcher - Your Notion Content DB has < 5 rows in
Status = Idea(proactive)
Skip for:
- Verbatim repurposing of one specific post (use
/repurpose) - Drafting a single post (use
/linkedin-copywriteror/x-copywriter) - Scraping arbitrary websites (this skill is X + LinkedIn + Notion only)
Modes
1. Trend scan · "what's hot in the world"
Pull recent posts from a curated list of creators on X + LinkedIn (account scan) or search by keyword (topic scan). Rank by engagement. Surface the themes worth riffing on.
Best for: weekly idea injection, knowing what's resonating broadly. Risk: noisy, off-niche topics if not filtered.
2. Performance scan · "what's working for me"
Pull your own published rows from the Notion Content DB. Fetch engagement metrics from LinkedIn (Unipile) and X (X API). Rank by engagement. For top performers, generate double-down ideas: follow-ups, deeper dives, contrarian counter-takes, variations.
Best for: amplifying signal you already have. The most leveraged mode because it's grounded in proof.
3. Customer scan · "what real customers say"
Query the HUMAN NOTES DB for recent user-interview / external-meeting rows. Read the transcripts. Extract pain points, direct quotes (use customer language verbatim), and recurring themes across multiple interviews. Generate angles tied to those.
Best for: sharp pain-point posts, customer-quoted content, lead- magnet topics that solve real problems. The most original mode because it draws on private signal nobody else has.
4. Concept scan · "extend your own canon"
Read the content knowledge graph in content/concepts/ and
content/mocs/ (see content/CONTENT-WIKI.md). Two moves:
- Extend a thread. For a high-value concept or an open MOC arc, propose the next beat: the unwritten angle, the new proof point, the counter-take, the deeper dive. Ground it in the concept's existing canonical lines so the new post compounds the old ones.
- Find the gaps. Surface thin concepts (low
appears_in) that deserve more, and recurring ideas in recent posts that have no concept note yet (candidates for a new node).
Best for: making content compound instead of restart. The most on-brand mode because it builds on your own canon, not the feed. (If the graph is still empty, skip this mode until you've published a few posts.)
5. Hybrid (recommended for weekly runs)
Run all four. Dedupe. Output a balanced backlog: 3 trend ideas, 3
performance double-downs, 2 customer-pain ideas, 2 concept extensions
(or whatever ratio makes sense given recency). When you create an idea
that extends a concept, note Extends: [[concept-slug]] on it so the
link exists from the Idea stage. See content/CONTENT-WIKI.md.
Workflow
1. Decide mode + scope
Ask the user (skip if already specified):
- Mode: trend / performance / customer / hybrid (default: hybrid)
- Time window: default 7 days for trends, 30 days for performance, 60 days for customer
- How many idea cards to create: default 10, max 25
2. Fetch from each active source
Trend scan · X
source ./.env
mkdir -p /tmp/researcher
# Account scan: per cached user ID in seed-accounts.md
for uid in 1893653481858433024 512156315 859850213015597056; do
curl -s "https://api.twitter.com/2/users/${uid}/tweets?max_results=100&tweet.fields=public_metrics,created_at,entities&exclude=retweets,replies" \
-H "Authorization: Bearer ${X_BEARER_TOKEN}" \
-o /tmp/researcher/x_${uid}.json
done
# Topic scan: keyword search (last 7d, English, exclude retweets)
TOPIC="AI GTM agent"
curl -s --get "https://api.twitter.com/2/tweets/search/recent" \
--data-urlencode "query=${TOPIC} -is:retweet lang:en" \
--data-urlencode "max_results=50" \
--data-urlencode "tweet.fields=public_metrics,created_at,author_id,entities" \
-H "Authorization: Bearer ${X_BEARER_TOKEN}" \
-o /tmp/researcher/x_topic.json
X engagement score:
score = like_count + 3*retweet_count + 2*reply_count + 3*quote_count
Trend scan · LinkedIn
source ./.env
for pid in <YOUR_LINKEDIN_PROFILE_ID>; do
curl -s "https://${UNIPILE_DSN}/api/v1/users/${pid}/posts?account_id=${UNIPILE_ACCOUNT_ID}&limit=20" \
-H "X-API-KEY: ${UNIPILE_API_KEY}" \
-H "accept: application/json" \
-o /tmp/researcher/li_${pid}.json
done
LinkedIn engagement score:
score = reaction_counter + 3*comment_counter + 5*share_counter
If a seed account in seed-accounts.md has profile ID TBD, resolve
it on first use:
curl -s "https://${UNIPILE_DSN}/api/v1/users?account_id=${UNIPILE_ACCOUNT_ID}&keyword=<name>&limit=5" \
-H "X-API-KEY: ${UNIPILE_API_KEY}"
Pick the right profile, copy the ID into seed-accounts.md (commit),
continue.
Performance scan · your own content
Step 1: query the Notion Content DB for your recent Published rows.
Use mcp__claude_ai_Notion__notion-search with:
data_source_url: collection://<YOUR_NOTION_CONTENT_DB_ID>
query: ""
page_size: 25
filters: { created_date_range: { start_date: "<30d ago>" } }
Filter to rows where Status = Published and Live URL is non-empty.
Step 2: fetch metrics per Live URL.
For LinkedIn URLs (pattern linkedin.com/posts/...):
# Fetch your own posts (your profile ID is cached)
curl -s "https://${UNIPILE_DSN}/api/v1/users/<YOUR_LINKEDIN_PROFILE_ID>/posts?account_id=${UNIPILE_ACCOUNT_ID}&limit=50" \
-H "X-API-KEY: ${UNIPILE_API_KEY}" \
-H "accept: application/json" \
-o /tmp/researcher/li_self.json
Match each Notion row's Live URL against the response · use the
post's reaction_counter, comment_counter, share_counter.
For X URLs (pattern x.com/<handle>/status/<id>):
# Extract tweet IDs from URLs
TWEET_IDS="1234567890,2345678901,..." # comma-separated
curl -s --get "https://api.twitter.com/2/tweets" \
--data-urlencode "ids=${TWEET_IDS}" \
--data-urlencode "tweet.fields=public_metrics,created_at" \
-H "Authorization: Bearer ${X_BEARER_TOKEN}"
If your X user ID is not yet cached in seed-accounts.md, the tweet
lookup-by-ID still works without it · we just can't filter to your
own without the ID. Note as soft-blocker if it limits the run.
Step 3: rank and pick.
Sort by engagement score (X formula above for tweets, LinkedIn formula for LI posts). Top 5 are double-down candidates. Bottom 3 are flop diagnostics (what didn't work · note for avoidance, not for ideation).
Step 4: generate double-down angles.
For each top-5 row:
- Follow-up: a continuation post answering "and then what happened?" or "the next step after X"
- Deeper dive: pick one bullet from the original and make it the whole post
- Counter-take: argue the opposite of the original (works if the original was a popular take · creates contrast)
- Format flip: original was text → carousel; original was post → thread; etc.
Pick whichever fits the source. Multi-angle per row is fine if rich material exists.
Customer scan · HUMAN NOTES DB
Query the user-interview rows.
Use mcp__claude_ai_Notion__notion-search with:
data_source_url: collection://<YOUR_NOTION_HUMAN_NOTES_DB_ID>
query: ""
page_size: 25
filters: { created_date_range: { start_date: "<60d ago>" } }
Filter the response to Category in ("User Interview Meeting", "External Meeting"). Skip Co-Founder Meeting, Dev Notes, Reading
List, Application categories · those aren't customer signal.
For each surviving row, fetch the page body via
mcp__claude_ai_Notion__notion-fetch with the row ID. The body
contains the transcript / notes.
For each interview, extract:
- Pain points: 2-4 bullets describing what's broken in the customer's world (in their words, not yours)
- Direct quotes: 1-3 quotable lines (verbatim · with attribution to interview date and customer if not under NDA)
- Recurring themes: themes that show up across multiple interviews (note which · a theme in 1 interview is anecdote, in 3+ it's signal)
For each recurring theme (3+ occurrences), generate an angle:
- The pain stated as a question you have the answer to
- A framework that resolves the pain
- A contrarian take on common-but-wrong solutions in that space
- A customer-quote post (the verbatim line as the hook)
3. Filter (all modes)
- Drop posts older than the time window
- Drop banned-signal posts (see
seed-accounts.md§ "Banned signals") - Drop URL-only / image-only posts with no text body
- Drop posts under the engagement floor (trend mode only · 50 likes on X · 100 reactions on LinkedIn)
- For customer scan: drop interviews under 5 minutes (likely no-shows or aborted) and skip the ones marked "private · do not use"
4. Cluster + angle (all modes)
Read all surviving inputs. Group by theme · expect 5-10. For each theme, pick the strongest representative (highest engagement for trends, top performer for performance, most-quoted for customer) and write:
- Angle: a one-sentence hook you could use, in your voice (terse, contrarian, concrete, direct, no hype)
- Why it's hot / working / real: one sentence on why this matters
- Suggested Pillar: pick one of the six (
Building in Public,Educational / Tactical,Personal,Memes,Promotional,Trend Insights) - Suggested Format + Channel: usually
TextonLinkedInorX· sometimesLong-form Articlefor richer themes · sometimesLead Magnetfor customer-pain frameworks
5. Create Notion rows
For each idea card, call
mcp__claude_ai_Notion__notion-create-pages with data source
<YOUR_NOTION_CONTENT_DB_ID>. Properties:
- Title: the one-sentence angle (max ~80 chars)
- Status:
Idea - Pillar: suggested multi-select (single value usually)
- Format: suggested
- Channel: suggested
Page body, branched by mode:
Trend mode body
Source: <original post URL>
Mode: trend
Author: <handle / name>
Engagement: <metrics line>
Window: <date range>
— Original post —
> <quoted post text>
— Why this is hot —
<one sentence>
— Your angle —
<one to three sentences in your voice>
Performance mode body
Source: <your published Notion row URL>
Mode: performance · double-down
Original metrics: <metrics line>
Pillar of original: <pillar>
— Original post —
> <quoted post text>
— Why this performed —
<one sentence on what worked>
— Double-down angle —
<one to three sentences · what to write next that builds on the win>
Customer mode body
Source: <interview Notion row URL · plural if theme spans rows>
Mode: customer · pain-point
Interview date(s): <date(s)>
Customer(s): <names if not under NDA, "Customer A / B / C" otherwise>
Theme recurrence: <count> interviews
— Customer quote(s) —
> "<verbatim line>"
> "<verbatim line>"
— The pain —
<one to two sentences in the customer's framing>
— Your angle —
<one to three sentences in your voice · what to say about this pain>
6. Report back
One-line summary by mode plus the Notion URLs of created rows. Example:
Created 10 ideas (4 trend, 3 performance double-down, 3 customer-pain).
Pipeline view: <link>
Trend
- <title> → notion.so/...
- <title> → notion.so/...
...
Performance double-down
- <title> (riff on "<original>" · 47 reactions) → notion.so/...
...
Customer pain
- <title> (3 interviews · A, B, C) → notion.so/...
...
If any mode soft-blocked (e.g. X user ID missing), mention it in the report.
Defaults
| Knob | Default |
|---|---|
| Mode | Hybrid |
| Time window (trend) | 7 days |
| Time window (performance) | 30 days |
| Time window (customer) | 60 days |
| Cards to create | 10 |
| Trend / performance / customer ratio (hybrid) | 4 / 3 / 3 |
| X account scan | 3 cached creators |
| LinkedIn account scan | Your profile + curated list as IDs are resolved |
| Topic seeds | from seed-accounts.md |
| Engagement floor (X trend) | 50 likes |
| Engagement floor (LI trend) | 100 reactions |
| Customer category filter | User Interview Meeting OR External Meeting |
Don'ts
- Don't paraphrase the original post into your voice as the Title. The Title is the angle you would write · derived from the post, not copied. The original post text goes in the page body.
- Don't surface 30 ideas. Cap at 10-15 default. More creates fatigue, not optionality.
- Don't skip the engagement floor on trend mode. Low-engagement posts on these topics are usually slop, even from good accounts.
- Don't auto-spawn drafts. Status=Idea means just-an-idea. Drafting is a separate step.
- Don't pollute the DB with duplicates. Before creating, do a quick search of recent Idea rows for the same theme. If a similar idea exists, append the new source as another bullet in the existing row's body instead of creating a duplicate.
- Don't fabricate engagement numbers. If the API call fails or returns empty, say so · don't fill in plausible-looking metrics.
- Don't quote customers under NDA verbatim. If the interview notes mark a section private / off-record, paraphrase it in the pain framing and skip the direct quote. When in doubt, ask.
- Don't crawl outside X + LinkedIn + Notion. This skill stays
scoped. For blog / podcast / YouTube discovery, use
WebSearchseparately. - Don't over-double-down on one performance winner. If the same post drives 5 angles, you'll oversaturate one theme. Cap at 2 double-downs per source row.
See also
- Notion Content DB data source:
<YOUR_NOTION_CONTENT_DB_ID> - Notion HUMAN NOTES DB data source:
<YOUR_NOTION_HUMAN_NOTES_DB_ID> - Seed accounts + topic list:
seed-accounts.md - API auth env:
./.env·<YOUR_X_BEARER_TOKEN>(X) ·<YOUR_UNIPILE_DSN>,<YOUR_UNIPILE_API_KEY>,<YOUR_UNIPILE_ACCOUNT_ID>(LinkedIn) - Downstream skills:
/linkedin-copywriter,/x-copywriter,/repurpose,/lead-magnet-creator,/long-form,/youtube-script
| 1 | |
| 2 | name researcher |
| 3 | description The single idea-generation pipeline for marketing content. Three input modes converging on Notion Status=Idea rows. Trend scan (X + LinkedIn creators + topic search) finds what's hot in the world. Performance scan (your own published rows + their engagement metrics) finds what's working for you so you can double down. Customer scan (HUMAN NOTES DB user-interview transcripts) finds the words, pains, and themes from real customer conversations. Hybrid mode runs all three, dedupes, and outputs a balanced backlog. Use when asked to "find content ideas", "what's working", "what's hot", "what are customers saying", "research", "scan trends", "give me ideas for the week", "/researcher", or proactively when the Notion Idea queue is empty. |
| 4 | |
| 5 | |
| 6 | # researcher |
| 7 | |
| 8 | The single discovery pipeline. Three idea sources, one Notion output. |
| 9 | Use this instead of separate /performance-check or /listening skills · |
| 10 | they're folded in as modes here. |
| 11 | |
| 12 | ## When to use |
| 13 | |
| 14 | Trigger on: |
| 15 | "Find me content ideas" |
| 16 | "What's hot on X / LinkedIn" |
| 17 | "What's working for me" |
| 18 | "Pull from my user interviews" |
| 19 | "What are customers saying" |
| 20 | "Scan the GTM space" |
| 21 | "Give me ten posts to write next week" |
| 22 | User explicitly types `/researcher` |
| 23 | Your Notion Content DB has < 5 rows in `Status = Idea` (proactive) |
| 24 | |
| 25 | Skip for: |
| 26 | Verbatim repurposing of one specific post (use `/repurpose`) |
| 27 | Drafting a single post (use `/linkedin-copywriter` or `/x-copywriter`) |
| 28 | Scraping arbitrary websites (this skill is X + LinkedIn + Notion only) |
| 29 | |
| 30 | ## Modes |
| 31 | |
| 32 | ### 1. Trend scan · "what's hot in the world" |
| 33 | |
| 34 | Pull recent posts from a curated list of creators on X + |
| 35 | LinkedIn (account scan) or search by keyword (topic scan). Rank by |
| 36 | engagement. Surface the themes worth riffing on. |
| 37 | |
| 38 | Best for: weekly idea injection, knowing what's resonating broadly. |
| 39 | Risk: noisy, off-niche topics if not filtered. |
| 40 | |
| 41 | ### 2. Performance scan · "what's working for me" |
| 42 | |
| 43 | Pull your own published rows from the Notion Content DB. Fetch |
| 44 | engagement metrics from LinkedIn (Unipile) and X (X API). Rank by |
| 45 | engagement. For top performers, generate **double-down ideas**: |
| 46 | follow-ups, deeper dives, contrarian counter-takes, variations. |
| 47 | |
| 48 | Best for: amplifying signal you already have. The most leveraged |
| 49 | mode because it's grounded in proof. |
| 50 | |
| 51 | ### 3. Customer scan · "what real customers say" |
| 52 | |
| 53 | Query the HUMAN NOTES DB for recent user-interview / external-meeting |
| 54 | rows. Read the transcripts. Extract pain points, direct quotes (use |
| 55 | customer language verbatim), and recurring themes across multiple |
| 56 | interviews. Generate angles tied to those. |
| 57 | |
| 58 | Best for: sharp pain-point posts, customer-quoted content, lead- |
| 59 | magnet topics that solve real problems. The most original mode |
| 60 | because it draws on private signal nobody else has. |
| 61 | |
| 62 | ### 4. Concept scan · "extend your own canon" |
| 63 | |
| 64 | Read the content knowledge graph in `content/concepts/` and |
| 65 | `content/mocs/` (see `content/CONTENT-WIKI.md`). Two moves: |
| 66 | **Extend a thread.** For a high-value concept or an open MOC arc, |
| 67 | propose the next beat: the unwritten angle, the new proof point, the |
| 68 | counter-take, the deeper dive. Ground it in the concept's existing |
| 69 | canonical lines so the new post compounds the old ones. |
| 70 | **Find the gaps.** Surface thin concepts (low `appears_in`) that |
| 71 | deserve more, and recurring ideas in recent posts that have no concept |
| 72 | note yet (candidates for a new node). |
| 73 | |
| 74 | Best for: making content compound instead of restart. The most on-brand |
| 75 | mode because it builds on your own canon, not the feed. (If the graph is |
| 76 | still empty, skip this mode until you've published a few posts.) |
| 77 | |
| 78 | ### 5. Hybrid (recommended for weekly runs) |
| 79 | |
| 80 | Run all four. Dedupe. Output a balanced backlog: 3 trend ideas, 3 |
| 81 | performance double-downs, 2 customer-pain ideas, 2 concept extensions |
| 82 | (or whatever ratio makes sense given recency). When you create an idea |
| 83 | that extends a concept, note `Extends: [[concept-slug]]` on it so the |
| 84 | link exists from the Idea stage. See `content/CONTENT-WIKI.md`. |
| 85 | |
| 86 | ## Workflow |
| 87 | |
| 88 | ### 1. Decide mode + scope |
| 89 | |
| 90 | Ask the user (skip if already specified): |
| 91 | Mode: trend / performance / customer / hybrid (default: hybrid) |
| 92 | Time window: default 7 days for trends, 30 days for performance, |
| 93 | 60 days for customer |
| 94 | How many idea cards to create: default 10, max 25 |
| 95 | |
| 96 | ### 2. Fetch from each active source |
| 97 | |
| 98 | #### Trend scan · X |
| 99 | |
| 100 | |
| 101 | source ./.env |
| 102 | mkdir -p /tmp/researcher |
| 103 | |
| 104 | # Account scan: per cached user ID in seed-accounts.md |
| 105 | for uid in 1893653481858433024 512156315 859850213015597056; do |
| 106 | curl -s "https://api.twitter.com/2/users/${uid}/tweets?max_results=100&tweet.fields=public_metrics,created_at,entities&exclude=retweets,replies" \ |
| 107 | -H "Authorization: Bearer ${X_BEARER_TOKEN}" \ |
| 108 | -o /tmp/researcher/x_${uid}.json |
| 109 | done |
| 110 | |
| 111 | # Topic scan: keyword search (last 7d, English, exclude retweets) |
| 112 | TOPIC="AI GTM agent" |
| 113 | curl -s --get "https://api.twitter.com/2/tweets/search/recent" \ |
| 114 | --data-urlencode "query=${TOPIC} -is:retweet lang:en" \ |
| 115 | --data-urlencode "max_results=50" \ |
| 116 | --data-urlencode "tweet.fields=public_metrics,created_at,author_id,entities" \ |
| 117 | -H "Authorization: Bearer ${X_BEARER_TOKEN}" \ |
| 118 | -o /tmp/researcher/x_topic.json |
| 119 | |
| 120 | |
| 121 | X engagement score: |
| 122 | |
| 123 | score = like_count + 3*retweet_count + 2*reply_count + 3*quote_count |
| 124 | |
| 125 | |
| 126 | #### Trend scan · LinkedIn |
| 127 | |
| 128 | |
| 129 | source ./.env |
| 130 | |
| 131 | for pid in <YOUR_LINKEDIN_PROFILE_ID>; do |
| 132 | curl -s "https://${UNIPILE_DSN}/api/v1/users/${pid}/posts?account_id=${UNIPILE_ACCOUNT_ID}&limit=20" \ |
| 133 | -H "X-API-KEY: ${UNIPILE_API_KEY}" \ |
| 134 | -H "accept: application/json" \ |
| 135 | -o /tmp/researcher/li_${pid}.json |
| 136 | done |
| 137 | |
| 138 | |
| 139 | LinkedIn engagement score: |
| 140 | |
| 141 | score = reaction_counter + 3*comment_counter + 5*share_counter |
| 142 | |
| 143 | |
| 144 | If a seed account in `seed-accounts.md` has profile ID `TBD`, resolve |
| 145 | it on first use: |
| 146 | |
| 147 | |
| 148 | curl -s "https://${UNIPILE_DSN}/api/v1/users?account_id=${UNIPILE_ACCOUNT_ID}&keyword=<name>&limit=5" \ |
| 149 | -H "X-API-KEY: ${UNIPILE_API_KEY}" |
| 150 | |
| 151 | |
| 152 | Pick the right profile, copy the ID into `seed-accounts.md` (commit), |
| 153 | continue. |
| 154 | |
| 155 | #### Performance scan · your own content |
| 156 | |
| 157 | Step 1: query the Notion Content DB for your recent Published rows. |
| 158 | |
| 159 | |
| 160 | Use mcp__claude_ai_Notion__notion-search with: |
| 161 | data_source_url: collection://<YOUR_NOTION_CONTENT_DB_ID> |
| 162 | query: "" |
| 163 | page_size: 25 |
| 164 | filters: { created_date_range: { start_date: "<30d ago>" } } |
| 165 | |
| 166 | |
| 167 | Filter to rows where `Status = Published` and `Live URL` is non-empty. |
| 168 | |
| 169 | Step 2: fetch metrics per Live URL. |
| 170 | |
| 171 | For LinkedIn URLs (pattern `linkedin.com/posts/...`): |
| 172 | |
| 173 | |
| 174 | # Fetch your own posts (your profile ID is cached) |
| 175 | curl -s "https://${UNIPILE_DSN}/api/v1/users/<YOUR_LINKEDIN_PROFILE_ID>/posts?account_id=${UNIPILE_ACCOUNT_ID}&limit=50" \ |
| 176 | -H "X-API-KEY: ${UNIPILE_API_KEY}" \ |
| 177 | -H "accept: application/json" \ |
| 178 | -o /tmp/researcher/li_self.json |
| 179 | |
| 180 | |
| 181 | Match each Notion row's Live URL against the response · use the |
| 182 | post's `reaction_counter`, `comment_counter`, `share_counter`. |
| 183 | |
| 184 | For X URLs (pattern `x.com/<handle>/status/<id>`): |
| 185 | |
| 186 | |
| 187 | # Extract tweet IDs from URLs |
| 188 | TWEET_IDS="1234567890,2345678901,..." # comma-separated |
| 189 | curl -s --get "https://api.twitter.com/2/tweets" \ |
| 190 | --data-urlencode "ids=${TWEET_IDS}" \ |
| 191 | --data-urlencode "tweet.fields=public_metrics,created_at" \ |
| 192 | -H "Authorization: Bearer ${X_BEARER_TOKEN}" |
| 193 | |
| 194 | |
| 195 | If your X user ID is not yet cached in `seed-accounts.md`, the tweet |
| 196 | lookup-by-ID still works without it · we just can't filter to your |
| 197 | own without the ID. Note as soft-blocker if it limits the run. |
| 198 | |
| 199 | Step 3: rank and pick. |
| 200 | |
| 201 | Sort by engagement score (X formula above for tweets, LinkedIn |
| 202 | formula for LI posts). Top 5 are double-down candidates. Bottom 3 |
| 203 | are flop diagnostics (what didn't work · note for avoidance, not for |
| 204 | ideation). |
| 205 | |
| 206 | Step 4: generate double-down angles. |
| 207 | |
| 208 | For each top-5 row: |
| 209 | **Follow-up**: a continuation post answering "and then what |
| 210 | happened?" or "the next step after X" |
| 211 | **Deeper dive**: pick one bullet from the original and make it the |
| 212 | whole post |
| 213 | **Counter-take**: argue the opposite of the original (works if |
| 214 | the original was a popular take · creates contrast) |
| 215 | **Format flip**: original was text → carousel; original was post → thread; etc. |
| 216 | |
| 217 | Pick whichever fits the source. Multi-angle per row is fine if rich |
| 218 | material exists. |
| 219 | |
| 220 | #### Customer scan · HUMAN NOTES DB |
| 221 | |
| 222 | Query the user-interview rows. |
| 223 | |
| 224 | |
| 225 | Use mcp__claude_ai_Notion__notion-search with: |
| 226 | data_source_url: collection://<YOUR_NOTION_HUMAN_NOTES_DB_ID> |
| 227 | query: "" |
| 228 | page_size: 25 |
| 229 | filters: { created_date_range: { start_date: "<60d ago>" } } |
| 230 | |
| 231 | |
| 232 | Filter the response to `Category in ("User Interview Meeting", |
| 233 | "External Meeting")`. Skip Co-Founder Meeting, Dev Notes, Reading |
| 234 | List, Application categories · those aren't customer signal. |
| 235 | |
| 236 | For each surviving row, fetch the page body via |
| 237 | `mcp__claude_ai_Notion__notion-fetch` with the row ID. The body |
| 238 | contains the transcript / notes. |
| 239 | |
| 240 | For each interview, extract: |
| 241 | **Pain points**: 2-4 bullets describing what's broken in the |
| 242 | customer's world (in their words, not yours) |
| 243 | **Direct quotes**: 1-3 quotable lines (verbatim · with attribution |
| 244 | to interview date and customer if not under NDA) |
| 245 | **Recurring themes**: themes that show up across multiple |
| 246 | interviews (note which · a theme in 1 interview is anecdote, in |
| 247 | 3+ it's signal) |
| 248 | |
| 249 | For each recurring theme (3+ occurrences), generate an angle: |
| 250 | The pain stated as a question you have the answer to |
| 251 | A framework that resolves the pain |
| 252 | A contrarian take on common-but-wrong solutions in that space |
| 253 | A customer-quote post (the verbatim line as the hook) |
| 254 | |
| 255 | ### 3. Filter (all modes) |
| 256 | |
| 257 | Drop posts older than the time window |
| 258 | Drop banned-signal posts (see `seed-accounts.md` § "Banned signals") |
| 259 | Drop URL-only / image-only posts with no text body |
| 260 | Drop posts under the engagement floor (trend mode only · 50 likes |
| 261 | on X · 100 reactions on LinkedIn) |
| 262 | For customer scan: drop interviews under 5 minutes (likely no-shows |
| 263 | or aborted) and skip the ones marked "private · do not use" |
| 264 | |
| 265 | ### 4. Cluster + angle (all modes) |
| 266 | |
| 267 | Read all surviving inputs. Group by theme · expect 5-10. For each |
| 268 | theme, pick the strongest representative (highest engagement for |
| 269 | trends, top performer for performance, most-quoted for customer) |
| 270 | and write: |
| 271 | |
| 272 | **Angle**: a one-sentence hook you could use, in your voice (terse, |
| 273 | contrarian, concrete, direct, no hype) |
| 274 | **Why it's hot / working / real**: one sentence on why this matters |
| 275 | **Suggested Pillar**: pick one of the six (`Building in Public`, |
| 276 | `Educational / Tactical`, `Personal`, `Memes`, `Promotional`, |
| 277 | `Trend Insights`) |
| 278 | **Suggested Format + Channel**: usually `Text` on `LinkedIn` or `X` |
| 279 | · sometimes `Long-form Article` for richer themes · sometimes |
| 280 | `Lead Magnet` for customer-pain frameworks |
| 281 | |
| 282 | ### 5. Create Notion rows |
| 283 | |
| 284 | For each idea card, call |
| 285 | `mcp__claude_ai_Notion__notion-create-pages` with data source |
| 286 | `<YOUR_NOTION_CONTENT_DB_ID>`. Properties: |
| 287 | |
| 288 | **Title**: the one-sentence angle (max ~80 chars) |
| 289 | **Status**: `Idea` |
| 290 | **Pillar**: suggested multi-select (single value usually) |
| 291 | **Format**: suggested |
| 292 | **Channel**: suggested |
| 293 | |
| 294 | Page body, branched by mode: |
| 295 | |
| 296 | #### Trend mode body |
| 297 | |
| 298 | Source: <original post URL> |
| 299 | Mode: trend |
| 300 | Author: <handle / name> |
| 301 | Engagement: <metrics line> |
| 302 | Window: <date range> |
| 303 | |
| 304 | — Original post — |
| 305 | > <quoted post text> |
| 306 | |
| 307 | — Why this is hot — |
| 308 | <one sentence> |
| 309 | |
| 310 | — Your angle — |
| 311 | <one to three sentences in your voice> |
| 312 | |
| 313 | |
| 314 | #### Performance mode body |
| 315 | |
| 316 | Source: <your published Notion row URL> |
| 317 | Mode: performance · double-down |
| 318 | Original metrics: <metrics line> |
| 319 | Pillar of original: <pillar> |
| 320 | |
| 321 | — Original post — |
| 322 | > <quoted post text> |
| 323 | |
| 324 | — Why this performed — |
| 325 | <one sentence on what worked> |
| 326 | |
| 327 | — Double-down angle — |
| 328 | <one to three sentences · what to write next that builds on the win> |
| 329 | |
| 330 | |
| 331 | #### Customer mode body |
| 332 | |
| 333 | Source: <interview Notion row URL · plural if theme spans rows> |
| 334 | Mode: customer · pain-point |
| 335 | Interview date(s): <date(s)> |
| 336 | Customer(s): <names if not under NDA, "Customer A / B / C" otherwise> |
| 337 | Theme recurrence: <count> interviews |
| 338 | |
| 339 | — Customer quote(s) — |
| 340 | > "<verbatim line>" |
| 341 | > "<verbatim line>" |
| 342 | |
| 343 | — The pain — |
| 344 | <one to two sentences in the customer's framing> |
| 345 | |
| 346 | — Your angle — |
| 347 | <one to three sentences in your voice · what to say about this pain> |
| 348 | |
| 349 | |
| 350 | ### 6. Report back |
| 351 | |
| 352 | One-line summary by mode plus the Notion URLs of created rows. |
| 353 | Example: |
| 354 | |
| 355 | |
| 356 | Created 10 ideas (4 trend, 3 performance double-down, 3 customer-pain). |
| 357 | Pipeline view: <link> |
| 358 | |
| 359 | Trend |
| 360 | - <title> → notion.so/... |
| 361 | - <title> → notion.so/... |
| 362 | ... |
| 363 | Performance double-down |
| 364 | - <title> (riff on "<original>" · 47 reactions) → notion.so/... |
| 365 | ... |
| 366 | Customer pain |
| 367 | - <title> (3 interviews · A, B, C) → notion.so/... |
| 368 | ... |
| 369 | |
| 370 | |
| 371 | If any mode soft-blocked (e.g. X user ID missing), mention it in the |
| 372 | report. |
| 373 | |
| 374 | ## Defaults |
| 375 | |
| 376 | | Knob | Default | |
| 377 | | --------------------------- | ------------------ | |
| 378 | | Mode | Hybrid | |
| 379 | | Time window (trend) | 7 days | |
| 380 | | Time window (performance) | 30 days | |
| 381 | | Time window (customer) | 60 days | |
| 382 | | Cards to create | 10 | |
| 383 | | Trend / performance / customer ratio (hybrid) | 4 / 3 / 3 | |
| 384 | | X account scan | 3 cached creators | |
| 385 | | LinkedIn account scan | Your profile + curated list as IDs are resolved | |
| 386 | | Topic seeds | from `seed-accounts.md` | |
| 387 | | Engagement floor (X trend) | 50 likes | |
| 388 | | Engagement floor (LI trend) | 100 reactions | |
| 389 | | Customer category filter | `User Interview Meeting` OR `External Meeting` | |
| 390 | |
| 391 | ## Don'ts |
| 392 | |
| 393 | **Don't paraphrase the original post into your voice as the Title.** |
| 394 | The Title is the angle you would write · derived from the post, not |
| 395 | copied. The original post text goes in the page body. |
| 396 | **Don't surface 30 ideas.** Cap at 10-15 default. More creates |
| 397 | fatigue, not optionality. |
| 398 | **Don't skip the engagement floor on trend mode.** Low-engagement |
| 399 | posts on these topics are usually slop, even from good accounts. |
| 400 | **Don't auto-spawn drafts.** Status=Idea means just-an-idea. |
| 401 | Drafting is a separate step. |
| 402 | **Don't pollute the DB with duplicates.** Before creating, do a |
| 403 | quick search of recent Idea rows for the same theme. If a similar |
| 404 | idea exists, append the new source as another bullet in the |
| 405 | existing row's body instead of creating a duplicate. |
| 406 | **Don't fabricate engagement numbers.** If the API call fails or |
| 407 | returns empty, say so · don't fill in plausible-looking metrics. |
| 408 | **Don't quote customers under NDA verbatim.** If the interview |
| 409 | notes mark a section private / off-record, paraphrase it in the |
| 410 | pain framing and skip the direct quote. When in doubt, ask. |
| 411 | **Don't crawl outside X + LinkedIn + Notion.** This skill stays |
| 412 | scoped. For blog / podcast / YouTube discovery, use `WebSearch` |
| 413 | separately. |
| 414 | **Don't over-double-down on one performance winner.** If the same |
| 415 | post drives 5 angles, you'll oversaturate one theme. Cap at 2 |
| 416 | double-downs per source row. |
| 417 | |
| 418 | ## See also |
| 419 | |
| 420 | Notion Content DB data source: `<YOUR_NOTION_CONTENT_DB_ID>` |
| 421 | Notion HUMAN NOTES DB data source: `<YOUR_NOTION_HUMAN_NOTES_DB_ID>` |
| 422 | Seed accounts + topic list: [`seed-accounts.md`] |
| 423 | API auth env: `./.env` · `<YOUR_X_BEARER_TOKEN>` (X) · `<YOUR_UNIPILE_DSN>`, |
| 424 | `<YOUR_UNIPILE_API_KEY>`, `<YOUR_UNIPILE_ACCOUNT_ID>` (LinkedIn) |
| 425 | Downstream skills: `/linkedin-copywriter`, `/x-copywriter`, |
| 426 | `/repurpose`, `/lead-magnet-creator`, `/long-form`, |
| 427 | `/youtube-script` |
| 428 |
Discussion
Browse more free Claude skills.