Cold Email Outreach logo

Cold Email Outreach

Organization
hyperfx-ai
cold-email-outreach

Run end-to-end B2B cold-email outreach through the Hyper MCP — enrich prospects with Apollo, scrape per-prospect signals from company sites and LinkedIn, draft personalized emails using proven hook frameworks, send via Gmail with safe defaults, and route replies into labeled folders. Use when the user wants to write cold emails, run an outbound sequence, prospect a list, build a follow-up cadence, "reach out to leads," or asks why nobody is replying to their cold emails.

Overview

Publisherhyperfx-ai
Repositorymarketing-skills
Skill namecold-email-outreach
Stars
107
Forks
21
Bundled files
3
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 3 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by hyperfx-ai on GitHub. Read the source before you install it.

Installation

Install the Cold Email Outreach AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/hyperfx-ai/marketing-skills/tree/main/skills/cold-email-outreach
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/hyperfx-ai/marketing-skills.git /tmp/marketing-skills
mkdir -p .claude/skills
cp -r /tmp/marketing-skills/skills/cold-email-outreach .claude/skills/cold-email-outreach
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Cold Email Outreach in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Cold Email Outreach on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Cold Email Outreach is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Cold Email Outreach

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.

Out of scope — defer to other skills

RequestSend 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 replycrm-revops (planned)
Scraping competitor adsmeta-ads-library

Requirements

  • Hyper MCP installed and connected. https://app.hyperfx.ai/mcp
  • Gmail integration connected at https://app.hyperfx.ai/apps — supplies the sending account.
  • Apollo integration connected — supplies prospect search and email enrichment.
  • Firecrawl (bundled) — for company-page signals.
  • Optional: LinkedIn scraper (bundled, runs through Apify) — for richer per-prospect personalization.

If gmail_messages_send is not found, the integration to connect is Gmail; if apollo_people_search is not found, it is Apollo.

How to run the tools in this skill

Every tool in this skill is named by its canonical tool name. Run it with the call your surface gives you:

SurfaceFind a toolRun it
Hyper chatCall the tool by its name; search_tools(queries=["<provider> <action>"]) shows its parameters<name>(...)
MCP client (Claude, Cursor, Codex, ChatGPT)search("<what you want to do>"), then describe("<name>")call_read("<name>", {...}), call_write or call_destructive: the one that describe names in call_with
Hyper CLIhyperai search "<what you want to do>", then hyperai describe <name>hyperai call <name> --json '{...}'

If a tool is not found: in Hyper chat, find its toolkit id with discover_toolkits and pass it to enable_toolkit. On an MCP client or the CLI, tell the user which integration to connect in Hyper.

Tool surface

PhaseTools
Prospect researchapollo_people_search, apollo_companies_search, apollo_people_match_bulk (preferred for 2+ enrich), apollo_people_match (single only)
Per-prospect signalsfirecrawl_urls_scrape, firecrawl_urls_scrape_batch, firecrawl_branding_extract, firecrawl_screenshots_create, scrape_linkedin_profiles (conditional — requires LinkedIn Apify integration)
Draftinggmail_drafts_create, gmail_drafts_update, gmail_drafts_get, gmail_drafts_list
Sendinggmail_messages_send, gmail_drafts_send, gmail_messages_reply
Reply routinggmail_messages_list, gmail_messages_get, gmail_labels_create, gmail_labels_add, gmail_labels_remove, gmail_messages_move_to_label (takes label_id string, not label_ids array)

Critical rules

  1. Never loop apollo_people_match for multiple prospects. For 2+ records always batch into apollo_people_match_bulk. Apollo's tool description warns about this explicitly — looping single-match calls burns credits and is much slower.
  2. Default send mode = drafts-first for review. For any campaign with 4+ prospects, draft the first 1–3 with gmail_drafts_create, show them to the user, get explicit approval, then batch-send the rest with gmail_messages_send. Never send a full campaign without showing samples first.
  3. One label per campaign. Create a cold/<campaign-name> label with gmail_labels_create 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.
  4. Stay under Gmail's send limits. ~500 messages/day per consumer Gmail account, ~2,000/day per Workspace user. Space sends out — see references/deliverability.md for warming and per-day pacing.
  5. Personalization must connect to the problem. If the personalized opener could be deleted and the email still makes sense, it isn't doing any work. The opener should naturally bridge into why you're emailing.
  6. One ask per email, one CTA. Interest-based (Worth exploring?) beats meeting requests on cold touch 1.
  7. Honor unsubscribes immediately. Apply an unsubscribed label on any "remove me / not interested" reply and never re-target that address from the same Hyper workspace.

