keinsaasforever/gtm-pipeline-skills/gtm-demo
Claude Code and agent skill by keinsaasforever/gtm-pipeline-skills
- community
Checking that the SKILL.md file is still in the repository.
Generate a demo lead list of ~10 enriched contacts with personalized message examples. Use when a demo is requested, a webhook prompt describes a target audience, or someone asks to "create a demo for [client]". Enforces demo mode restrictions (email only, no phone, ~10 contacts). Chains people-search → contact-filter → people-enrichment → (optional signal-search) → message generation. Pass `--with-signals` (or ask the user) to enable a buying-intent scoring pass before message generation — pricier but produces sharper, signal-anchored messages.
Install
npx vskill@latest install keinsaasforever/gtm-pipeline-skills/gtm-demoSKILL.md
Demo
Generate a demo lead list of ~10 enriched contacts with personalized message examples, triggered by a webhook prompt.
Read `~/.claude/skills/gtm-pipeline/_shared/conventions.md` before executing.
When to Use
- Webhook trigger: user submits a free demo form describing their target audience
- Goal: prove the AI agent writes authentic, non-generic outreach using real leads
- Scope: ~10 contacts, enriched with LinkedIn + email, 2–4 message examples
Demo Restrictions
- No phone enrichment — email only
- ~10 contacts (request 10–15, expect enrichment drop-off)
- Message generation is optional but recommended
- Signal search is opt-in — off by default. Enable via
--with-signalsflag or explicit user request. See Step 5.5. - Cost gate: before the first paid provider call, state the expected spend (finder searches per People-Source Cadence are mostly free; ~10-15 email enrichment credits; signals <$0.50 if enabled). Interactive: confirm with the user first. Headless: log the estimate in
run_log.mdand proceed, never block.
Step 1 — Parse the Prompt & Establish the ICP
The webhook prompt describes the user's target audience. Extract:
Must have:
- What do you sell / offer?
- Who is your ideal customer? (industry, role, company size, location)
- What's your value proposition?
- What tone? (formal vs. casual, examples if possible)
- Is this for recruiting OR selling to customers?
If not in the prompt, infer (do not stall):
- Target job titles, location, company size/type
Auto-resolve the requester before interpreting the audience (fixes the recurring "what do they even sell / why do they want this audience" gap):
- Resolve the requester's own domain from their email (e.g.
name@acme.de→acme.de),
scrape/enrich it, and establish what they sell. Multi-offering companies: confirm which product line the demo is for — the prompt's stated product can mismatch the real one.
- Determine the relationship to the target audience — a target term (e.g. "call centers")
is usually a segment they sell to, not what they are. Classify: sell-to / buy-from / acquire / partner / recruit. Persona keywords derive from this, not from a guess.
Interactive vs deployed (headless):
- Interactive: if a must-have is genuinely ambiguous after auto-resolution, ask one concise
clarifying question. Otherwise proceed.
- Deployed / headless (invoked via
claude -pfrom the webhook — see Deployment): **never
block on questions.** Infer every field from the prompt + requester-domain research, record assumptions in context/icp.md under an "Assumptions" heading, and proceed end-to-end.
Do NOT proceed to search until the ICP is clear enough to build a meaningful filter.
Save ICP to: {client-slug}-gtm/context/icp.md (include the offering, the relationship classification, and any headless assumptions).
Step 2 — Create Working Directory
Create the {client-slug}-gtm/ directory structure as defined in conventions.md. Write the ICP definition to context/icp.md.
Step 3 — People Search (10 contacts)
Use the people-search skill to find ~10–15 contacts.
Provider selection for demo: follow the finder cadence in conventions.md → People-Source Cadence — FullEnrich Finder → BetterContact → Pipe0 → Amplemarket/Crustdata (last resort), max 2 attempts/source, FE-first for SME/owner-led/non-English segments. Both FE and BC return LinkedIn URLs directly (needed for email enrichment). If no company list (persona-based prompt), use Parallel FindAll or BC Search. For directory/scrape-sourced company lists, search by company name + location, never by exact domain (conventions #11).
Key fields to collect:
Follow the people-search execution protocol: sandbox → test → review → run.
Step 4 — Contact Filter (ICP Ranking)
Run contact-filter on the 10–15 contacts found. Even small batches benefit from ICP ranking — it ensures the enrichment step focuses on the best-fit contacts.
- Applies job tier, industry tier, location tier, and company size classification
- Rejects hard non-ICP contacts
- Ranks passed contacts by priority
- Output:
csv/intermediate/contacts_filtered.csv
For demos: use a relaxed hard-reject threshold (allow tiers 1–5 to pass), prioritize ranking over filtering.
Step 5 — People Enrichment (Email Only)
Run people-enrichment on the filtered contacts. Demo mode: email only, no phone.
Recommended flow:
- FullEnrich v2 (email) — all contacts
- Pipe0 waterfall — for FE misses only
One address, one person. A provider can return the same address for two people at one company (one mailbox for two "Scott"s), so check addresses across contacts before Step 7: a shared address stays only with the person a source ties it to (their name in the local part, scott.clay@ for Scott Clay, or a page that pairs the name and the address, such as the company's team page); otherwise drop it from both. A contact that loses its address keeps its card, LinkedIn draft only, with the est-warn badge.
An address the organisation publishes itself. Public-sector mail servers often don't answer a verifier's check, so the address comes back unknown. When the organisation's own website or own document (staff page, org chart, imprint, its own PDF) prints that exact address next to that person's name, keep it with email_status published and write that page's URL into email_source. Example: a city's IT head whose address is printed on the city's staff page. Only for an unknown verdict: never for an invalid one, never for a pattern or format guess, never from a third-party source (a directory, a data provider, an article on another site). The deck shows it with its own badge and never as verified (Step 7b).
Additional enrichment for message personalization (if available):
- LinkedIn headline and summary (from LinkedIn scrape via PhantomBuster)
- Recent LinkedIn posts (2–3 per contact) — significantly improves message quality
Minimum viable fields for message generation:
Low yield: if fewer than ~8 contacts survive filtering + enrichment, run one additional finder pass (next source in the People-Source Cadence) before proceeding to messages.
Step 5.5 — Signal Search (Optional)
Default: OFF. Enable when:
- The user explicitly asks for signal-anchored messages
- The webhook prompt mentions buying triggers (funding, hiring, transformation, recent news)
- The client's offering depends on timing signals to make sense (e.g. "we help post-Series-A companies scale ops")
- A
--with-signalsflag is passed to the demo invocation
Cost note: adds ~$0.01–0.05 per unique company (web search + scoring). On a 10-contact demo, that's typically 5–10 unique companies, so <$0.50.
Required inputs for signal-search
Signal-search needs three context files:
context/icp.md— already collected in Step 1context/offering.md— the value-prop block from Step 1 (write it now if not already saved)context/signal_criteria.md— bulleted list of signal types relevant to the offering
If signal_criteria.md doesn't exist, ask the user: "What would a company be doing right now that suggests they need what you offer?" — capture 5–10 bullets and save.
Run
The resolve_env.sh source line ensures $GTM_ENV_PATH is set even in a fresh shell (see signal-search SKILL.md / conventions). For the demo, leave Firecrawl and Parallel enrichment OFF — web search + scoring is enough for a ~10-contact lead list. Enable Firecrawl only if on-site content (careers, blog) is the primary signal source; if this machine has Firecrawl only via MCP (no FIRECRAWL_API_KEY), use the --firecrawl-pages-dir route documented in the signal-search skill. When the signal criteria include hiring, signal-search also reads the companies' job feeds on its own (their ATS board, plus the Arbeitsagentur for German companies; free, no flag; signal-search "Hiring signals").
Merge signals back into contacts
The message-generation step in Step 6 will then have company_overall_summary and company_scored_signals per contact — use the highest-scored signal as the message hook.
Step 6 — Generate Message Examples
Generate 2–4 sample messages before committing to the full batch.
Message Structure
Every message must follow: Hook → Bridge → Offer → Soft CTA
| Part | Purpose | Length | |
|---|---|---|---|
| Hook | Reference something specific to this person (post, career move, company signal) | 1 sentence | |
| Bridge | Connect their situation to your offer | 1 sentence | |
| Offer | What you provide, clearly stated | 1 sentence | |
| CTA | Soft ask — not "let's schedule a call" | 1 sentence |
Total: 320–450 characters. No blank line after greeting. Paragraphs separated by single line break.
Quality Rules
Must have:
- Specific hook (post reference OR career insight OR scored buying signal — not generic)
- Clear value proposition
- Natural, conversational tone
- Soft CTA
Must avoid:
- Repeating profile info they already know ("You work as X at Y")
- Generic observations ("impressive background", "I noticed you're in [industry]")
- Corporate jargon or buzzwords
- Pushy CTAs ("Let's schedule a call this week")
If Step 5.5 ran: for each contact, prefer the highest-scored signal from company_scored_signals as the hook over generic LinkedIn-post references. A score >= 70 signal anchored in real recent news is the strongest hook the demo can produce.
Generation Process
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/gtm-demo/SKILL.md
Popularity
- Repository stars
- 61
- Repository forks
- 6
- 7-day trend score
- 21
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/keinsaasforever/gtm-pipeline-skills/gtm-demo)