AgentStack
SKILL verified MIT Self-run

Outreach Enrich Company

skill-doctormozg-claude-pipelines-outreach-enrich-company · by DoctorMozg

ALWAYS invoke when the user wants to deepen the dossier on a company card AND/OR generate LinkedIn/email outreach letters from it. Fans out 5 enrichment subagents (news, tech, growth, reputation, contacts) to fill gaps left by the base research, then drafts and naturalizes one letter per Key Contact. Triggers - "enrich <card>", "go deeper on <card>", "deepen research on <company>", "write outreac…

No reviews yet
0 installs
16 views
0.0% view→install

Install

$ agentstack add skill-doctormozg-claude-pipelines-outreach-enrich-company

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Outreach Enrich Company? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Outreach Enrich Company

Overview

You are an orchestrator that takes a company card produced by /outreach-research and does two things, in this order:

  1. Deepen the dossier. Fan out five specialist enrichment subagents in parallel — outreach-news-finder, outreach-tech-analyst, outreach-growth-analyst, outreach-scanner, outreach-contact-finder — each instructed to find data not already in the card (gap-filling, not duplicating). Their findings are merged into a new ## Deeper Intelligence section appended to the card.
  2. Draft outreach letters. Using the original card data plus the deeper intelligence as personalization fuel, draft one letter per named Key Contact via expert-copywriter — each subtly calibrated to the contact's inferred communication style (Social Styles, produced grounded-only by outreach-personality-profiler) — then mandatorily naturalize each via expert-naturalizer. The letters are appended as a ## Outreach Letters section inside the card.

The whole pipeline is fully automatic — no approval gates, no mid-run prompts. The user invokes the skill, the skill enriches and writes letters, the card now holds them both.

When to Use

