Install
$ agentstack add skill-xiongqvq-b2b-lead-hunter-skill-b2b-lead-hunter-skill ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
B2B Lead Hunter
Purpose
Research foreign-trade B2B prospects and contact channels for physical-product export, distributor discovery, importer discovery, and outreach preparation.
Hermes owns judgment, evidence review, search iteration, language choice, and approval decisions. Scripts own deterministic normalization, page reading, contact extraction, dedupe, validation, template rendering, draft evaluation, export, and SMTP plumbing.
Default objective: produce a traceable lead file where every company, contact channel, decision maker, score, and outreach draft is tied to source URLs and structured artifacts. Quality gates override target count.
User Workflow Preference
User prefers continuous-cycle execution: mine leads → find decision makers → generate emails → send, all in one loop. Do not pause between stages unless the user explicitly asks to stop. After sending one batch, immediately resume mining the next. The cycle is:
search new leads → get contact emails → send generic emails
→ search decision makers → infer/find DM emails → send DM emails
→ search new leads (next country/niche) → repeat
Do not ask "continue or pause?" after each batch — just keep going until the user says stop.
Non-Negotiable Rules
- Use
scripts/read_jina.pyas the primary reader for every website or URL: seller site, candidate website, contact page, product page, directory profile, or source article. Use browser tools only when Jina fails or interaction is required. - Use Hermes native web search for search queries. Do not open Google, Bing, or other search engines in a browser.
- Keep lead discovery, outreach drafting, human approval, and SMTP sending as separate stages with separate files.
- Do not send email unless the user explicitly requests sending, SMTP config exists, approved records exist, suppression checks run, and
send_smtp.pyreceives matching passing evaluations. - Never auto-send to inferred emails, free-mail addresses, low/reject leads, directory-only leads, records without source URLs, or records without buyer-role evidence.
- A lead cannot enter strict
leads.csvunless company reality, buyer-role evidence, contactability, and source URLs are present. - Do not relax gates to satisfy
target_count. - Directories and B2B platforms are discovery sources, not final truth. Confirm with official or strong independent evidence before accepting.
- Customs/trade evidence is useful buying intent, but absence of customs data is not a rejection reason.
- Every outreach message must include truthful sender identity, source-backed personalization, a low-pressure CTA, and a clear opt-out line.
Reference Router
Read only the reference files needed for the current stage. Do not load all references by default.
| User Goal | Read First | Key Scripts | | --- | --- | --- | | Full run or unclear request | references/reference-router.md, references/workflow.md | run_hunt.py, validate_artifact.py | | Search planning | references/query-lanes.md (includes Brand Distributor Networks lane), references/region-language-map.md, references/search-resilience.md | normalize_search_results.py, serper_maps.py | | Company and contact research | references/company-website-research.md, references/output-schema.md | read_jina.py, extract_contacts.py | | Decision makers | references/decision-maker-discovery.md, references/chinese-founder-contact-discovery.md, references/contact-discovery-from-pdfs-and-directories.md | linkedin_dm_search.py, infer_email.py | | Chinese AI/robotics startup leads (recruitment, not B2B trade) | references/chinese-ai-startup-leads.md | — search lanes, sources, pitfalls only; no dedicated scripts | | Customs/import verification | references/customs-verification.md | customs_verify.py | | Outreach generation | references/outreach-workflow.md, references/outreach-parameter-guide.md, references/email-localization.md | prepare_outreach.py, generate_outreach_templates.py, generate_outreach_drafts.py, evaluate_outreach_drafts.py | | SMTP sending | references/outreach-compliance.md, references/outreach-parameter-guide.md, references/smtp-quirks.md | send_smtp.py, validate_artifact.py |
Required Inputs
Ask for missing high-impact inputs, but proceed with conservative defaults if the user wants execution:
product: concrete product or product family.seller_context: seller website, product page, catalog text, or short description.target_regions: countries or regions.target_customer_profile: importer, distributor, wholesaler, installer, integrator, OEM, or end user.negative_criteria: direct competitors, B2C-only stores, unsupported countries, tiny local services, or other knockouts.target_count: default 30 for MVP runs.round_limits: default pilot first, then 3 rounds, 6-10 queries per round, 10-20 results per query.
Default ICP: importers, distributors, wholesalers, and agents. Include installers, integrators, OEMs, or end users only when buying, resale, procurement, or project-use evidence exists.
Artifact Contract
Create a run directory:
lead-runs/-YYYYMMDD-HHMM/
├── brief.json
├── search-plan.md
├── raw-search.jsonl
├── candidates.jsonl
├── enriched.jsonl
├── leads.jsonl
├── leads.csv
├── leads_all.csv
├── review.jsonl
├── rejected.jsonl
└── run-report.md
Optional outreach artifacts:
lead-runs/-YYYYMMDD-HHMM/
├── sender-profile.json
├── outreach-candidates.jsonl
├── outreach-templates.jsonl
├── outreach-drafts.jsonl
├── outreach-evaluations.jsonl
├── outreach-review.csv
├── approved-outreach.jsonl
├── sent-log.jsonl
├── suppression-list.csv
└── outreach-report.md
Validate handoffs whenever artifacts already exist, before export, and before any SMTP dry-run/send. Use scripts/validate_artifact.py . Exact command examples live in references/outreach-parameter-guide.md.
Lead Research State Machine
- Build
brief.jsonfrom user input and seller context. If seller website exists, read it withscripts/read_jina.pyfirst. - Write
search-plan.mdusing at least three lanes unless the user requests a narrow run. - Run a pilot: 5-8 queries, 5-10 results per query, inspect 20-40 candidates.
- Stop and ask before full scale if pilot candidates are mostly wrong, B2C-only, direct manufacturers, directories, region drift, or contact-poor.
- Normalize search results to
raw-search.jsonl. - Build and triage
candidates.jsonl; reject only clear mismatches at discovery stage. - Research official websites and important pages with Jina first.
- Extract contacts and classify email type:
generic,person, orinferred. - Score from evidence: fit, contactability, evidence quality, priority.
- Export strict and review views, then write
run-report.md.
Acceptance gate for strict leads:
- Real company evidence.
- Buyer-role evidence.
- At least one contact channel.
- Source URL for every key claim.
Decision Maker Rules
Decision-maker discovery is mandatory phase-two enrichment for high and strong medium leads. Do it immediately after the generic email batch is sent, before moving to the next round of lead discovery. The cycle is:
send generic email batch → immediately search decision makers for those companies → send DM emails → then start next round of lead mining
Do not separate these stages — the user expects them back-to-back. After sending DM emails, immediately resume mining new leads (new countries, new niches, new search lanes).
Preferred order:
- Official website pages: contact, team, management, Ansprechpartner, Impressum, brochures, catalog PDFs.
- Industry directories and supplier linecard directories.
- LinkedIn/native web/Tavily search for role-specific profiles.
- Email pattern detection from known same-domain employee emails.
- Email inference only when a same-domain employee pattern is observed.
Inferred personal emails are auxiliary only. They cannot be the only contact channel for a high lead and cannot be auto-sent.
Use scripts/enrich_decision_makers.py to generate role-based search plans and merge public employee contacts back into leads. Search pattern: role + company first, then person + company/domain to find public contact channels.
Customs Verification Rules
Use customs/trade data as a buying-intent signal after a company already looks plausible. Extract shipment count, supplier names, origin country, HS/product clues, date recency, and source URL.
Do not downgrade a company only because customs data is unavailable. Many valid European distributors, agents, and wholesalers do not appear in free customs portals.
Use scripts/customs_verify.py only on normalized search results for a target company. See references/customs-verification.md.
Outreach State Machine
Outreach starts only after leads.jsonl exists and has passed validation.
leads.jsonl
-> outreach-candidates.jsonl
-> outreach-templates.jsonl
-> outreach-drafts.jsonl
-> outreach-evaluations.jsonl
-> outreach-review.csv
-> approved-outreach.jsonl
-> sent-log.jsonl
Run the outreach scripts in the exact order shown above. Use --require-template when rendering drafts so every email comes from a regional/language template. See references/outreach-parameter-guide.md for concrete command lines and parameters.
Email Generation Strategy
Use hybrid generation:
- One base template per
country + language + buyer_role + product_anglecluster. - One final email per company by filling source-backed company variables into that regional/language template.
- Never send a pure regional template with no company-specific evidence.
- Avoid fully free-writing every company email unless the account is high value; it increases variance and review cost.
Required company variables:
company_namerecipient_email- concrete source-backed fit reason
- product/application angle from
sender-profile.json - low-friction CTA
- opt-out line
Template controls:
- language and greeting style
- directness/formality
- subject shape
- CTA wording
- opt-out wording
- allowed claims and forbidden phrases
Prefer local language when confidence is high. Use English when local-language confidence is medium/low, the contact page is English, or the product category is commonly handled in English.
Mandatory Outreach Gate Before Sending
SMTP dry-run and real sending are blocked unless all are true:
- User explicitly requested sending.
- SMTP config is present. Prefer per-run
lead-runs//smtp-config.json; otherwise use$B2B_LEAD_HUNTER_SMTP_CONFIGor shared/_shared/smtp-config.json. approved-outreach.jsonlexists and every record hasapproval_status=approved.outreach-evaluations.jsonlexists.- Each approved
draft_idhas a matching evaluation withdecision=pass. - The passing evaluation hash matches the exact current recipient, subject, body, and opt-out line.
approved_body_hashmatches the exact current recipient, subject, body, and opt-out line.- WARNING:
body_hash()insend_smtp.pyusesrecipient+subject+body+opt_outconcatenated, NOT just the body text. Always use--print-approval-hashesto get the correct hash rather than computing manually. - Suppression and prior sent-log checks run.
- Dry-run succeeds before
--send-approved.
Always run send_smtp.py --dry-run successfully before --send-approved. Both commands must include --evaluations, --suppression-list, and --sent-log. Pass --smtp-config for per-run config, or rely on $B2B_LEAD_HUNTER_SMTP_CONFIG / /_shared/smtp-config.json. Exact command examples live in references/outreach-parameter-guide.md.
SMTP troubleshooting: See references/smtp-quirks.md for QQ exmail port 465 SSL, hash computation formula, env var propagation, and common failure patterns.
Output Policy
leads.jsonl: canonical lead data.leads.csv: strict view with high and medium only.leads_all.csv: full view including low, visibly marked.review.jsonl: uncertain/low leads needing human review.rejected.jsonl: clear non-leads with concrete reasons.run-report.md: Chinese-readable summary, metrics, top queries, bad queries, evidence gaps, next actions.outreach-drafts.jsonl: draft-only email records followingtemplates/outreach-draft.schema.json.outreach-evaluations.jsonl: deterministic quality gate for draft emails.approved-outreach.jsonl: manually approved subset allowed for SMTP dry-run/sending.sent-log.jsonl: append-only log of dry runs, sends, skips, suppression hits, duplicate blocks, failures, and message IDs.
Never hide rejected records. Keep rejected records with reasons so the next round can improve.
Stop Conditions
Stop and ask for confirmation before spending more calls or sending anything when:
- Pilot candidates are over 60% wrong customer type.
- Results are mostly direct manufacturers, B2C-only shops, local services, or directories.
- Target region drifts badly.
- Most candidates have no usable contact channel.
- Search/Jina failures, 429s, or costs are abnormal.
- Outreach evaluations produce many
revieworrejectdecisions. - SMTP dry-run reports suppression, duplicate, hash mismatch, missing evaluation, or config problems.
Compliance Boundaries
- Collect only publicly available business contact information.
- Do not bypass authentication, paywalls, robots restrictions, CAPTCHAs, or access controls.
- Do not generate deceptive identities, fake relationships, fake offices, fake stock, fake certifications, or unsupported claims.
- Respect opt-out requests and regional email/privacy laws.
- Avoid personal data unrelated to B2B purchasing or company representation.
- Keep sending low-volume, reviewable, logged, and reversible.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: xiongQvQ
- Source: xiongQvQ/-b2b-lead-hunter-skill
- License: MIT
- Homepage: https://b2binsights.io/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.