Help us improve
Share bugs, ideas, or general feedback.
From hyper-marketing
Researches prospects via Apollo, scrapes company/LinkedIn signals, drafts personalized cold emails using proven hook frameworks, sends through Gmail, and routes replies into labeled folders.
npx claudepluginhub hyperfx-ai/marketing-skills --plugin hyper-marketingHow this skill is triggered — by the user, by Claude, or both
Slash command
/hyper-marketing:cold-email-outreachThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
End-to-end cold outreach: research, draft, send, follow up, route replies. Strategy is grounded in proven hook frameworks (number-led / question / pain-point / benefit-first); the execution runs on Apollo, Firecrawl, the LinkedIn scraper, and Gmail through the Hyper MCP.
Builds high-response cold outreach campaigns with personalized sequences, response handling, and compliance. For B2B sales and SDR workflows.
Generates personalized multi-channel outreach sequences across email, LinkedIn, and phone from buying signals. Outputs 4-6 ready-to-send touchpoints over 10-14 days, optionally drafts emails via Composio Gmail.
Researches prospects via web or connected enrichment/CRM, then drafts personalized cold emails, subjects, and LinkedIn messages.
Share bugs, ideas, or general feedback.
End-to-end cold outreach: research, draft, send, follow up, route replies. Strategy is grounded in proven hook frameworks (number-led / question / pain-point / benefit-first); the execution runs on Apollo, Firecrawl, the LinkedIn scraper, and Gmail through the Hyper MCP.
| Request | Send them to |
|---|---|
| Lifecycle / nurture sequences for warm leads (welcome, onboarding, re-engagement, win-back) | email-lifecycle (planned) |
| LinkedIn DMs, connection requests, or Sales Navigator workflows | (planned) |
| Lead scoring, routing, deal-stage updates after a reply | crm-revops (planned) |
| Scraping competitor ads | meta-ads-library |
If gmail_send_message and apollo_mixed_people_search are not in the agent's tool list, stop and tell the user to enable the Hyper MCP and connect Gmail + Apollo.
| Phase | Tools |
|---|---|
| Prospect research | apollo_mixed_people_search, apollo_mixed_companies_search, apollo_people_bulk_match (preferred for 2+ enrich), apollo_people_match (single only) |
| Per-prospect signals | firecrawl_scrape_url, firecrawl_batch_scrape, firecrawl_extract_branding, firecrawl_screenshot, scrape_linkedin_profiles (conditional — requires LinkedIn Apify integration) |
| Drafting | gmail_create_draft, gmail_update_draft, gmail_get_draft, gmail_list_drafts |
| Sending | gmail_send_message, gmail_send_draft, gmail_reply_to_message |
| Reply routing | gmail_list_messages, gmail_get_message, gmail_create_label, gmail_add_labels, gmail_remove_labels, gmail_move_email_to_label (takes label_id string, not label_ids array) |
apollo_people_match for multiple prospects. For 2+ records always batch into apollo_people_bulk_match. Apollo's tool description warns about this explicitly — looping single-match calls burns credits and is much slower.gmail_create_draft, show them to the user, get explicit approval, then batch-send the rest with gmail_send_message. Never send a full campaign without showing samples first.cold/<campaign-name> label with gmail_create_label at the start, apply it to every send, then track replies by searching that label. This is what makes Phase 6 reply routing actually work.references/deliverability.md for warming and per-day pacing.Worth exploring?) beats meeting requests on cold touch 1.unsubscribed label on any "remove me / not interested" reply and never re-target that address from the same Hyper workspace.Get the user to commit to:
gmail_list_labels to verify the integration is live.)If they're stuck on any of these, push back. A campaign without proof or a clear ask will not perform regardless of how clever the writing is.
# Search by ICP
apollo_mixed_people_search(
person_titles=["Head of Growth", "VP Growth", "Director of Growth"],
organization_num_employees_ranges=["11,50"],
person_locations=["United States"],
per_page=50,
)
Then for the prospects you actually want to contact, batch-enrich for emails:
# CORRECT — one bulk call for many prospects
apollo_people_bulk_match(
details=[
{"first_name": "...", "last_name": "...", "domain": "..."},
...up to 10 per call...
],
reveal_personal_emails=True,
)
Only fall back to apollo_people_match for single-prospect lookups (e.g., the user pastes one LinkedIn URL).
For deeper company-level context (industry, revenue range, tech stack), call apollo_mixed_companies_search by organization name on the companies you want to enrich. Note that person search results already include core company fields (headcount, industry, location) — only reach for apollo_mixed_companies_search when you need data beyond what the person search returns.
For each prospect, gather one specific observation that connects to the problem you solve. Use the cheapest signal that works:
| Cost | Tool | Use it for |
|---|---|---|
| Free (already have it) | Apollo response fields | Title change, recent role start, company headcount jump, funding |
| Cheap | firecrawl_scrape_url of the careers / pricing / blog page | "You're hiring 4 SDRs", "Pricing pages says enterprise plan launching", "Latest blog post is about X" |
| Cheap (multi-page) | firecrawl_batch_scrape | Same observation across many sites in one call |
| Medium | firecrawl_extract_branding | Brand voice for the email tone, brand colors if you'll send a follow-up image |
| Higher (conditional) | scrape_linkedin_profiles(profile_urls=[...]) (requires LinkedIn Apify integration — skip if not connected) | Recent post, mutual connection, recent job change, school/employer overlap |
Personalization tiers (use the highest tier you can afford for this campaign):
Anything below Tier 2 should be treated with suspicion — {{FirstName}} swaps don't count as personalization.
Pick a framework that matches the situation. The four shapes that consistently work:
See references/frameworks.md for full examples and when each shape works best.
Subject lines. Short, lowercase, internal-looking. 2–4 words. No emojis, no first names, no urgency tricks. Targets: looks-like-a-colleague-sent-it. Examples: quick question, reply rates, hiring ops, q3 forecast, for {{company}}. Avoid: Increase your revenue 10x!, John, are you free Thursday?, [URGENT] follow-up.
Voice rules.
What to avoid (these are the AI-tells reviewers immediately spot):
Re: / Fwd: subject lines.{{FirstName}} swapped.Drafts-first send pattern (default for any 4+ prospect campaign):
# 1. Create label for the campaign once — capture the returned id
label = gmail_create_label(name="cold/q3-growth-leads")
campaign_label_id = label["id"]
# 2. Draft the first 1-3 prospects for user review
for p in prospects[:3]:
gmail_create_draft(
to=p["email"],
subject="quick question",
body=render_email(framework="observation", prospect=p),
)
# 3. Show drafts to user, await explicit approval
# 4. After approval, send and label each message
for p in prospects[3:]:
result = gmail_send_message(
to=p["email"],
subject="quick question",
body=render_email(framework="observation", prospect=p),
)
gmail_add_labels(message_id=result["id"], label_ids=[campaign_label_id])
If the user wants every email reviewed, use gmail_create_draft for all of them and send via gmail_send_draft after approval. If the user is confident and the templates are pre-approved (e.g., they've run this campaign shape before), you can skip directly to gmail_send_message from prospect 1. Default behavior is drafts-first.
3–5 total touches with widening gaps. Each follow-up adds something new — a different angle, fresh proof, a useful resource. "Just checking in" gives the reader no reason to respond.
Default cadence (adjust to the user's situation):
| Touch | Day | Angle | Tool |
|---|---|---|---|
| 1 | 0 | Initial framework (observation/question/trigger/story) | gmail_send_message |
| 2 | +3 | Reply in the same thread, add a one-line specific proof | gmail_reply_to_message |
| 3 | +7 | Different angle (if 1 was observation, try question or value-first) | gmail_reply_to_message |
| 4 | +14 | Useful free resource — case study, calculator, teardown | gmail_reply_to_message |
| 5 | +21 | Breakup email. "Closing your file unless I hear back. Worth keeping the door open?" | gmail_reply_to_message |
Always reply in the original thread (gmail_reply_to_message with the message_id returned from the touch-1 send) — preserves context and improves deliverability. See references/follow-up-sequences.md for angle rotation, breakup-email templates, and how to prune prospects mid-sequence.
# Pull all replies on the campaign label from the last 7 days
gmail_list_messages(query="label:cold/q3-growth-leads is:unread newer_than:7d")
For each reply, read the body with gmail_get_message(message_id=...), classify it, and label:
| Classification | Label | What to do |
|---|---|---|
| Interested ("yes / tell me more / send a calendar") | cold/q3-growth-leads/interested | Stop the sequence. Hand off (eventually crm-revops once shipped). |
| Objection ("we use X / no budget / try us in Q4") | cold/q3-growth-leads/objection | Reply with one specific response, then stop sequence. |
| Not now ("circle back later") | cold/q3-growth-leads/not-now | Stop sequence. Re-tag for re-engagement in 90 days. |
| Unsubscribe ("remove me / not interested") | cold/q3-growth-leads/unsubscribed | Stop sequence. Add unsubscribed global label. Never re-contact. |
| Out-of-office | cold/q3-growth-leads/ooo | Pause sequence, resume after the OOO end date in the message. |
Apply classification and clear unread with two separate calls:
gmail_add_labels(message_id=..., label_ids=[classification_label_id])
gmail_remove_labels(message_id=..., label_ids=["UNREAD"])
Create the sub-labels once with gmail_create_label and capture their IDs before the routing loop.
Read each draft against this gut-check. Reject any that fail more than one:
For long-form material — read on demand:
| Reference | When to read |
|---|---|
references/frameworks.md | Choosing a framework, full examples, calibrating tone by seniority |
references/follow-up-sequences.md | Building the multi-touch cadence, angle rotation, breakup email templates |
references/deliverability.md | Gmail rate limits, sender warming, SPF/DKIM/DMARC, list hygiene, blocklist recovery |