Workflow

Phase 1 — Define the campaign (always do this first)

Get the user to commit to:

  1. ICP — Role(s), industry, company size, tech stack, geography. Concrete: "Heads of Growth at US-based pre-seed-to-Series-A B2B SaaS, 10–50 employees, using HubSpot."
  2. The ask — What does a "yes" look like? (15-min call, async reply, demo, intro to someone else.)
  3. Value prop in one sentence — "We help X do Y so they can Z."
  4. Proof point — One specific result: "We helped Notion cut their CAC by 31% in 90 days." (Made up examples are worse than no example — get a real one.)
  5. Trigger / signal (optional but powerful) — Funding round, hiring, pricing-page change, recent blog post, product launch, leadership change.
  6. Sender + reply-to — Which Gmail account is sending. (Confirm with gmail_labels_list to verify the integration is live.)
  7. Volume + cadence — Total prospects, max sends/day, follow-up gap pattern.

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.

Phase 2 — Build & enrich the prospect list

# Search by ICP
apollo_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_match_bulk(
  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_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_companies_search when you need data beyond what the person search returns.

Phase 3 — Per-prospect signals (the personalization layer)

For each prospect, gather one specific observation that connects to the problem you solve. Use the cheapest signal that works:

CostToolUse it for
Free (already have it)Apollo response fieldsTitle change, recent role start, company headcount jump, funding
Cheapfirecrawl_urls_scrape 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_urls_scrape_batchSame observation across many sites in one call
Mediumfirecrawl_branding_extractBrand 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):

  • Tier 1 (mass / low-effort) — first name + role + company + industry. Acceptable only when the value prop is sharp enough to carry the email on its own. Reply rates: low.
  • Tier 2 (signal-based) — the prospect is in a role/stage where the problem you solve is acute (e.g., a new Head of Growth in their first 60 days). Reply rates: meaningfully better.
  • Tier 3 (observation-based) — references something from the company site, pricing page, careers page, or a recent product launch. This is the sweet spot.
  • Tier 4 (deep) — references a recent LinkedIn post, blog post they wrote, or talk they gave. Reserve for high-value targets.

Anything below Tier 2 should be treated with suspicion — {{FirstName}} swaps don't count as personalization.

Phase 4 — Draft emails (drafts-first by default)

Pick a framework that matches the situation. The four shapes that consistently work:

  • Observation → Problem → Proof → Ask — "You're hiring SDRs. That usually means meetings/SDR ratio is the bottleneck. We helped [company] hit X. Worth exploring?"
  • Question → Value → Ask — "Struggling with [problem]? We do [Y]. [Company Z] saw [result]. Worth a look?"
  • Trigger → Insight → Ask — "Congrats on [funding/launch]. That usually creates [Y challenge]. We've helped similar teams with that. Curious?"
  • Story → Bridge → Ask — "[Similar company] had [problem]. They [solved it this way with us]. Relevant to you?"

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.

  • Write like a peer, not a vendor. Use contractions. Read it aloud — if it sounds like marketing copy, rewrite it.
  • "You/your" should outnumber "I/we" by ≥2:1.
  • Every sentence must move the reader toward replying. The best cold emails feel like they could have been shorter, not longer.
  • Calibrate to seniority: C-suite → ultra-brief and peer-level. Mid-level → more specific value. Technical → precise, no fluff, respect their intelligence.

What to avoid (these are the AI-tells reviewers immediately spot):

  • "I hope this email finds you well." / "I came across your profile."
  • "leverage", "synergy", "best-in-class", "leading provider", "circle back"
  • Feature dumps. One proof point beats ten features.
  • HTML, images, multiple links.
  • Fake Re: / Fwd: subject lines.
  • Identical templates with only {{FirstName}} swapped.
  • Asking for a 30-minute call on touch 1.

