From intent-outreach
Run a research → enrich → outreach SDR campaign from inside Claude Code, fully local with your own data-provider + model keys. Use when the user wants to prospect companies, build a lead list, research accounts, or draft personalized cold outreach (email or LinkedIn) over domains they name. Triggers: "run an outreach campaign", "prospect these companies", "research these domains", "draft cold emails to", "build me a lead list", "/intent-outreach".
How this skill is triggered — by the user, by Claude, or both
Slash command
/intent-outreach:intent-outreach <ICP description> <comma,separated,domains><ICP description> <comma,separated,domains>inheritThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
**Problem:** founders doing their own outbound have no SDR and won't pay per-seat data tools, yet cold
Problem: founders doing their own outbound have no SDR and won't pay per-seat data tools, yet cold outreach still needs real research + enrichment to land. Solution: run a deterministic Research → Enrich → Outreach campaign entirely on the user's machine with their own keys, drafting grounded outreach the user approves before anything is saved.
Drive the bundled Intent Outreach MCP server through fixed phases, in order. This is ONE skill — do not spawn subagents or let tool choice become improvised. The connectors decide what data comes back; the model only molds that data into outreach. Everything is local; keys are the user's own.
save_run, which validates before it
writes. If save_run returns a validation error, fix the run and retry — never work around it.list_connectors. Show the user which data connectors are configured (have a key) and
which are skipped, with each one's tier (free / paid / enterprise / legacy).APOLLO_API_KEY, HUNTER_API_KEY) — Apollo + Hunter both have free tiers, so a full campaign can
run for free. Authentication is per-connector BYO: each MCP tool authenticates to its provider
with your own API key read from the environment (no shared credentials, no login); keys never leave
the machine except to each provider's own API.For each domain, call research_domain(domain, icp). Aggregate the returned leads and
contacts. Present a compact table (company, industry, size, # contacts). Checkpoint: let the user
drop any companies before spending enrichment calls.
For each lead the user kept, call enrich_lead(domain, companyName, contacts). Collect the
enrichments (funding, verified emails/phones, web context). Show the user the new signals.
For each lead:
prompts/outreach.v1.md
the standalone pipeline uses):
Show the drafts. Checkpoint: the user approves, edits, or rejects each before anything is saved.
Assemble the run and call save_run with: id (a unique id you generate, e.g. from the current time), icp, domains,
provider (the model you used), model, and the arrays leads, contacts, enrichments,
messages (each message: contactKey, channel, subject?, body, cta, fitScore?, model,
promptVersion: "outreach.v1", createdAt). save_run validates and appends to the local JSONL
store; report the saved path and counts. If it returns a validation error, correct the offending
field and call it again.
User: "/intent-outreach — prospect stripe.com and linear.app, ICP = seed-stage dev-tools founders, draft cold emails."
list_connectors shows apollo + hunter configured (free tier). Confirm the ICP, the two domains, channel = email, 1 contact each.research_domain("stripe.com", icp) then research_domain("linear.app", icp); present the leads + contacts table. The user keeps both.enrich_lead(...) per lead; surface funding + verified emails.save_run; it validates and appends a CampaignRun to ~/.intent-outreach/runs.jsonl. Report the saved path + counts.The save_run payload you assemble looks like:
{
"id": "run-2026-06-16-devtools",
"icp": "seed-stage dev-tools founders",
"domains": ["stripe.com", "linear.app"],
"provider": "anthropic",
"model": "claude-sonnet-4-6",
"leads": [{ "domain": "linear.app", "companyName": "Linear", "source": "apollo" }],
"contacts": [{ "name": "A. Founder", "leadDomain": "linear.app", "email": "[email protected]", "source": "apollo" }],
"enrichments": [{ "subjectType": "lead", "subjectKey": "linear.app", "provider": "crunchbase", "data": {} }],
"messages": [{ "contactKey": "[email protected]", "channel": "email", "body": "...", "cta": "Open to a quick call?", "model": "claude-sonnet-4-6", "promptVersion": "outreach.v1", "createdAt": "..." }]
}
This runs on whatever model Claude Code is using. To drive a non-Anthropic model from inside Claude
Code, point ANTHROPIC_BASE_URL at an LLM gateway (LiteLLM/Bifrost) that translates to OpenAI / Grok
/ Gemini. The standalone intent-outreach CLI can also target a provider directly with that
provider's key — but only providers that have passed the eval gate are marketed as supported (Claude
is the default). See 000-docs/017-AT-DECR.
If the user has a Report Profile (a local file under profiles/ or ~/.intent-outreach/profiles/),
use Read to load it and honor its knobs — intake, filtering, tone/length, output formats, and
delivery. The profile owns the deterministic choices; the model owns the creative drafting. Full knob
reference and the shipped starters: references/report-profiles.md.
npx claudepluginhub jeremylongshore/intent-outreach --plugin intent-outreachSearches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.