Invoke when the user has a company card (produced by /outreach-research, lives at .mz/outreach//companies/.md) and wants either richer company intelligence, outreach letters, or both. Trigger phrases:

  • "enrich .mz/outreach/.../companies/.md and write letters"
  • "deepen the research on this card"
  • "go deeper on `` and draft outreach"
  • "write outreach letters for ``"
  • "generate letters from this card"

When NOT to use

  • The user has only a company name or domain and no card — run /outreach-research first (single-company mode if they want only one).
  • The user wants to discover companies first — use /outreach-research.
  • The user wants recruiter contacts for a job application — use /job-recruiter-info in mz-job-outreach.
  • The user wants general marketing copy (landing pages, announcements, social) — use /copywrite from mz-creative.
  • The user wants letters written to a separate location than the card — this skill only writes back into the card.

Input

  • $ARGUMENTS — Required: an absolute or repo-relative path to a company card .md file. Two accepted shapes:
  • Research baseline: .mz/outreach//companies/.md — direct output of /outreach-research. First activation moves it to active/.
  • Active: .mz/outreach/active/_.md — a card already activated by this skill or /outreach-update-card. The date prefix is the last interaction date; this run updates it to today.
  • Optional modifiers (case-insensitive, order-independent):
  • channels:email|linkedin|both — overrides per-contact channel auto-detection. Default: best channel per contact (email if known, else LinkedIn DM, else skip).
  • sender: — overrides the sender voice. Inline text becomes the voice description; a path is read as a sender bio markdown file. Default: read /strategy.json sender_voice field if present.
  • enrich:only — run the deep-enrichment phase and skip letter drafting (card gets ## Deeper Intelligence but no ## Outreach Letters).
  • enrich:skip — skip the deep-enrichment phase and draft letters directly from the existing card content only.
  • brief: — pull the local business-climate dossier from an outreach-brief run; the combo matching the card's sector and location seeds the letters with regional-climate angles. Default: unset (company data only).
  • personality:off — disable reader-style calibration entirely (skip the Phase 3 profiling wave; letters use neutral structure). Default: on — role-based priorities always shape the leading angle, and footprint profiling runs automatically when a contact has a usable public profile.
  • Default (neither flag): both phases run.

If $ARGUMENTS is empty or no source can be resolved (see Source Resolution below), emit STATUS: BLOCKED with a clear message and stop.

Argument Parsing

Extract from $ARGUMENTS:

  • user_path — the path token (everything not matching a parameter pattern). Must end in .md.
  • channels_override — from channels: (default: unset → per-contact auto-detect).
  • sender_override — from sender: (default: unset → use strategy.json or fallback voice).
  • enrich_mode — from enrich:: only, skip, or unset (default unset = both phases run).
  • brief_run — optional, from brief:; resolves to .mz/outreach//climate.json (default: unset).
  • personality_mode — from personality:: off disables reader-style calibration; any other value or absent = on (default).

Source resolution

Extract the company slug from user_path's basename:

  • If the basename matches _.md (active path), company_slug = the part after the date prefix.
  • Otherwise (.md), company_slug = the basename minus .md.

Then resolve source_path (the file actually read and updated by this run):

mkdir -p .mz/outreach/active
find .mz/outreach/active -maxdepth 1 -type f \
  -name '[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]_.md' 2>/dev/null | head -1
  • If foundsource_path = the active path returned. The user-supplied path is ignored in favor of the active version (which holds the canonical accumulated history). The user may have passed a now-deleted research-baseline path; the active version is authoritative.
  • If not foundsource_path = user_path. The card has not been activated yet; this run will activate it.

Validate the card at source_path before any other work:

  1. The file exists (Read succeeds).
  2. The first non-empty line starts with # (H1 = company name).
  3. The body contains H2 headers matching the canonical card shape — at minimum ## Overview, ## Key Contacts, ## Outreach Recommendation must all be present. If any are missing, emit STATUS: BLOCKED with the list of missing headers.

Directory Structure

  • State.mz/task//state.md. Source of truth across phases.
  • Card snapshot.mz/task//card_parsed.json. Structured extract of the source card, consumed by the deep-enrichment subagents in Phase 2 so they know what is ALREADY documented.
  • Enrichment artifacts.mz/task//enrichment/.json. One JSON per Phase 2 subagent (news.json, tech.json, growth.json, reputation.json, contacts.json).
  • Briefs.mz/task//briefs/.json. One brief per contact selected for drafting.
  • Profiles.mz/task//profiles/.json. One reader-style read per profiled contact (Social Style or role-priorities, evidence, confidence, calibration directive), written by outreach-personality-profiler in Phase 3 and merged into the briefs. Absent when personality:off.
  • Drafts.mz/task//drafts/_.md. One draft file per (contact, channel) pair. Each draft carries YAML frontmatter (subject, channel, recipient) followed by the body.
  • Card lifecycle — the card ends this run at target_path = .mz/outreach/active/_.md. If source_path != target_path, the source file is deleted in the final card-rewrite phase (move semantics). Research-baseline cards at .mz/outreach//companies/.md and stale-dated active cards (active/_.md) are removed by this run.

task_name follows _outreach_enrich_ where ` is derived in Source Resolution (slug without date prefix or .md). Same-day collisions append v2, v3`.

` = the directory containing sourcepath when the card is still at its research-baseline location (typically .mz/outreach//companies/). The sibling strategy.json lives at /../strategy.json — read it from there for sender voice and outreach angles. When sourcepath is already an active path, falls back to the most-recently-modified .mz/outreach// directory containing a strategy.json (or default` voice if none can be located).

Core Process

Phase Overview

| # | Phase | Agent(s) | Details | | --- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | | 0 | Setup + card validation | — (orchestrator) | Inline below | | 1 | Parse card + light web enrichment | — (orchestrator + WebSearch) | Inline below | | 2 | Deep enrichment via subagents | outreach-news-finder, outreach-tech-analyst, outreach-growth-analyst, outreach-scanner, outreach-contact-finder | phases/deep_enrichment.md | | 3 | Reader profiling + draft letters | outreach-personality-profiler, expert-copywriter | phases/draft_and_finalize.md | | 4 | Naturalize letters | expert-naturalizer | phases/draft_and_finalize.md | | 5 | Rewrite card (deeper + letters) | — (orchestrator, Read + Write) | phases/draft_and_finalize.md | | 6 | Verification summary | — (orchestrator) | Inline below |

Read phases/deep_enrichment.md when you reach Phase 2 and phases/draft_and_finalize.md when you reach Phase 3. If enrich_mode == "only", Phases 3 and 4 are skipped; Phase 5 still runs to append the ## Deeper Intelligence section. If enrich_mode == "skip", Phase 2 is skipped; Phase 5 only appends the ## Outreach Letters section.

Phase 0: Setup + card validation

Parse arguments. Resolve user_path, channels_override, sender_override, enrich_mode. Run Source Resolution (see Argument Parsing) to derive company_slug and source_path. Verify source_path exists and parses as a canonical company card.

Derive:

  • company_slug — already set by Source Resolution (stripped of any date prefix and .md).
  • task_name = _outreach_enrich_ (truncate ` to 30 chars if needed). Collision: v2, v3`.
  • task_dir = .mz/task//.
  • run_dir = if source_path is under .mz/outreach//companies/, then dirname(dirname(source_path)); otherwise (active path) the most-recently-modified .mz/outreach// directory that contains a strategy.json, falling back to default voice if none found.
mkdir -p .mz/task//enrichment
mkdir -p .mz/task//briefs
mkdir -p .mz/task//profiles
mkdir -p .mz/task//drafts
mkdir -p .mz/outreach/active

Write .mz/task//state.md:

schema_version: 2
Status: running
Phase: 0
Started: 
phase_complete: false
what_remains: []
UserPath: 
SourcePath: 
CompanySlug: 
RunDir: 
ChannelsOverride: 
SenderOverride: 
EnrichMode: 
BriefRun: 
PersonalityMode: 

Phase 1: Parse card + light web enrichment

Read the card. Extract structured data — do this with normal markdown reading, not a regex parser. Capture:

  • Company: name (from H1), domain, sector, location, founded, size, score (from the metadata header lines).
  • Overview: the ## Overview paragraph.
  • Key Contacts: every numbered entry under ## Key Contacts. Each entry is **** — — [LinkedIn]() — . Extract name, title, LinkedIn URL, relevance line. Also capture the trailing **Emails**:, **Phone**:, **Company LinkedIn**: lines. Cap at 5 contacts.
  • Recent News: numbered entries under ## Recent News & Timing Signals. Each: **** (, , timing) — . Keep top 3 by timing_relevance (high first).
  • Outreach Recommendation: the synthesizing paragraph plus the three labeled lines **Best contact**:, **Best angle**:, **Timing**:.
  • Technology Profile: stack list, maturity, GitHub URL, tech blog URL.
  • Growth Signals: trajectory, open roles, funding (if present).
  • Red Flags: any bulleted items (or "None identified").

Persist the parsed structure to .mz/task//card_parsed.json so Phase 2 subagents can read it without re-parsing the markdown:

{
  "company": { "name": "...", "slug": "...", "domain": "...", "sector": "...", "location": "...", "founded": "...", "size": "..." },
  "overview": "",
  "key_contacts": [ { "name": "...", "title": "...", "linkedin_url": "...", "email": "...", "relevance": "..." } ],
  "recent_news": [ { "title": "...", "date": "...", "category": "...", "timing_relevance": "...", "outreach_implication": "..." } ],
  "outreach_recommendation": { "summary": "...", "best_contact": "...", "best_angle": "...", "timing": "..." },
  "tech_profile": { "stack": ["..."], "maturity": "...", "github_url": "...", "tech_blog_url": "..." },
  "growth_signals": { "trajectory": "...", "open_roles": ["..."], "funding": "..." },
  "red_flags": ["..."]
}

Read /strategy.json if it exists. Capture the sender_voice (or outreach_strategy.sender_voice) and outreach_angles fields. If the file is missing OR the field is empty, use these defaults:

  • sender_voice = "Professional, concise, plain-spoken. No marketing register, no hype. First-person singular. Direct request, one CTA per letter."
  • outreach_angles = ["Value-first introduction citing one verified personalization signal from the card or fresh research."]

If sender_override was supplied as an argument, it overrides the strategy.json value (inline text → used directly; path → read the file).

Record strategy_source per brief: strategy.json if loaded from disk, default if fallback applied, sender_override if argument was used. If default, the final STATUS will be DONE_WITH_CONCERNS.

Local-climate context

If brief_run was supplied, read .mz/outreach//climate.json and select the combo whose industry and region best match the card's sector and location (prefer an exact region match, then industry; if none match, skip climate context and letters fall back to company data). Capture the matched combo's signals and top_outreach_angles as climate_context, carried into Phase 3 brief-building. If the file is missing, warn and continue without it.

Light web enrichment

This is a small fast pre-pass for the orchestrator to grab per-contact signals the Phase 2 subagents won't touch. The deep, multi-source enrichment happens in Phase 2 via subagents. Hard cap here: 6 calls.

Run a single parallel wave of WebSearch calls:

  1. 1 × WebSearch per Key Contact (up to 5) — public activity. Query: "" "" linkedin OR podcast OR interview OR keynote.
  2. 1 × WebSearch — anchor query for cross-referencing in Phase 2. Query: "" news .

Capture per-contact signal strings (1–2 lines each, verbatim from the search snippet). Discard anything that cannot be cited. These signals seed Phase 3 brief-building; they are not written into the card.

Record the total number of light-pass web calls — surface in the final verification block.

Update state.md Phase field to card_parsed. If enrich_mode == "skip", advance directly to Phase 3 (handoff to phases/draft_and_finalize.md). Otherwise advance to Phase 2 (handoff to phases/deep_enrichment.md).

Phase 6: Verification summary

After Phase 5 completes, emit a visible block:

Outreach enrich-company done.
Source (read from):     
Card (final):           _.md>
Relocated:                   # yes if source_path != target_path
Task dir:               .mz/task//
Enrichment mode:        
Subagents dispatched:       (capped at 5)
Subagents failed:       
Deeper-intel fields:    
Contacts drafted:          (channels: )   # 0 if enrich_mode == only
Contacts skipped:

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [DoctorMozg](https://github.com/DoctorMozg)
- **Source:** [DoctorMozg/claude-pipelines](https://github.com/DoctorMozg/claude-pipelines)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.