Drafts-first send pattern (default for any 4+ prospect campaign):

# 1. Create label for the campaign once — capture the returned id
label = gmail_labels_create(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_drafts_create(
      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_messages_send(
      to=p["email"],
      subject="quick question",
      body=render_email(framework="observation", prospect=p),
    )
    gmail_labels_add(message_id=result["id"], label_ids=[campaign_label_id])

If the user wants every email reviewed, use gmail_drafts_create for all of them and send via gmail_drafts_send 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_messages_send from prospect 1. Default behavior is drafts-first.

Phase 5 — Run the follow-up cadence

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):

TouchDayAngleTool
10Initial framework (observation/question/trigger/story)gmail_messages_send
2+3Reply in the same thread, add a one-line specific proofgmail_messages_reply
3+7Different angle (if 1 was observation, try question or value-first)gmail_messages_reply
4+14Useful free resource — case study, calculator, teardowngmail_messages_reply
5+21Breakup email. "Closing your file unless I hear back. Worth keeping the door open?"gmail_messages_reply

Always reply in the original thread (gmail_messages_reply 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.

Phase 6 — Track replies and route them

# Pull all replies on the campaign label from the last 7 days
gmail_messages_list(query="label:cold/q3-growth-leads is:unread newer_than:7d")

For each reply, read the body with gmail_messages_get(message_id=...), classify it, and label:

ClassificationLabelWhat to do
Interested ("yes / tell me more / send a calendar")cold/q3-growth-leads/interestedStop the sequence. Hand off (eventually crm-revops once shipped).
Objection ("we use X / no budget / try us in Q4")cold/q3-growth-leads/objectionReply with one specific response, then stop sequence.
Not now ("circle back later")cold/q3-growth-leads/not-nowStop sequence. Re-tag for re-engagement in 90 days.
Unsubscribe ("remove me / not interested")cold/q3-growth-leads/unsubscribedStop sequence. Add unsubscribed global label. Never re-contact.
Out-of-officecold/q3-growth-leads/oooPause sequence, resume after the OOO end date in the message.

Apply classification and clear unread with two separate calls:

gmail_labels_add(message_id=..., label_ids=[classification_label_id])
gmail_labels_remove(message_id=..., label_ids=["UNREAD"])

Create the sub-labels once with gmail_labels_create and capture their IDs before the routing loop.

Quality check (before any send)

Read each draft against this gut-check. Reject any that fail more than one:

  • Does it sound like a human wrote it? (Read it aloud.)
  • Would you reply if you got this?
  • Does every sentence serve the reader, not the sender?
  • Is the personalization connected to the problem you solve — not just a generic compliment?
  • Is there one clear, low-friction ask?
  • Does the subject line look like it came from a colleague?
  • Is the email under ~120 words on touch 1?

Reference workflows

For long-form material — read on demand:

ReferenceWhen to read
references/frameworks.mdChoosing a framework, full examples, calibrating tone by seniority
references/follow-up-sequences.mdBuilding the multi-touch cadence, angle rotation, breakup email templates
references/deliverability.mdGmail rate limits, sender warming, SPF/DKIM/DMARC, list hygiene, blocklist recovery

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Cold Email Outreach AI skill do?

Run end-to-end B2B cold-email outreach through the Hyper MCP — enrich prospects with Apollo, scrape per-prospect signals from company sites and LinkedIn, draft personalized emails using proven hook frameworks, send via Gmail with safe defaults, and route replies into labeled folders. Use when the user wants to write cold emails, run an outbound sequence, prospect a list, build a follow-up cadence, "reach out to leads," or asks why nobody is replying to their cold emails.

Why use Cold Email Outreach on TypingMind?

Because you install it once and use it with any model. Cold Email Outreach is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Cold Email Outreach in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/hyperfx-ai/marketing-skills/tree/main/skills/cold-email-outreach. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Cold Email Outreach?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Cold Email Outreach?

As many as you like. As long as a model supports skills, you can use Cold Email Outreach with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Cold Email Outreach AI skill free?

Yes. It is published on GitHub by hyperfx-ai under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